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