Merge pull request #2006 from civicrm/4.3
[civicrm-core.git] / CRM / Core / BAO / Dashboard.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.4 |
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 */
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 *
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 */
85 static function getContactDashlets($flatFormat = FALSE) {
86 $dashlets = array();
87
88 $contactID = CRM_Core_Session::singleton()->get('userID');
89
90 // get contact dashboard dashlets
91 $hasDashlets = FALSE;
92 $dao = new CRM_Contact_DAO_DashboardContact();
93 $dao->contact_id = $contactID;
94 $dao->orderBy('column_no asc, weight asc');
95 $dao->find();
96 while ($dao->fetch()) {
97 $hasDashlets = TRUE;
98 if (!$flatFormat) {
99 if ($dao->is_active) {
100 // append weight so that order is preserved.
101 $dashlets[$dao->column_no]["{$dao->weight}-{$dao->dashboard_id}"] = $dao->is_minimized;
102 }
103 }
104 else {
105 $dashlets[$dao->dashboard_id] = $dao->dashboard_id;
106 }
107 }
108
109 if ($flatFormat) {
110 return $dashlets;
111 }
112
113 // If empty then initialize contact dashboard for this user
114 if (!$hasDashlets) {
115 $defaultDashlets = self::getDashlets();
116 if ($defaultDashlets) {
117 // Add dashlet entries for logged in contact
118 // TODO: need to optimize this sql
119 $items = '';
120 foreach ($defaultDashlets as $key => $values) {
121 // Set civicrm blog as default enabled
122 $default = $values['url'] == 'civicrm/dashlet/blog&reset=1&snippet=5' ? 1 : 0;
123 $items .= ($items ? ', ' : '') . "($key, $contactID, $default, $default)";
124 }
125 $query = "INSERT INTO civicrm_dashboard_contact (dashboard_id, contact_id, column_no, is_active) VALUES $items";
126 CRM_Core_DAO::executeQuery($query);
127 }
128 }
129
130 return $dashlets;
131 }
132
133 /**
134 * Function to check dashlet permission for current user
135 *
136 * @param string permission string
137 *
138 * @return boolean true if use has permission else false
139 */
140 static function checkPermission($permission, $operator) {
141 if ($permission) {
142 $permissions = explode(',', $permission);
143 $config = CRM_Core_Config::singleton();
144
145 static $allComponents;
146 if (!$allComponents) {
147 $allComponents = CRM_Core_Component::getNames();
148 }
149
150 $hasPermission = FALSE;
151 foreach ($permissions as $key) {
152 $showDashlet = TRUE;
153
154 $componentName = NULL;
155 if (strpos($key, 'access') === 0) {
156 $componentName = trim(substr($key, 6));
157 if (!in_array($componentName, $allComponents)) {
158 $componentName = NULL;
159 }
160 }
161
162 // hack to handle case permissions
163 if (!$componentName && in_array($key, array(
164 'access my cases and activities', 'access all cases and activities'))) {
165 $componentName = 'CiviCase';
166 }
167
168 //hack to determine if it's a component related permission
169 if ($componentName) {
170 if (!in_array($componentName, $config->enableComponents) ||
171 !CRM_Core_Permission::check($key)
172 ) {
173 $showDashlet = FALSE;
174 if ($operator == 'AND') {
175 return $showDashlet;
176 }
177 }
178 else {
179 $hasPermission = TRUE;
180 }
181 }
182 elseif (!CRM_Core_Permission::check($key)) {
183 $showDashlet = FALSE;
184 if ($operator == 'AND') {
185 return $showDashlet;
186 }
187 }
188 else {
189 $hasPermission = TRUE;
190 }
191 }
192
193 if (!$showDashlet && !$hasPermission) {
194 return FALSE;
195 }
196 else {
197 return TRUE;
198 }
199 }
200 else {
201 // if permission is not set consider everyone has permission to access it.
202 return TRUE;
203 }
204 }
205
206 /**
207 * Function to get details of each dashlets
208 *
209 * @param int $dashletID widget ID
210 *
211 * @return array associted array title and content
212 * @access public
213 * @static
214 */
215 static function getDashletInfo($dashletID) {
216 $dashletInfo = array();
217
218 $params = array(1 => array($dashletID, 'Integer'));
219 $query = "SELECT label, url, fullscreen_url, is_fullscreen FROM civicrm_dashboard WHERE id = %1";
220 $dashboadDAO = CRM_Core_DAO::executeQuery($query, $params);
221 $dashboadDAO->fetch();
222
223 // build the content
224 $dao = new CRM_Contact_DAO_DashboardContact();
225
226 $session = CRM_Core_Session::singleton();
227 $dao->contact_id = $session->get('userID');
228 $dao->dashboard_id = $dashletID;
229 $dao->find(TRUE);
230
231 //reset content based on the cache time set in config
232 $createdDate = strtotime($dao->created_date);
233 $dateDiff = round(abs(time() - $createdDate) / 60);
234
235 $config = CRM_Core_Config::singleton();
236 if ($config->dashboardCacheTimeout <= $dateDiff) {
237 $dao->content = NULL;
238 }
239
240 // if content is empty and url is set, retrieve it from url
241 if (!$dao->content && $dashboadDAO->url) {
242 $url = $dashboadDAO->url;
243
244 // CRM-7087
245 // -lets use relative url for internal use.
246 // -make sure relative url should not be htmlize.
247 if (substr($dashboadDAO->url, 0, 4) != 'http') {
248 $urlParam = CRM_Utils_System::explode('&', $dashboadDAO->url, 2);
249 $url = CRM_Utils_System::url($urlParam[0], $urlParam[1], TRUE, NULL, FALSE);
250 }
251
252 //get content from url
253 $dao->content = CRM_Utils_System::getServerResponse($url);
254 $dao->created_date = date("YmdHis");
255 $dao->save();
256 }
257
258 $dashletInfo = array(
259 'title' => $dashboadDAO->label,
260 'content' => $dao->content,
261 );
262
263 if ($dashboadDAO->is_fullscreen) {
264 $fullscreenUrl = $dashboadDAO->fullscreen_url;
265 if (substr($fullscreenUrl, 0, 4) != 'http') {
266 $urlParam = CRM_Utils_System::explode('&', $dashboadDAO->fullscreen_url, 2);
267 $fullscreenUrl = CRM_Utils_System::url($urlParam[0], $urlParam[1], TRUE, NULL, FALSE);
268 }
269 $dashletInfo['fullscreenUrl'] = $fullscreenUrl;
270 }
271 return $dashletInfo;
272 }
273
274 /**
275 * Function to save changes made by use to the Dashlet
276 *
277 * @param array $columns associated array
278 *
279 * @return void
280 * @access public
281 * @static
282 */
283 static function saveDashletChanges($columns) {
284 $session = CRM_Core_Session::singleton();
285 $contactID = $session->get('userID');
286
287 //we need to get existing dashletes, so we know when to update or insert
288 $contactDashlets = self::getContactDashlets(TRUE);
289
290 $dashletIDs = array();
291 if (is_array($columns)) {
292 foreach ($columns as $colNo => $dashlets) {
293 if (!is_integer($colNo)) {
294 continue;
295 }
296 $weight = 1;
297 foreach ($dashlets as $dashletID => $isMinimized) {
298 $isMinimized = (int) $isMinimized;
299 if (in_array($dashletID, $contactDashlets)) {
300 $query = " UPDATE civicrm_dashboard_contact
301 SET weight = {$weight}, is_minimized = {$isMinimized}, column_no = {$colNo}, is_active = 1
302 WHERE dashboard_id = {$dashletID} AND contact_id = {$contactID} ";
303 }
304 else {
305 $query = " INSERT INTO civicrm_dashboard_contact
306 ( weight, is_minimized, column_no, is_active, dashboard_id, contact_id )
307 VALUES( {$weight}, {$isMinimized}, {$colNo}, 1, {$dashletID}, {$contactID} )";
308 }
309 // fire update query for each column
310 $dao = CRM_Core_DAO::executeQuery($query);
311
312 $dashletIDs[] = $dashletID;
313 $weight++;
314 }
315 }
316 }
317
318 if (!empty($dashletIDs)) {
319 // we need to disable widget that removed
320 $updateQuery = " UPDATE civicrm_dashboard_contact
321 SET is_active = 0
322 WHERE dashboard_id NOT IN ( " . implode(',', $dashletIDs) . ") AND contact_id = {$contactID}";
323 }
324 else {
325 // this means all widgets are disabled
326 $updateQuery = " UPDATE civicrm_dashboard_contact
327 SET is_active = 0
328 WHERE contact_id = {$contactID}";
329 }
330
331 CRM_Core_DAO::executeQuery($updateQuery);
332 }
333
334 /**
335 * Function to add dashlets
336 *
337 * @param array $params associated array
338 *
339 * @return object $dashlet returns dashlet object
340 * @access public
341 * @static
342 */
343 static function addDashlet(&$params) {
344
345 // special case to handle duplicate entires for report instances
346 $dashboardID = NULL;
347 if (CRM_Utils_Array::value('instanceURL', $params)) {
348 $query = "SELECT id
349 FROM `civicrm_dashboard`
350 WHERE url LIKE '" . CRM_Utils_Array::value('instanceURL', $params) . "&%'";
351 $dashboardID = CRM_Core_DAO::singleValueQuery($query);
352 }
353
354 $dashlet = new CRM_Core_DAO_Dashboard();
355
356 if (!$dashboardID) {
357 // check url is same as exiting entries, if yes just update existing
358 $dashlet->url = CRM_Utils_Array::value('url', $params);
359 $dashlet->find(TRUE);
360 }
361 else {
362 $dashlet->id = $dashboardID;
363 }
364
365 if (is_array(CRM_Utils_Array::value('permission', $params))) {
366 $params['permission'] = implode(',', $params['permission']);
367 }
368 $dashlet->copyValues($params);
369
370 $dashlet->domain_id = CRM_Core_Config::domainID();
371
372 $dashlet->save();
373
374 // now we need to make dashlet entries for each contact
375 self::addContactDashlet($dashlet);
376
377 return $dashlet;
378 }
379
380 /**
381 * Update contact dashboard with new dashlet
382 *
383 * @param object: $dashlet
384 *
385 * @return void
386 * @static
387 */
388 static function addContactDashlet($dashlet) {
389 $admin = CRM_Core_Permission::check('administer CiviCRM');
390
391 // if dashlet is created by admin then you need to add it all contacts.
392 // else just add to contact who is creating this dashlet
393 $contactIDs = array();
394 if ($admin) {
395 $query = "SELECT distinct( contact_id )
396 FROM civicrm_dashboard_contact
397 WHERE contact_id NOT IN (
398 SELECT distinct( contact_id )
399 FROM civicrm_dashboard_contact WHERE dashboard_id = {$dashlet->id}
400 )";
401
402 $dao = CRM_Core_DAO::executeQuery($query);
403 while ($dao->fetch()) {
404 $contactIDs[] = $dao->contact_id;
405 }
406 }
407 else {
408 //Get the id of Logged in User
409 $session = CRM_Core_Session::singleton();
410 $contactIDs[] = $session->get('userID');
411 }
412
413 if (!empty($contactIDs)) {
414 foreach ($contactIDs as $contactID) {
415 $valuesArray[] = " ( {$dashlet->id}, {$contactID} )";
416 }
417
418 $valuesString = implode(',', $valuesArray);
419 $query = "
420 INSERT INTO civicrm_dashboard_contact ( dashboard_id, contact_id )
421 VALUES {$valuesString}";
422
423 CRM_Core_DAO::executeQuery($query);
424 }
425 }
426
427 /**
428 * Function to reset dashlet cache
429 *
430 * @param int $contactID reset cache only for specific contact
431 *
432 * @return void
433 * @static
434 */
435 static function resetDashletCache($contactID = null) {
436 $whereClause = null;
437 $params = array();
438 if ($contactID) {
439 $whereClause = "WHERE contact_id = %1";
440 $params[1] = array($contactID, 'Integer');
441 }
442 $query = "UPDATE civicrm_dashboard_contact SET content = NULL $whereClause";
443 $dao = CRM_Core_DAO::executeQuery($query, $params);
444 }
445
446 /**
447 * Delete Dashlet
448 *
449 * @return void
450 * @static
451 */
452 static function deleteDashlet($dashletID) {
453 $dashlet = new CRM_Core_DAO_Dashboard();
454 $dashlet->id = $dashletID;
455 $dashlet->delete();
456 }
457 }
458