CRM_Core_DAO::copyValues deduplicate pseudo-constant fields
authorSandor Semsey <sandor@es-progress.hu>
Mon, 9 Oct 2023 19:15:14 +0000 (21:15 +0200)
committerSandor Semsey <sandor@es-progress.hu>
Thu, 19 Oct 2023 07:19:20 +0000 (09:19 +0200)
CRM/Contact/BAO/Contact.php
CRM/Core/DAO.php
tests/phpunit/CRM/Contact/BAO/ContactTest.php

index 5d948999fc31a9a6453e3e341e32585818b572e7..f05ed0793163ddbdce376ad8a016faf6dbf9dbaa 100644 (file)
@@ -119,7 +119,6 @@ class CRM_Contact_BAO_Contact extends CRM_Contact_DAO_Contact implements Civi\Co
           // CRM-7925
           throw new CRM_Core_Exception(ts('The Contact Sub Type does not match the Contact type for this record'));
         }
-        $params['contact_sub_type'] = CRM_Utils_Array::implodePadded($params['contact_sub_type']);
       }
     }
 
index 027ea8c5abc7d13ae741f3088cd0dfaa23b72cc7..554d89b11f7ece9875650097e45863f75fa2403e 100644 (file)
@@ -780,6 +780,10 @@ class CRM_Core_DAO extends DB_DataObject {
           }
         }
         elseif (is_array($value) && !empty($field['serialize'])) {
+          if (!empty($field['pseudoconstant'])) {
+            // Pseudoconstant implies 1-1 option matching; duplicates would not make sense
+            $value = array_unique($value);
+          }
           $this->$dbName = CRM_Core_DAO::serializeField($value, $field['serialize']);
           $allNull = FALSE;
         }
index c238be6b9b9411ba924d72175aec5faf68b98099..81406f95d9ab00287f53b58158922f97f440fa38 100644 (file)
@@ -230,6 +230,37 @@ class CRM_Contact_BAO_ContactTest extends CiviUnitTestCase {
     $this->contactDelete($contactId);
   }
 
+  /**
+   * Test case for add( ) with duplicated sub contact types.
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testAddWithDuplicatedSubContactType(): void {
+    // Sub contact-type as array
+    $sub_contact_type = ['Staff', 'Parent', 'Staff'];
+    $params = [
+      'first_name' => 'Duplicated sub contact-type as array',
+      'contact_type' => 'Individual',
+      'contact_sub_type' => $sub_contact_type,
+    ];
+    $contact = CRM_Contact_BAO_Contact::add($params);
+    $this->assertSame(
+      CRM_Core_DAO::serializeField((array_unique($sub_contact_type)), $contact->fields()['contact_sub_type']['serialize']),
+      $contact->contact_sub_type,
+      'Contact sub-type not deduplicated.'
+    );
+
+    // Sub contact-type as string
+    $sub_contact_type = 'Staff';
+    $params = [
+      'first_name' => 'Sub contact-type as string',
+      'contact_type' => 'Individual',
+      'contact_sub_type' => $sub_contact_type,
+    ];
+    $contact = CRM_Contact_BAO_Contact::add($params);
+    $this->assertSame($sub_contact_type, $contact->contact_sub_type, 'Wrong contact sub-type saved.');
+  }
+
   /**
    * Test case for create.
    *