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