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