Merge pull request #22825 from MegaphoneJon/membership-41
[civicrm-core.git] / CRM / Report / Page / InstanceList.php
CommitLineData
6a488035 1<?php
6a488035
TO
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
16 */
17
18/**
04994ffc 19 * Page for invoking report instances.
6a488035
TO
20 */
21class CRM_Report_Page_InstanceList extends CRM_Core_Page {
22
c86d4e7c 23 public static $_links = NULL;
6a488035 24
c86d4e7c 25 public static $_exceptions = ['logging/contact/detail'];
2f4c2f5d 26
6a488035 27 /**
fe482240 28 * Name of component if report list is filtered.
6a488035
TO
29 *
30 * @var string
ae5ffbb7 31 */
6a488035
TO
32 protected $_compName = NULL;
33
34 /**
fe482240 35 * ID of component if report list is filtered.
6a488035
TO
36 *
37 * @var int
ae5ffbb7 38 */
6a488035
TO
39 protected $_compID = NULL;
40
2066e389 41 /**
fe482240 42 * ID of grouping if report list is filtered.
2066e389 43 *
44 * @var int
ae5ffbb7 45 */
37c20553 46 protected $_grouping = NULL;
2066e389 47
e166a1c7
EM
48 /**
49 * Possibly always null.... maybe $_title is used...
50 *
51 * The relationship between this & $_title is ambigous & seemingly not worked through.
52 *
53 * @var string
54 */
55 protected $title;
56
6a488035 57 /**
fe482240 58 * ID of parent report template if list is filtered by template.
6a488035
TO
59 *
60 * @var int
ae5ffbb7 61 */
6a488035
TO
62 protected $_ovID = NULL;
63
6a488035 64 /**
fe482240 65 * Title of parent report template if list is filtered by template.
6a488035
TO
66 *
67 * @var string
ae5ffbb7 68 */
6a488035
TO
69 protected $_title = NULL;
70
71 /**
04994ffc 72 * Retrieves report instances, optionally filtered.
73 *
74 * Filtering available by parent report template ($ovID) or by component ($compID).
6a488035 75 *
a6c01b45 76 * @return array
6a488035 77 */
182f5081 78 public function info() {
6a488035
TO
79
80 $report = '';
be2fb01f 81 $queryParams = [];
934f2552 82
6a488035 83 if ($this->ovID) {
934f2552 84 $report .= " AND v.id = %1 ";
be2fb01f 85 $queryParams[1] = [$this->ovID, 'Integer'];
6a488035 86 }
2f4c2f5d 87
6a488035
TO
88 if ($this->compID) {
89 if ($this->compID == 99) {
90 $report .= " AND v.component_id IS NULL ";
91 $this->_compName = 'Contact';
37c20553 92 }
93 else {
934f2552 94 $report .= " AND v.component_id = %2 ";
be2fb01f 95 $queryParams[2] = [$this->compID, 'Integer'];
6a488035
TO
96 $cmpName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Component', $this->compID,
97 'name', 'id'
98 );
99 $this->_compName = substr($cmpName, 4);
100 if ($this->_compName == 'Contribute') {
101 $this->_compName = 'Contribution';
102 }
103 }
104 }
37c20553 105 elseif ($this->grouping) {
934f2552 106 $report .= " AND v.grouping = %3 ";
be2fb01f 107 $queryParams[3] = [$this->grouping, 'String'];
37c20553 108 }
0f8c6e58 109 elseif ($this->myReports) {
934f2552 110 $report .= " AND inst.owner_id = %4 ";
be2fb01f 111 $queryParams[4] = [CRM_Core_Session::getLoggedInContactID(), 'Integer'];
0f8c6e58 112 }
6a488035
TO
113
114 $sql = "
0f8c6e58 115 SELECT inst.id, inst.title, inst.report_id, inst.description, inst.owner_id, v.label, v.grouping, v.name as class_name,
2066e389 116 CASE
117 WHEN comp.name IS NOT NULL THEN SUBSTRING(comp.name, 5)
118 WHEN v.grouping IS NOT NULL THEN v.grouping
119 ELSE 'Contact'
120 END as compName
6a488035
TO
121 FROM civicrm_option_group g
122 LEFT JOIN civicrm_option_value v
123 ON v.option_group_id = g.id AND
124 g.name = 'report_template'
125 LEFT JOIN civicrm_report_instance inst
126 ON v.value = inst.report_id
2f4c2f5d 127 LEFT JOIN civicrm_component comp
6a488035 128 ON v.component_id = comp.id
2f4c2f5d 129
6a488035 130 WHERE v.is_active = 1 {$report}
934f2552 131 AND inst.domain_id = %9
493bc048 132 ORDER BY v.weight ASC, inst.title ASC";
be2fb01f 133 $queryParams[9] = [CRM_Core_Config::domainID(), 'Integer'];
6a488035 134
934f2552 135 $dao = CRM_Core_DAO::executeQuery($sql, $queryParams);
6a488035 136
be2fb01f 137 $rows = [];
37c20553 138 $url = 'civicrm/report/instance';
0f8c6e58 139 $my_reports_grouping = 'My';
6a488035
TO
140 while ($dao->fetch()) {
141 if (in_array($dao->report_id, self::$_exceptions)) {
142 continue;
143 }
144
e46f73c7 145 $enabled = CRM_Core_Component::isEnabled("Civi{$dao->compName}");
37c20553 146 if ($dao->compName == 'Contact' || $dao->compName == $dao->grouping) {
6a488035
TO
147 $enabled = TRUE;
148 }
0f8c6e58 149
150 // filter report listings for private reports
151 if (!empty($dao->owner_id) && CRM_Core_Session::getLoggedInContactID() != $dao->owner_id) {
152 continue;
153 }
154
6a488035
TO
155 //filter report listings by permissions
156 if (!($enabled && CRM_Report_Utils_Report::isInstancePermissioned($dao->id))) {
157 continue;
158 }
159 //filter report listing by group/role
160 if (!($enabled && CRM_Report_Utils_Report::isInstanceGroupRoleAllowed($dao->id))) {
161 continue;
162 }
163
164 if (trim($dao->title)) {
165 if ($this->ovID) {
be2fb01f 166 $this->title = ts("Report(s) created from the template: %1", [1 => $dao->label]);
6a488035 167 }
0f8c6e58 168
169 $report_grouping = $dao->compName;
170 if ($dao->owner_id != NULL) {
171 $report_grouping = $my_reports_grouping;
172 }
173 $rows[$report_grouping][$dao->id]['title'] = $dao->title;
174 $rows[$report_grouping][$dao->id]['label'] = $dao->label;
175 $rows[$report_grouping][$dao->id]['description'] = $dao->description;
176 $rows[$report_grouping][$dao->id]['url'] = CRM_Utils_System::url("{$url}/{$dao->id}", "reset=1&output=criteria");
177 $rows[$report_grouping][$dao->id]['viewUrl'] = CRM_Utils_System::url("{$url}/{$dao->id}", 'force=1&reset=1');
178 $rows[$report_grouping][$dao->id]['actions'] = $this->getActionLinks($dao->id, $dao->class_name);
6a488035
TO
179 }
180 }
0f8c6e58 181 // Move My Reports to the beginning of the reports list
182 if (isset($rows[$my_reports_grouping])) {
183 $my_reports = $rows[$my_reports_grouping];
184 unset($rows[$my_reports_grouping]);
be2fb01f 185 $rows = [$my_reports_grouping => $my_reports] + $rows;
0f8c6e58 186 }
6a488035
TO
187 return $rows;
188 }
189
190 /**
100fef9d 191 * Run this page (figure out the action needed and perform it).
6a488035 192 */
00be9182 193 public function run() {
6a488035 194 //Filters by source report template or by component
353ffa53 195 $this->ovID = CRM_Utils_Request::retrieve('ovid', 'Positive', $this);
0f8c6e58 196 $this->myReports = CRM_Utils_Request::retrieve('myreports', 'String', $this);
6a488035 197 $this->compID = CRM_Utils_Request::retrieve('compid', 'Positive', $this);
37c20553 198 $this->grouping = CRM_Utils_Request::retrieve('grp', 'String', $this);
199
353ffa53 200 $rows = $this->info();
e166a1c7 201 $this->assign('title', $this->title);
6a488035 202 $this->assign('list', $rows);
c86d4e7c 203 if ($this->ovID or $this->compID) {
6a488035
TO
204 // link to view all reports
205 $reportUrl = CRM_Utils_System::url('civicrm/report/list', "reset=1");
e166a1c7 206 if (!$this->ovID) {
be2fb01f 207 CRM_Utils_System::setTitle(ts('%1 Reports', [1 => $this->_compName]));
6a488035
TO
208 }
209 }
e166a1c7 210 $this->assign('reportUrl', $reportUrl ?? FALSE);
6a488035
TO
211 // assign link to template list for users with appropriate permissions
212 if (CRM_Core_Permission::check('administer Reports')) {
213 if ($this->compID) {
be2fb01f 214 $newButton = ts('New %1 Report', [1 => $this->_compName]);
6a488035 215 $templateUrl = CRM_Utils_System::url('civicrm/report/template/list', "reset=1&compid={$this->compID}");
0db6c3e1
TO
216 }
217 else {
6a488035
TO
218 $newButton = ts('New Report');
219 $templateUrl = CRM_Utils_System::url('civicrm/report/template/list', "reset=1");
220 }
221 $this->assign('newButton', $newButton);
6a488035
TO
222 $this->assign('compName', $this->_compName);
223 }
e166a1c7
EM
224 $this->assign('myReports', $this->myReports);
225 $this->assign('templateUrl', $templateUrl ?? NULL);
6a488035
TO
226 return parent::run();
227 }
96025800 228
182f5081 229 /**
230 * Get action links.
231 *
232 * @param int $instanceID
233 * @param string $className
234 *
235 * @return array
236 */
237 protected function getActionLinks($instanceID, $className) {
238 $urlCommon = 'civicrm/report/instance/' . $instanceID;
be2fb01f
CW
239 $actions = [
240 'copy' => [
182f5081 241 'url' => CRM_Utils_System::url($urlCommon, 'reset=1&output=copy'),
242 'label' => ts('Save a Copy'),
e166a1c7 243 'confirm_message' => NULL,
be2fb01f
CW
244 ],
245 'pdf' => [
182f5081 246 'url' => CRM_Utils_System::url($urlCommon, 'reset=1&force=1&output=pdf'),
247 'label' => ts('View as pdf'),
e166a1c7 248 'confirm_message' => NULL,
be2fb01f
CW
249 ],
250 'print' => [
182f5081 251 'url' => CRM_Utils_System::url($urlCommon, 'reset=1&force=1&output=print'),
252 'label' => ts('Print report'),
e166a1c7 253 'confirm_message' => NULL,
be2fb01f
CW
254 ],
255 ];
182f5081 256 // Hackery, Hackera, Hacker ahahahahahaha a super nasty hack.
257 // Almost all report classes support csv & loading each class to call the method seems too
258 // expensive. We also have on our later list 'do they support charts' which is instance specific
259 // e.g use of group by might affect it. So, lets just skip for the few that don't for now.
be2fb01f 260 $csvBlackList = [
182f5081 261 'CRM_Report_Form_Contact_Detail',
262 'CRM_Report_Form_Event_Income',
be2fb01f 263 ];
182f5081 264 if (!in_array($className, $csvBlackList)) {
be2fb01f 265 $actions['csv'] = [
182f5081 266 'url' => CRM_Utils_System::url($urlCommon, 'reset=1&force=1&output=csv'),
267 'label' => ts('Export to csv'),
e166a1c7 268 'confirm_message' => NULL,
be2fb01f 269 ];
182f5081 270 }
271 if (CRM_Core_Permission::check('administer Reports')) {
be2fb01f 272 $actions['delete'] = [
182f5081 273 'url' => CRM_Utils_System::url($urlCommon, 'reset=1&action=delete'),
274 'label' => ts('Delete report'),
275 'confirm_message' => ts('Are you sure you want delete this report? This action cannot be undone.'),
be2fb01f 276 ];
182f5081 277 }
090e9e0e 278 CRM_Utils_Hook::links('view.report.links',
279 $className,
280 $instanceID,
281 $actions
282 );
182f5081 283
284 return $actions;
285 }
286
6a488035 287}