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