Update DAO to use declared primary field, do not assume...
authorEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 16 Aug 2022 07:34:26 +0000 (19:34 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 16 Aug 2022 08:19:53 +0000 (20:19 +1200)
CRM/Core/DAO.php

index be52f2b24a219d1ad6988e8b70496f383822262c..55b353c617569fb943b4623844f68e7249612649 100644 (file)
@@ -39,6 +39,13 @@ class CRM_Core_DAO extends DB_DataObject {
    */
   public static $_primaryKey = ['id'];
 
+  /**
+   * @return string[]
+   */
+  protected function getPrimaryKey(): array {
+    return static::$_primaryKey;
+  }
+
   /**
    * How many times has this instance been cloned.
    *
@@ -536,7 +543,7 @@ class CRM_Core_DAO extends DB_DataObject {
   public function sequenceKey() {
     static $sequenceKeys;
     if (!isset($sequenceKeys)) {
-      $sequenceKeys = ['id', TRUE];
+      $sequenceKeys = [$this->getPrimaryKey()[0], TRUE];
     }
     return $sequenceKeys;
   }
@@ -634,11 +641,15 @@ class CRM_Core_DAO extends DB_DataObject {
    */
   public function save($hook = TRUE) {
     $eventID = uniqid();
-    if (!empty($this->id)) {
+    // In practice the 'Import' entities are probably the only ones with a single
+    // primary key that is not import. Should we check all if more than one?
+    // Can do that when it comes up...
+    $primaryField = $this->getPrimaryKey()[0];
+    if (!empty($this->$primaryField)) {
       if ($hook) {
         $preEvent = new \Civi\Core\DAO\Event\PreUpdate($this);
         $preEvent->eventID = $eventID;
-        \Civi::dispatcher()->dispatch("civi.dao.preUpdate", $preEvent);
+        \Civi::dispatcher()->dispatch('civi.dao.preUpdate', $preEvent);
       }
 
       $result = $this->update();
@@ -646,7 +657,7 @@ class CRM_Core_DAO extends DB_DataObject {
       if ($hook) {
         $event = new \Civi\Core\DAO\Event\PostUpdate($this, $result);
         $event->eventID = $eventID;
-        \Civi::dispatcher()->dispatch("civi.dao.postUpdate", $event);
+        \Civi::dispatcher()->dispatch('civi.dao.postUpdate', $event);
       }
       $this->clearDbColumnValueCache();
     }