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