Commit | Line | Data |
---|---|---|
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 | 16 | */ |
0b25329b | 17 | class CRM_Report_BAO_ReportInstance extends CRM_Report_DAO_ReportInstance { |
6a488035 | 18 | |
6ea7a229 | 19 | /** |
fe482240 | 20 | * Takes an associative array and creates an instance object. |
6ea7a229 DS |
21 | * |
22 | * the function extract all the params it needs to initialize the create a | |
23 | * instance object. the params array could contain additional unused name/value | |
24 | * pairs | |
25 | * | |
7e06c9f5 TO |
26 | * @param array $params |
27 | * (reference ) an assoc array of name/value pairs. | |
6ea7a229 | 28 | * |
16b10e64 | 29 | * @return CRM_Report_DAO_ReportInstance |
6ea7a229 | 30 | */ |
00be9182 | 31 | public static function add(&$params) { |
6ea7a229 DS |
32 | if (empty($params)) { |
33 | return NULL; | |
34 | } | |
35 | ||
edb1d052 | 36 | $instanceID = CRM_Utils_Array::value('id', $params, CRM_Utils_Array::value('instance_id', $params)); |
6ea7a229 DS |
37 | |
38 | // convert roles array to string | |
39 | if (isset($params['grouprole']) && is_array($params['grouprole'])) { | |
be2fb01f | 40 | $grouprole_array = []; |
6ea7a229 DS |
41 | foreach ($params['grouprole'] as $key => $value) { |
42 | $grouprole_array[$value] = $value; | |
43 | } | |
44 | $params['grouprole'] = implode(CRM_Core_DAO::VALUE_SEPARATOR, | |
45 | array_keys($grouprole_array) | |
46 | ); | |
47 | } | |
48 | ||
08f06889 | 49 | if (!$instanceID || !isset($params['id'])) { |
0bbbbae1 | 50 | $params['is_reserved'] = CRM_Utils_Array::value('is_reserved', $params, FALSE); |
edb1d052 | 51 | $params['domain_id'] = CRM_Utils_Array::value('domain_id', $params, CRM_Core_Config::domainID()); |
aaf5f726 | 52 | // CRM-17256 set created_id on report creation. |
2e1f50d6 | 53 | $params['created_id'] = $params['created_id'] ?? CRM_Core_Session::getLoggedInContactID(); |
6ea7a229 DS |
54 | } |
55 | ||
56 | if ($instanceID) { | |
57 | CRM_Utils_Hook::pre('edit', 'ReportInstance', $instanceID, $params); | |
58 | } | |
59 | else { | |
60 | CRM_Utils_Hook::pre('create', 'ReportInstance', NULL, $params); | |
61 | } | |
62 | ||
0b25329b | 63 | $instance = new CRM_Report_DAO_ReportInstance(); |
fc944198 | 64 | $instance->copyValues($params); |
6ea7a229 | 65 | |
edb1d052 | 66 | if (CRM_Core_Config::singleton()->userFramework == 'Joomla') { |
6ea7a229 DS |
67 | $instance->permission = 'null'; |
68 | } | |
69 | ||
70 | // explicitly set to null if params value is empty | |
0bbbbae1 | 71 | if (!$instanceID && empty($params['grouprole'])) { |
6ea7a229 DS |
72 | $instance->grouprole = 'null'; |
73 | } | |
74 | ||
75 | if ($instanceID) { | |
76 | $instance->id = $instanceID; | |
77 | } | |
78 | ||
353ffa53 | 79 | if (!$instanceID) { |
a8d9a461 TO |
80 | if ($reportID = CRM_Utils_Array::value('report_id', $params)) { |
81 | $instance->report_id = $reportID; | |
0db6c3e1 | 82 | } |
4c9b6178 | 83 | elseif ($instanceID) { |
a8d9a461 | 84 | $instance->report_id = CRM_Report_Utils_Report::getValueFromUrl($instanceID); |
0db6c3e1 TO |
85 | } |
86 | else { | |
a8d9a461 TO |
87 | // just take it from current url |
88 | $instance->report_id = CRM_Report_Utils_Report::getValueFromUrl(); | |
89 | } | |
6ea7a229 | 90 | } |
a8d9a461 | 91 | |
6ea7a229 | 92 | $instance->save(); |
2efcf0c2 | 93 | |
6ea7a229 | 94 | if ($instanceID) { |
ba01526d | 95 | CRM_Utils_Hook::post('edit', 'ReportInstance', $instance->id, $instance); |
6ea7a229 DS |
96 | } |
97 | else { | |
ba01526d | 98 | CRM_Utils_Hook::post('create', 'ReportInstance', $instance->id, $instance); |
6ea7a229 DS |
99 | } |
100 | return $instance; | |
101 | } | |
102 | ||
103 | /** | |
fe482240 | 104 | * Create instance. |
182f5081 | 105 | * |
6ea7a229 DS |
106 | * takes an associative array and creates a instance object and does any related work like permissioning, adding to dashboard etc. |
107 | * | |
108 | * This function is invoked from within the web form layer and also from the api layer | |
109 | * | |
7e06c9f5 TO |
110 | * @param array $params |
111 | * (reference ) an assoc array of name/value pairs. | |
6ea7a229 | 112 | * |
16b10e64 | 113 | * @return CRM_Report_BAO_ReportInstance |
6ea7a229 | 114 | */ |
00be9182 | 115 | public static function &create(&$params) { |
0bbbbae1 | 116 | if (isset($params['report_header'])) { |
9c1bc317 | 117 | $params['header'] = $params['report_header'] ?? NULL; |
0bbbbae1 TO |
118 | } |
119 | if (isset($params['report_footer'])) { | |
9c1bc317 | 120 | $params['footer'] = $params['report_footer'] ?? NULL; |
0bbbbae1 | 121 | } |
6ea7a229 DS |
122 | |
123 | // build navigation parameters | |
a7488080 | 124 | if (!empty($params['is_navigation'])) { |
6ea7a229 | 125 | if (!array_key_exists('navigation', $params)) { |
be2fb01f | 126 | $params['navigation'] = []; |
6ea7a229 DS |
127 | } |
128 | $navigationParams =& $params['navigation']; | |
129 | ||
be2fb01f | 130 | $navigationParams['permission'] = []; |
6ea7a229 | 131 | $navigationParams['label'] = $params['title']; |
353ffa53 | 132 | $navigationParams['name'] = $params['title']; |
6ea7a229 | 133 | |
9c1bc317 CW |
134 | $navigationParams['current_parent_id'] = $navigationParams['parent_id'] ?? NULL; |
135 | $navigationParams['parent_id'] = $params['parent_id'] ?? NULL; | |
6ea7a229 DS |
136 | $navigationParams['is_active'] = 1; |
137 | ||
138 | if ($permission = CRM_Utils_Array::value('permission', $params)) { | |
139 | $navigationParams['permission'][] = $permission; | |
140 | } | |
141 | ||
142 | // unset the navigation related elements, not used in report form values | |
143 | unset($params['parent_id']); | |
144 | unset($params['is_navigation']); | |
145 | } | |
146 | ||
f7dbf5d9 | 147 | $viewMode = !empty($params['view_mode']); |
e6e7e540 | 148 | if ($viewMode) { |
149 | // Do not save to the DB - it's saved in the url. | |
150 | unset($params['view_mode']); | |
151 | } | |
152 | ||
6ea7a229 | 153 | // add to dashboard |
be2fb01f | 154 | $dashletParams = []; |
a7488080 | 155 | if (!empty($params['addToDashboard'])) { |
be2fb01f | 156 | $dashletParams = [ |
6ea7a229 DS |
157 | 'label' => $params['title'], |
158 | 'is_active' => 1, | |
be2fb01f | 159 | ]; |
6ea7a229 DS |
160 | if ($permission = CRM_Utils_Array::value('permission', $params)) { |
161 | $dashletParams['permission'][] = $permission; | |
162 | } | |
163 | } | |
164 | ||
165 | $transaction = new CRM_Core_Transaction(); | |
166 | ||
167 | $instance = self::add($params); | |
168 | if (is_a($instance, 'CRM_Core_Error')) { | |
169 | $transaction->rollback(); | |
170 | return $instance; | |
171 | } | |
172 | ||
173 | // add / update navigation as required | |
174 | if (!empty($navigationParams)) { | |
8cc574cf | 175 | if (empty($params['id']) && empty($params['instance_id']) && !empty($navigationParams['id'])) { |
6ea7a229 DS |
176 | unset($navigationParams['id']); |
177 | } | |
e6e7e540 | 178 | $navigationParams['url'] = "civicrm/report/instance/{$instance->id}" . ($viewMode == 'view' ? '?reset=1&force=1' : '?reset=1&output=criteria'); |
6ea7a229 DS |
179 | $navigation = CRM_Core_BAO_Navigation::add($navigationParams); |
180 | ||
a7488080 | 181 | if (!empty($navigationParams['is_active'])) { |
6ea7a229 | 182 | //set the navigation id in report instance table |
0b25329b | 183 | CRM_Core_DAO::setFieldValue('CRM_Report_DAO_ReportInstance', $instance->id, 'navigation_id', $navigation->id); |
6ea7a229 DS |
184 | } |
185 | else { | |
186 | // has been removed from the navigation bar | |
0b25329b | 187 | CRM_Core_DAO::setFieldValue('CRM_Report_DAO_ReportInstance', $instance->id, 'navigation_id', 'NULL'); |
6ea7a229 DS |
188 | } |
189 | //reset navigation | |
190 | CRM_Core_BAO_Navigation::resetNavigation(); | |
191 | } | |
192 | ||
193 | // add to dashlet | |
194 | if (!empty($dashletParams)) { | |
195 | $section = 2; | |
242055d3 | 196 | $chart = $limitResult = ''; |
a7488080 | 197 | if (!empty($params['charts'])) { |
6ea7a229 | 198 | $section = 1; |
353ffa53 | 199 | $chart = "&charts=" . $params['charts']; |
6ea7a229 | 200 | } |
a8f56d71 | 201 | if (!empty($params['row_count']) && CRM_Utils_Rule::positiveInteger($params['row_count'])) { |
dbb4a0f9 PN |
202 | $limitResult = '&rowCount=' . $params['row_count']; |
203 | } | |
a8f56d71 CW |
204 | if (!empty($params['cache_minutes']) && CRM_Utils_Rule::positiveInteger($params['cache_minutes'])) { |
205 | $dashletParams['cache_minutes'] = $params['cache_minutes']; | |
206 | } | |
db049bcd | 207 | $dashletParams['name'] = "report/{$instance->id}"; |
242055d3 CW |
208 | $dashletParams['url'] = "civicrm/report/instance/{$instance->id}?reset=1§ion={$section}{$chart}&context=dashlet" . $limitResult; |
209 | $dashletParams['fullscreen_url'] = "civicrm/report/instance/{$instance->id}?reset=1§ion={$section}{$chart}&context=dashletFullscreen" . $limitResult; | |
6ea7a229 DS |
210 | $dashletParams['instanceURL'] = "civicrm/report/instance/{$instance->id}"; |
211 | CRM_Core_BAO_Dashboard::addDashlet($dashletParams); | |
212 | } | |
213 | $transaction->commit(); | |
214 | ||
215 | return $instance; | |
216 | } | |
217 | ||
6a488035 | 218 | /** |
fe482240 | 219 | * Delete the instance of the Report. |
6a488035 | 220 | * |
100fef9d | 221 | * @param int $id |
6a488035 | 222 | * |
72b3a70c CW |
223 | * @return mixed |
224 | * $results no of deleted Instance on success, false otherwise | |
6a488035 | 225 | */ |
00be9182 | 226 | public static function del($id = NULL) { |
e3c612db | 227 | $navId = CRM_Core_DAO::getFieldValue('CRM_Report_DAO_ReportInstance', $id, 'navigation_id', 'id'); |
0b25329b | 228 | $dao = new CRM_Report_DAO_ReportInstance(); |
6a488035 | 229 | $dao->id = $id; |
e3c612db | 230 | $result = $dao->delete(); |
231 | ||
232 | // Delete navigation if exists. | |
233 | if ($navId) { | |
234 | CRM_Core_BAO_Navigation::processDelete($navId); | |
235 | CRM_Core_BAO_Navigation::resetNavigation(); | |
236 | } | |
237 | return $result; | |
6a488035 TO |
238 | } |
239 | ||
74cf4551 | 240 | /** |
98f1f7a1 | 241 | * Retrieve instance. |
242 | * | |
c490a46a | 243 | * @param array $params |
98f1f7a1 | 244 | * @param array $defaults |
74cf4551 EM |
245 | * |
246 | * @return CRM_Report_DAO_ReportInstance|null | |
247 | */ | |
00be9182 | 248 | public static function retrieve($params, &$defaults) { |
0b25329b | 249 | $instance = new CRM_Report_DAO_ReportInstance(); |
6a488035 TO |
250 | $instance->copyValues($params); |
251 | ||
252 | if ($instance->find(TRUE)) { | |
253 | CRM_Core_DAO::storeValues($instance, $defaults); | |
6a488035 TO |
254 | return $instance; |
255 | } | |
256 | return NULL; | |
257 | } | |
96025800 | 258 | |
0f8c6e58 | 259 | /** |
260 | * Check if report is private. | |
261 | * | |
262 | * @param int $instance_id | |
263 | * | |
264 | * @return bool | |
265 | */ | |
266 | public static function reportIsPrivate($instance_id) { | |
267 | $owner_id = CRM_Core_DAO::getFieldValue('CRM_Report_DAO_ReportInstance', $instance_id, 'owner_id', 'id'); | |
268 | if ($owner_id) { | |
269 | return TRUE; | |
270 | } | |
271 | return FALSE; | |
272 | } | |
273 | ||
274 | /** | |
275 | * Check if the logged in user is the owner. | |
276 | * | |
277 | * @param int $instance_id | |
278 | * | |
279 | * @return TRUE if contact owns the report, FALSE if not | |
280 | */ | |
281 | public static function contactIsOwner($instance_id) { | |
282 | $session = CRM_Core_Session::singleton(); | |
283 | $contact_id = $session->get('userID'); | |
284 | $owner_id = CRM_Core_DAO::getFieldValue('CRM_Report_DAO_ReportInstance', $instance_id, 'owner_id', 'id'); | |
285 | if ($contact_id === $owner_id) { | |
286 | return TRUE; | |
287 | } | |
288 | return FALSE; | |
289 | } | |
290 | ||
291 | /** | |
292 | * Check if the logged in contact can administer the report. | |
293 | * | |
294 | * @param int $instance_id | |
295 | * | |
296 | * @return bool | |
297 | * True if contact can edit the private report, FALSE if not. | |
298 | */ | |
299 | public static function contactCanAdministerReport($instance_id) { | |
300 | if (self::reportIsPrivate($instance_id)) { | |
301 | if (self::contactIsOwner($instance_id) || CRM_Core_Permission::check('access all private reports')) { | |
302 | return TRUE; | |
303 | } | |
304 | } | |
305 | elseif (CRM_Core_Permission::check('administer Reports')) { | |
306 | return TRUE; | |
307 | } | |
308 | return FALSE; | |
309 | } | |
310 | ||
e3c612db | 311 | /** |
312 | * Delete a report instance wrapped in handling for the form layer. | |
313 | * | |
314 | * @param int $instanceId | |
315 | * @param string $bounceTo | |
316 | * Url to redirect the browser to on fail. | |
317 | * @param string $successRedirect | |
318 | */ | |
319 | public static function doFormDelete($instanceId, $bounceTo = 'civicrm/report/list?reset=1', $successRedirect = NULL) { | |
320 | if (!CRM_Core_Permission::check('administer Reports')) { | |
321 | $statusMessage = ts('You do not have permission to Delete Report.'); | |
322 | CRM_Core_Error::statusBounce($statusMessage, $bounceTo); | |
323 | } | |
324 | ||
325 | CRM_Report_BAO_ReportInstance::del($instanceId); | |
326 | ||
327 | CRM_Core_Session::setStatus(ts('Selected report has been deleted.'), ts('Deleted'), 'success'); | |
328 | if ($successRedirect) { | |
329 | CRM_Utils_System::redirect(CRM_Utils_System::url($successRedirect)); | |
330 | } | |
331 | } | |
332 | ||
44543184 | 333 | /** |
334 | * Get the metadata of actions available for this entity. | |
1a7356e7 | 335 | * |
336 | * The thinking here is to describe the various actions on the BAO and then functions | |
337 | * can add a mix of actions from different BAO as appropriate. The crm.SearchForm.js code | |
338 | * transforms the 'confirm_mesage' into a message that needs to be confirmed. | |
339 | * confirm_refresh_fields need to be reviewed & potentially updated at the confirm stage. | |
340 | * | |
341 | * Ideas not yet implemented: | |
342 | * - supports_modal task can be loaded in a popup, theoretically worked, not attempted. | |
343 | * - class and or icon - per option icons or classes (I added these in addTaskMenu::addTaskMenu | |
344 | * but I didn't have the right classes). ie adding 'class' => 'crm-i fa-print' to print / class looked | |
345 | * wrong, but at the php level it worked https://github.com/civicrm/civicrm-core/pull/8529#issuecomment-227639091 | |
346 | * - general script-add. | |
44543184 | 347 | */ |
348 | public static function getActionMetadata() { | |
be2fb01f | 349 | $actions = []; |
4341efe4 | 350 | if (CRM_Core_Permission::check('save Report Criteria')) { |
be2fb01f CW |
351 | $actions['report_instance.save'] = ['title' => ts('Save')]; |
352 | $actions['report_instance.copy'] = [ | |
1a7356e7 | 353 | 'title' => ts('Save a Copy'), |
be2fb01f | 354 | 'data' => [ |
1a7356e7 | 355 | 'is_confirm' => TRUE, |
356 | 'confirm_title' => ts('Save a copy...'), | |
be2fb01f CW |
357 | 'confirm_refresh_fields' => json_encode([ |
358 | 'title' => [ | |
4341efe4 JV |
359 | 'selector' => '.crm-report-instanceForm-form-block-title', |
360 | 'prepend' => ts('(Copy) '), | |
be2fb01f CW |
361 | ], |
362 | 'description' => [ | |
4341efe4 JV |
363 | 'selector' => '.crm-report-instanceForm-form-block-description', |
364 | 'prepend' => '', | |
be2fb01f CW |
365 | ], |
366 | 'parent_id' => [ | |
4341efe4 JV |
367 | 'selector' => '.crm-report-instanceForm-form-block-parent_id', |
368 | 'prepend' => '', | |
be2fb01f CW |
369 | ], |
370 | ]), | |
371 | ], | |
372 | ]; | |
4341efe4 | 373 | } |
be2fb01f CW |
374 | $actions['report_instance.print'] = ['title' => ts('Print Report')]; |
375 | $actions['report_instance.pdf'] = ['title' => ts('Print to PDF')]; | |
376 | $actions['report_instance.csv'] = ['title' => ts('Export as CSV')]; | |
4341efe4 | 377 | |
44543184 | 378 | if (CRM_Core_Permission::check('administer Reports')) { |
be2fb01f | 379 | $actions['report_instance.delete'] = [ |
44543184 | 380 | 'title' => ts('Delete report'), |
be2fb01f | 381 | 'data' => [ |
1a7356e7 | 382 | 'is_confirm' => TRUE, |
383 | 'confirm_message' => ts('Are you sure you want delete this report? This action cannot be undone.'), | |
be2fb01f CW |
384 | ], |
385 | ]; | |
44543184 | 386 | } |
387 | return $actions; | |
388 | } | |
389 | ||
6a488035 | 390 | } |