CRM-17663 - Add unique index to civicrm_dashboard_contact
authorColeman Watts <coleman@civicrm.org>
Thu, 4 Aug 2016 19:03:55 +0000 (15:03 -0400)
committerColeman Watts <coleman@civicrm.org>
Fri, 12 Aug 2016 03:32:35 +0000 (23:32 -0400)
CRM/Core/BAO/Dashboard.php
CRM/Upgrade/Incremental/php/FourSeven.php
xml/schema/Contact/DashboardContact.xml

index 3d74b07cfbc45e52c6d7985799892ad8f22065de..1bb316b3bfd5a9ed31a3bcb1f2fed77fea752d20 100644 (file)
@@ -368,9 +368,6 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard {
       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) {
@@ -380,18 +377,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++;
@@ -399,18 +391,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);
   }
index 74a875f15136aa97331708c502a35fb48c260f98..9030a6afee27432af0a653008018936e661f9c36 100644 (file)
@@ -221,6 +221,16 @@ class CRM_Upgrade_Incremental_php_FourSeven extends CRM_Upgrade_Incremental_Base
     $this->addTask(ts('Alter index and type for image URL'), 'alterIndexAndTypeForImageURL');
   }
 
+  /**
+   * Upgrade function.
+   *
+   * @param string $rev
+   */
+  public function upgrade_4_7_11($rev) {
+    $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
+    $this->addTask('Dashboard schema updates', 'dashboardSchemaUpdate');
+  }
+
   /*
    * Important! All upgrade functions MUST call the 'runSql' task.
    * Uncomment and use the following template for a new upgrade version
@@ -727,6 +737,21 @@ FROM `civicrm_dashboard_contact` JOIN `civicrm_contact` WHERE civicrm_dashboard_
     return TRUE;
   }
 
+  /**
+   * CRM-17663 - Dashboard schema changes
+   *
+   * @param \CRM_Queue_TaskContext $ctx
+   *
+   * @return bool
+   */
+  public function dashboardSchemaUpdate(CRM_Queue_TaskContext $ctx) {
+    if (!CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_dashboard_contact', 'index_dashboard_id_contact_id')) {
+      // Delete any stray duplicate rows and add unique index to prevent new dupes and enable INSERT/UPDATE combo query
+      CRM_Core_DAO::executeQuery('DELETE c1 FROM civicrm_dashboard_contact c1, civicrm_dashboard_contact c2 WHERE c1.contact_id = c2.contact_id AND c1.dashboard_id = c2.dashboard_id AND c1.id > c2.id');
+      CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dashboard_contact ADD UNIQUE INDEX index_dashboard_id_contact_id (dashboard_id, contact_id);');
+    }
+  }
+
   /**
    * CRM-19100 - Alter Index and Type for Image URL
    * @return bool
index 95d990523a958ee1f4dbb0c1e44a9b121af10ba7..8a5fc6791be1164c544a5392dcd10724583c7edb 100644 (file)
     <onDelete>CASCADE</onDelete>
     <add>3.1</add>
   </foreignKey>
+  <index>
+    <name>index_dashboard_id_contact_id</name>
+    <fieldName>dashboard_id</fieldName>
+    <fieldName>contact_id</fieldName>
+    <unique>true</unique>
+    <add>4.7</add>
+  </index>
   <field>
     <name>column_no</name>
     <type>boolean</type>