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