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