From 58b68c8cb09dd359beaee4d6872e41303cf19a77 Mon Sep 17 00:00:00 2001 From: Sandor Semsey Date: Mon, 9 Oct 2023 21:15:14 +0200 Subject: [PATCH] CRM_Core_DAO::copyValues deduplicate pseudo-constant fields --- CRM/Contact/BAO/Contact.php | 1 - CRM/Core/DAO.php | 4 +++ tests/phpunit/CRM/Contact/BAO/ContactTest.php | 31 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index 5d948999fc..f05ed07931 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -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']); } } diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index 027ea8c5ab..554d89b11f 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -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; } diff --git a/tests/phpunit/CRM/Contact/BAO/ContactTest.php b/tests/phpunit/CRM/Contact/BAO/ContactTest.php index c238be6b9b..81406f95d9 100644 --- a/tests/phpunit/CRM/Contact/BAO/ContactTest.php +++ b/tests/phpunit/CRM/Contact/BAO/ContactTest.php @@ -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. * -- 2.25.1