CRM-17663 - Implement localStorage cache
[civicrm-core.git] / CRM / Core / BAO / Dashboard.php
index 5759ae679d4142bfec17f3a818a4ef0146de525d..1b14cdd2ca89f9d02910e61231c2fc297a658388 100644 (file)
@@ -93,71 +93,88 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
    * Additionlly, initializes the dashboard with defaults if this is the
    * user's first visit to their dashboard.
    *
-   * @param bool $flatFormat
-   *   This is true if you want simple associated.
-   *   array of all the contact's dashlets whether or not they are enabled.
-   *
    * @param int $contactID
-   *   Provide the dashlets for the contact id.
-   *   passed rather than the current user.
+   *   Defaults to the current user.
    *
    * @return array
    *   array of dashlets
    */
-  public static function getContactDashlets($flatFormat = FALSE, $contactID = NULL) {
+  public static function getContactDashlets($contactID = NULL) {
+    $contactID = $contactID ? $contactID : CRM_Core_Session::singleton()->getLoggedInContactID();
     $dashlets = array();
 
     // Get contact dashboard dashlets.
-    $hasDashlets = FALSE;
-    $dao = new CRM_Contact_DAO_DashboardContact();
-    $dao->contact_id = $contactID ? $contactID : CRM_Core_Session::singleton()->getLoggedInContactID();
-    $dao->orderBy('column_no asc, weight asc');
-    $dao->find();
-
-    // The available list will only include those which are valid for the domain.
-    $availableDashlets = self::getDashlets();
-    while ($dao->fetch()) {
-      // When a dashlet is removed, it stays in the table with status disabled,
-      // so even if a user decides not to have any dashlets show, they will still
-      // have records in the table to indicate that we are not newly initializing.
-      if ((!empty($availableDashlets[$dao->dashboard_id]) && $availableDashlets[$dao->dashboard_id]['is_active'])) {
-        $hasDashlets = TRUE;
-        if (!$flatFormat) {
-          if ($dao->is_active) {
-            // append weight so that order is preserved.
-            $dashlets[$dao->column_no]["{$dao->weight}-{$dao->dashboard_id}"] = $dao->is_minimized;
-          }
-        }
-        else {
-          $dashlets[$dao->dashboard_id] = $dao->dashboard_id;
-        }
+    $results = civicrm_api3('DashboardContact', 'get', array(
+      'contact_id' => $contactID,
+      'is_active' => 1,
+      'dashboard_id.is_active' => 1,
+      'options' => array('sort' => 'weight'),
+      'return' => array(
+        'id',
+        'weight',
+        'column_no',
+        'is_minimized',
+        'dashboard_id',
+        'dashboard_id.name',
+        'dashboard_id.label',
+        'dashboard_id.url',
+        'dashboard_id.fullscreen_url',
+        'dashboard_id.permission',
+        'dashboard_id.permission_operator',
+      ),
+    ));
+
+    foreach ($results['values'] as $item) {
+      if (self::checkPermission(CRM_Utils_Array::value('dashboard_id.permission', $item), CRM_Utils_Array::value('dashboard_id.permission_operator', $item))) {
+        $dashlets[$item['id']] = array(
+          'dashboard_id' => $item['dashboard_id'],
+          'weight' => $item['weight'],
+          'column_no' => $item['column_no'],
+          'is_minimized' => $item['is_minimized'],
+          'name' => $item['dashboard_id.name'],
+          'label' => $item['dashboard_id.label'],
+          'url' => $item['dashboard_id.url'],
+          'fullscreen_url' => $item['dashboard_id.fullscreen_url'],
+        );
       }
     }
 
-    if ($flatFormat) {
-      return $dashlets;
+    // If empty, then initialize default dashlets for this user.
+    if (!$results['count']) {
+      // They may just have disabled all their dashlets. Check if any records exist for this contact.
+      if (!civicrm_api3('DashboardContact', 'getcount', array('contact_id' => $contactID))) {
+        $dashlets = self::initializeDashlets();
+      }
     }
 
-    // If empty, then initialize contact dashboard for this user.
-    if (!$hasDashlets) {
-      return self::initializeDashlets($flatFormat);
-    }
     return $dashlets;
   }
 
+  public static function getContactDashletsForJS() {
+    $data = array(array(), array());
+    foreach (self::getContactDashlets() as $item) {
+      $data[$item['column_no']][] = array(
+        'id' => (int) $item['dashboard_id'],
+        'name' => $item['name'],
+        'title' => $item['label'],
+        'url' => self::parseUrl($item['url']),
+        'fullscreenUrl' => self::parseUrl($item['fullscreen_url']),
+      );
+    }
+    return $data;
+  }
+
   /**
    * Setup default dashlets for new users.
    *
    * When a user accesses their dashboard for the first time, set up
    * the default dashlets.
    *
-   * @param bool $flatFormat
-   *
    * @return array
    *    Array of dashboard_id's
    * @throws \CiviCRM_API3_Exception
    */
-  public static function initializeDashlets($flatFormat = FALSE) {
+  public static function initializeDashlets() {
     $dashlets = array();
     $getDashlets = civicrm_api3("Dashboard", "get", array(
         'domain_id' => CRM_Core_Config::domainID(),
@@ -168,7 +185,7 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
     $defaultDashlets = array();
     $defaults = array('blog' => 1, 'getting-started' => '0');
     foreach ($defaults as $name => $column) {
-      if (!empty($allDashlets[$name])) {
+      if (!empty($allDashlets[$name]) && !empty($allDashlets[$name]['id'])) {
         $defaultDashlets[$name] = array(
           'dashboard_id' => $allDashlets[$name]['id'],
           'is_active' => 1,
@@ -181,26 +198,40 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
     if (is_array($defaultDashlets) && !empty($defaultDashlets)) {
       foreach ($defaultDashlets as $id => $defaultDashlet) {
         $dashboard_id = $defaultDashlet['dashboard_id'];
-        if (!self::checkPermission($getDashlets['values'][$dashboard_id]['permission'],
-          CRM_Utils_Array::value('permission_operator', $getDashlets['values'][$dashboard_id]))
-        ) {
+        $dashlet = $getDashlets['values'][$dashboard_id];
+        if (!self::checkPermission(CRM_Utils_Array::value('permission', $dashlet), CRM_Utils_Array::value('permission_operator', $dashlet))) {
           continue;
         }
         else {
           $assignDashlets = civicrm_api3("dashboard_contact", "create", $defaultDashlet);
-          if (!$flatFormat) {
-            $values = $assignDashlets['values'][$assignDashlets['id']];
-            $dashlets[$values['column_no']][$values['weight'] - $values['dashboard_id']] = $values['is_minimized'];
-          }
-          else {
-            $dashlets[$dashboard_id] = $defaultDashlet['dashboard_id'];
-          }
+          $values = $assignDashlets['values'][$assignDashlets['id']];
+          $dashlets[$assignDashlets['id']] = array(
+            'dashboard_id' => $values['dashboard_id'],
+            'weight' => $values['weight'],
+            'column_no' => $values['column_no'],
+            'is_minimized' => $values['is_minimized'],
+            'name' => $dashlet['name'],
+            'label' => $dashlet['label'],
+            'url' => $dashlet['url'],
+            'fullscreen_url' => $dashlet['fullscreen_url'],
+          );
         }
       }
     }
     return $dashlets;
   }
 
+  /**
+   * @param $url
+   * @return string
+   */
+  public static function parseUrl($url) {
+    if (substr($url, 0, 4) != 'http') {
+      $urlParam = explode('?', $url);
+      $url = CRM_Utils_System::url($urlParam[0], $urlParam[1], FALSE, NULL, FALSE);
+    }
+    return $url;
+  }
 
   /**
    * Check dashlet permission for current user.
@@ -360,18 +391,14 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
    * @throws RuntimeException
    */
   public static function saveDashletChanges($columns, $contactID = NULL) {
-    $session = CRM_Core_Session::singleton();
     if (!$contactID) {
-      $contactID = $session->get('userID');
+      $contactID = CRM_Core_Session::getLoggedInContactID();
     }
 
     if (empty($contactID)) {
       throw new RuntimeException("Failed to determine contact ID");
     }
 
-    //we need to get existing dashlets, so we know when to update or insert
-    $contactDashlets = self::getContactDashlets(TRUE, $contactID);
-
     $dashletIDs = array();
     if (is_array($columns)) {
       foreach ($columns as $colNo => $dashlets) {
@@ -381,18 +408,13 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
         $weight = 1;
         foreach ($dashlets as $dashletID => $isMinimized) {
           $isMinimized = (int) $isMinimized;
-          if (in_array($dashletID, $contactDashlets)) {
-            $query = " UPDATE civicrm_dashboard_contact
-                                        SET weight = {$weight}, is_minimized = {$isMinimized}, column_no = {$colNo}, is_active = 1
-                                      WHERE dashboard_id = {$dashletID} AND contact_id = {$contactID} ";
-          }
-          else {
-            $query = " INSERT INTO civicrm_dashboard_contact
-                                        ( weight, is_minimized, column_no, is_active, dashboard_id, contact_id )
-                                     VALUES( {$weight},  {$isMinimized},  {$colNo}, 1, {$dashletID}, {$contactID} )";
-          }
+          $dashletID = (int) $dashletID;
+          $query = "INSERT INTO civicrm_dashboard_contact
+                    (weight, is_minimized, column_no, is_active, dashboard_id, contact_id)
+                    VALUES({$weight},  {$isMinimized},  {$colNo}, 1, {$dashletID}, {$contactID})
+                    ON DUPLICATE KEY UPDATE weight = {$weight}, is_minimized = {$isMinimized}, column_no = {$colNo}, is_active = 1";
           // fire update query for each column
-          $dao = CRM_Core_DAO::executeQuery($query);
+          CRM_Core_DAO::executeQuery($query);
 
           $dashletIDs[] = $dashletID;
           $weight++;
@@ -400,18 +422,11 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
       }
     }
 
-    if (!empty($dashletIDs)) {
-      // we need to disable widget that removed
-      $updateQuery = " UPDATE civicrm_dashboard_contact
-                               SET is_active = 0
-                               WHERE dashboard_id NOT IN  ( " . implode(',', $dashletIDs) . ") AND contact_id = {$contactID}";
-    }
-    else {
-      // this means all widgets are disabled
-      $updateQuery = " UPDATE civicrm_dashboard_contact
-                               SET is_active = 0
-                               WHERE contact_id = {$contactID}";
-    }
+    // Disable inactive widgets
+    $dashletClause = $dashletIDs ? "dashboard_id NOT IN  (" . implode(',', $dashletIDs) . ")" : '(1)';
+    $updateQuery = "UPDATE civicrm_dashboard_contact
+                    SET is_active = 0
+                    WHERE $dashletClause AND contact_id = {$contactID}";
 
     CRM_Core_DAO::executeQuery($updateQuery);
   }