INFRA-132 - CRM/ - PHPStorm cleanup
[civicrm-core.git] / CRM / Core / BAO / Dashboard.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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-2014
32 * $Id$
33 *
34 */
35
36 /**
37 * Class contains Contact dashboard related functions
38 */
39 class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
40 /**
41 * Add Dashboard
42 *
43 * @param array $params
44 * Values.
45 *
46 * @static
47 *
48 * @return object
49 */
50 public static function create($params) {
51 $hook = empty($params['id']) ? 'create' : 'edit';
52 CRM_Utils_Hook::pre($hook, 'Dashboard', CRM_Utils_Array::value('id', $params), $params);
53 $dao = self::addDashlet($params);
54 CRM_Utils_Hook::post($hook, 'Dashboard', $dao->id, $dao);
55 return $dao;
56 }
57
58 /**
59 * Get the list of dashlets enabled by admin
60 *
61 * @param bool $all
62 * All or only active.
63 * @param bool $checkPermission
64 * All or only authorized for the current user.
65 *
66 * @return array
67 * array of dashlets
68 * @static
69 */
70 public static function getDashlets($all = TRUE, $checkPermission = TRUE) {
71 $dashlets = array();
72 $dao = new CRM_Core_DAO_Dashboard();
73
74 if (!$all) {
75 $dao->is_active = 1;
76 }
77
78 $dao->domain_id = CRM_Core_Config::domainID();
79
80 $dao->find();
81 while ($dao->fetch()) {
82 if ($checkPermission && !self::checkPermission($dao->permission, $dao->permission_operator)) {
83 continue;
84 }
85
86 $values = array();
87 CRM_Core_DAO::storeValues($dao, $values);
88 $dashlets[$dao->id] = $values;
89 }
90
91 return $dashlets;
92 }
93
94 /**
95 * Get the list of dashlets for the current user or the specified user.
96 *
97 * Additionlly, initializes the dashboard with defaults if this is the
98 * user's first visit to their dashboard.
99 *
100 * @param bool $flatFormat
101 * This is true if you want simple associated.
102 * array of all the contact's dashlets whether or not they are enabled.
103 *
104 * @param int $contactID
105 * Provide the dashlets for the contact id.
106 * passed rather than the current user.
107 *
108 * @return array
109 * array of dashlets
110 * @static
111 */
112 public static function getContactDashlets($flatFormat = FALSE, $contactID = NULL) {
113 $dashlets = array();
114
115 if (!$contactID) {
116 $contactID = CRM_Core_Session::singleton()->get('userID');
117 }
118
119 // Get contact dashboard dashlets.
120 $hasDashlets = FALSE;
121 $dao = new CRM_Contact_DAO_DashboardContact();
122 $dao->contact_id = $contactID;
123 $dao->orderBy('column_no asc, weight asc');
124 $dao->find();
125 while ($dao->fetch()) {
126 // When a dashlet is removed, it stays in the table with status disabled,
127 // so even if a user decides not to have any dashlets show, they will still
128 // have records in the table to indicate that we are not newly initializing.
129 $hasDashlets = TRUE;
130 if (!$flatFormat) {
131 if ($dao->is_active) {
132 // append weight so that order is preserved.
133 $dashlets[$dao->column_no]["{$dao->weight}-{$dao->dashboard_id}"] = $dao->is_minimized;
134 }
135 }
136 else {
137 $dashlets[$dao->dashboard_id] = $dao->dashboard_id;
138 }
139 }
140
141 if ($flatFormat) {
142 return $dashlets;
143 }
144
145 // If empty, then initialize contact dashboard for this user.
146 if (!$hasDashlets) {
147 return self::initializeDashlets();
148 }
149 return $dashlets;
150 }
151
152 /**
153 * Setup default dashlets for new users
154 *
155 * When a user accesses their dashboard for the first time, set up
156 * the default dashlets.
157 *
158 * @return array
159 * of dashboard_id's
160 */
161 public static function initializeDashlets() {
162 $dashlets = array();
163 $getDashlets = civicrm_api3("Dashboard", "get", array(
164 'domain_id' => CRM_Core_Config::domainID(),
165 'option.limit' => 0
166 ));
167 $contactID = CRM_Core_Session::singleton()->get('userID');
168 $allDashlets = CRM_Utils_Array::index(array('name'), $getDashlets['values']);
169 $defaultDashlets = array();
170 if (CRM_Utils_Array::value('blog', $allDashlets)) {
171 $defaultDashlets['blog'] = array(
172 'dashboard_id' => $allDashlets['blog']['id'],
173 'is_active' => 1,
174 'column_no' => 1,
175 'contact_id' => $contactID,
176 );
177 }
178 CRM_Utils_Hook::dashboard_defaults($allDashlets, $defaultDashlets);
179 if (is_array($defaultDashlets) && !empty($defaultDashlets)) {
180 foreach ($defaultDashlets as $id => $defaultDashlet) {
181 $dashboard_id = $defaultDashlet['dashboard_id'];
182 if (!self::checkPermission($getDashlets['values'][$dashboard_id]['permission'],
183 $getDashlets['values'][$dashboard_id]['permission_operator'])
184 ) {
185 continue;
186 }
187 else {
188 $assignDashlets = civicrm_api3("dashboard_contact", "create", $defaultDashlet);
189 $dashlets[$dashboard_id] = $defaultDashlet['dashboard_id'];
190 }
191 }
192 }
193 return $dashlets;
194 }
195
196
197 /**
198 * Check dashlet permission for current user
199 *
200 * @param string $permission
201 * Comma separated list.
202 * @param string $operator
203 *
204 * @return boolean
205 * true if use has permission else false
206 */
207 public static function checkPermission($permission, $operator) {
208 if ($permission) {
209 $permissions = explode(',', $permission);
210 $config = CRM_Core_Config::singleton();
211
212 static $allComponents;
213 if (!$allComponents) {
214 $allComponents = CRM_Core_Component::getNames();
215 }
216
217 $hasPermission = FALSE;
218 foreach ($permissions as $key) {
219 $showDashlet = TRUE;
220
221 $componentName = NULL;
222 if (strpos($key, 'access') === 0) {
223 $componentName = trim(substr($key, 6));
224 if (!in_array($componentName, $allComponents)) {
225 $componentName = NULL;
226 }
227 }
228
229 // hack to handle case permissions
230 if (!$componentName && in_array($key, array(
231 'access my cases and activities',
232 'access all cases and activities'
233 ))
234 ) {
235 $componentName = 'CiviCase';
236 }
237
238 //hack to determine if it's a component related permission
239 if ($componentName) {
240 if (!in_array($componentName, $config->enableComponents) ||
241 !CRM_Core_Permission::check($key)
242 ) {
243 $showDashlet = FALSE;
244 if ($operator == 'AND') {
245 return $showDashlet;
246 }
247 }
248 else {
249 $hasPermission = TRUE;
250 }
251 }
252 elseif (!CRM_Core_Permission::check($key)) {
253 $showDashlet = FALSE;
254 if ($operator == 'AND') {
255 return $showDashlet;
256 }
257 }
258 else {
259 $hasPermission = TRUE;
260 }
261 }
262
263 if (!$showDashlet && !$hasPermission) {
264 return FALSE;
265 }
266 else {
267 return TRUE;
268 }
269 }
270 else {
271 // if permission is not set consider everyone has permission to access it.
272 return TRUE;
273 }
274 }
275
276 /**
277 * Get details of each dashlets
278 *
279 * @param int $dashletID
280 * Widget ID.
281 *
282 * @return array
283 * associted array title and content
284 * @static
285 */
286 public static function getDashletInfo($dashletID) {
287 $dashletInfo = array();
288
289 $params = array(1 => array($dashletID, 'Integer'));
290 $query = "SELECT name, label, url, fullscreen_url, is_fullscreen FROM civicrm_dashboard WHERE id = %1";
291 $dashboadDAO = CRM_Core_DAO::executeQuery($query, $params);
292 $dashboadDAO->fetch();
293
294 // build the content
295 $dao = new CRM_Contact_DAO_DashboardContact();
296
297 $session = CRM_Core_Session::singleton();
298 $dao->contact_id = $session->get('userID');
299 $dao->dashboard_id = $dashletID;
300 $dao->find(TRUE);
301
302 //reset content based on the cache time set in config
303 $createdDate = strtotime($dao->created_date);
304 $dateDiff = round(abs(time() - $createdDate) / 60);
305
306 $config = CRM_Core_Config::singleton();
307 if ($config->dashboardCacheTimeout <= $dateDiff) {
308 $dao->content = NULL;
309 }
310
311 // if content is empty and url is set, retrieve it from url
312 if (!$dao->content && $dashboadDAO->url) {
313 $url = $dashboadDAO->url;
314
315 // CRM-7087
316 // -lets use relative url for internal use.
317 // -make sure relative url should not be htmlize.
318 if (substr($dashboadDAO->url, 0, 4) != 'http') {
319 $urlParam = explode('?', $dashboadDAO->url);
320 $url = CRM_Utils_System::url($urlParam[0], $urlParam[1], TRUE, NULL, FALSE);
321 }
322
323 //get content from url
324 $dao->content = CRM_Utils_System::getServerResponse($url);
325 $dao->created_date = date("YmdHis");
326 $dao->save();
327 }
328
329 $dashletInfo = array(
330 'title' => $dashboadDAO->label,
331 'name' => $dashboadDAO->name,
332 'content' => $dao->content,
333 );
334
335 if ($dashboadDAO->is_fullscreen) {
336 $fullscreenUrl = $dashboadDAO->fullscreen_url;
337 if (substr($fullscreenUrl, 0, 4) != 'http') {
338 $urlParam = explode('?', $dashboadDAO->fullscreen_url);
339 $fullscreenUrl = CRM_Utils_System::url($urlParam[0], $urlParam[1], TRUE, NULL, FALSE);
340 }
341 $dashletInfo['fullscreenUrl'] = $fullscreenUrl;
342 }
343 return $dashletInfo;
344 }
345
346 /**
347 * Save changes made by use to the Dashlet
348 *
349 * @param array $columns
350 * Associated array.
351 *
352 * @param int $contactID
353 *
354 * @throws RuntimeException
355 * @return void
356 * @static
357 */
358 public static function saveDashletChanges($columns, $contactID = NULL) {
359 $session = CRM_Core_Session::singleton();
360 if (!$contactID) {
361 $contactID = $session->get('userID');
362 }
363
364 if (empty($contactID)) {
365 throw new RuntimeException("Failed to determine contact ID");
366 }
367
368 //we need to get existing dashlets, so we know when to update or insert
369 $contactDashlets = self::getContactDashlets(TRUE, $contactID);
370
371 $dashletIDs = array();
372 if (is_array($columns)) {
373 foreach ($columns as $colNo => $dashlets) {
374 if (!is_integer($colNo)) {
375 continue;
376 }
377 $weight = 1;
378 foreach ($dashlets as $dashletID => $isMinimized) {
379 $isMinimized = (int) $isMinimized;
380 if (in_array($dashletID, $contactDashlets)) {
381 $query = " UPDATE civicrm_dashboard_contact
382 SET weight = {$weight}, is_minimized = {$isMinimized}, column_no = {$colNo}, is_active = 1
383 WHERE dashboard_id = {$dashletID} AND contact_id = {$contactID} ";
384 }
385 else {
386 $query = " INSERT INTO civicrm_dashboard_contact
387 ( weight, is_minimized, column_no, is_active, dashboard_id, contact_id )
388 VALUES( {$weight}, {$isMinimized}, {$colNo}, 1, {$dashletID}, {$contactID} )";
389 }
390 // fire update query for each column
391 $dao = CRM_Core_DAO::executeQuery($query);
392
393 $dashletIDs[] = $dashletID;
394 $weight++;
395 }
396 }
397 }
398
399 if (!empty($dashletIDs)) {
400 // we need to disable widget that removed
401 $updateQuery = " UPDATE civicrm_dashboard_contact
402 SET is_active = 0
403 WHERE dashboard_id NOT IN ( " . implode(',', $dashletIDs) . ") AND contact_id = {$contactID}";
404 }
405 else {
406 // this means all widgets are disabled
407 $updateQuery = " UPDATE civicrm_dashboard_contact
408 SET is_active = 0
409 WHERE contact_id = {$contactID}";
410 }
411
412 CRM_Core_DAO::executeQuery($updateQuery);
413 }
414
415 /**
416 * Add dashlets
417 *
418 * @param array $params
419 * Associated array.
420 *
421 * @return object
422 * $dashlet returns dashlet object
423 * @static
424 */
425 public static function addDashlet(&$params) {
426
427 // special case to handle duplicate entries for report instances
428 $dashboardID = CRM_Utils_Array::value('id', $params);
429
430 if (!empty($params['instanceURL'])) {
431 $query = "SELECT id
432 FROM `civicrm_dashboard`
433 WHERE url LIKE '" . CRM_Utils_Array::value('instanceURL', $params) . "&%'";
434 $dashboardID = CRM_Core_DAO::singleValueQuery($query);
435 }
436
437 $dashlet = new CRM_Core_DAO_Dashboard();
438
439 if (!$dashboardID) {
440 // check url is same as exiting entries, if yes just update existing
441 if (!empty($params['name'])) {
442 $dashlet->name = CRM_Utils_Array::value('name', $params);
443 $dashlet->find(TRUE);
444 }
445 else {
446 $dashlet->url = CRM_Utils_Array::value('url', $params);
447 $dashlet->find(TRUE);
448 }
449 if (empty($params['domain_id'])) {
450 $dashlet->domain_id = CRM_Core_Config::domainID();
451 }
452 }
453 else {
454 $dashlet->id = $dashboardID;
455 }
456
457 if (is_array(CRM_Utils_Array::value('permission', $params))) {
458 $params['permission'] = implode(',', $params['permission']);
459 }
460 $dashlet->copyValues($params);
461 $dashlet->save();
462
463 // now we need to make dashlet entries for each contact
464 self::addContactDashlet($dashlet);
465
466 return $dashlet;
467 }
468
469 /**
470 * @param $url
471 *
472 * @return string
473 */
474 public static function getDashletName($url) {
475 $urlElements = explode('/', $url);
476 if ($urlElements[1] == 'dashlet') {
477 return $urlElements[2];
478 }
479 elseif ($urlElements[1] == 'report') {
480 return 'report/' . $urlElements[3];
481 }
482 return $url;
483 }
484
485 /**
486 * Update contact dashboard with new dashlet
487 *
488 * @param object : $dashlet
489 *
490 * @return void
491 * @static
492 */
493 public static function addContactDashlet($dashlet) {
494 $admin = CRM_Core_Permission::check('administer CiviCRM');
495
496 // if dashlet is created by admin then you need to add it all contacts.
497 // else just add to contact who is creating this dashlet
498 $contactIDs = array();
499 if ($admin) {
500 $query = "SELECT distinct( contact_id )
501 FROM civicrm_dashboard_contact
502 WHERE contact_id NOT IN (
503 SELECT distinct( contact_id )
504 FROM civicrm_dashboard_contact WHERE dashboard_id = {$dashlet->id}
505 )";
506
507 $dao = CRM_Core_DAO::executeQuery($query);
508 while ($dao->fetch()) {
509 $contactIDs[] = $dao->contact_id;
510 }
511 }
512 else {
513 //Get the id of Logged in User
514 $session = CRM_Core_Session::singleton();
515 $contactID = $session->get('userID');
516 if (!empty($contactID)) {
517 $contactIDs[] = $session->get('userID');
518 }
519 }
520
521 if (!empty($contactIDs)) {
522 foreach ($contactIDs as $contactID) {
523 $valuesArray[] = " ( {$dashlet->id}, {$contactID} )";
524 }
525
526 $valuesString = implode(',', $valuesArray);
527 $query = "
528 INSERT INTO civicrm_dashboard_contact ( dashboard_id, contact_id )
529 VALUES {$valuesString}";
530
531 CRM_Core_DAO::executeQuery($query);
532 }
533 }
534
535 /**
536 * @param array $params
537 * Each item is a spec for a dashlet on the contact's dashboard.
538 * @return bool
539 */
540 public static function addContactDashletToDashboard(&$params) {
541 $valuesString = NULL;
542 $columns = array();
543 foreach ($params as $dashboardIDs) {
544 $contactID = CRM_Utils_Array::value('contact_id', $dashboardIDs);
545 $dashboardID = CRM_Utils_Array::value('dashboard_id', $dashboardIDs);
546 $column = CRM_Utils_Array::value('column_no', $dashboardIDs, 0);
547 $columns[$column][$dashboardID] = 0;
548 }
549 self::saveDashletChanges($columns, $contactID);
550 return TRUE;
551 }
552
553 /**
554 * Reset dashlet cache
555 *
556 * @param int $contactID
557 * Reset cache only for specific contact.
558 *
559 * @return void
560 * @static
561 */
562 public static function resetDashletCache($contactID = NULL) {
563 $whereClause = NULL;
564 $params = array();
565 if ($contactID) {
566 $whereClause = "WHERE contact_id = %1";
567 $params[1] = array($contactID, 'Integer');
568 }
569 $query = "UPDATE civicrm_dashboard_contact SET content = NULL $whereClause";
570 $dao = CRM_Core_DAO::executeQuery($query, $params);
571 }
572
573 /**
574 * Delete Dashlet
575 *
576 * @param int $dashletID
577 *
578 * @return void
579 * @static
580 */
581 public static function deleteDashlet($dashletID) {
582 $dashlet = new CRM_Core_DAO_Dashboard();
583 $dashlet->id = $dashletID;
584 $dashlet->delete();
585 return TRUE;
586 }
587 }