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