From 79b6ac2bbbf317abdf6827eb9ecc672b7cf856d4 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Tue, 1 Feb 2022 15:03:37 -0500 Subject: [PATCH] CustomGroup - Ensure 'name' is always unique Previously, unique 'name' was only enforced in tandem with 'extends' Now it is required to be unique unconditionally. --- CRM/Core/DAO/CustomGroup.php | 9 ++++----- CRM/Upgrade/Incremental/php/FiveFortySeven.php | 9 +++++++++ CRM/Upgrade/Incremental/sql/5.47.alpha1.mysql.tpl | 3 +++ tests/phpunit/api/v3/ContributionTest.php | 4 ++-- xml/schema/Core/CustomGroup.xml | 5 ++--- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/CRM/Core/DAO/CustomGroup.php b/CRM/Core/DAO/CustomGroup.php index 6bb2ce18e0df..41f78998d694 100644 --- a/CRM/Core/DAO/CustomGroup.php +++ b/CRM/Core/DAO/CustomGroup.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Core/CustomGroup.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:0c41f19103b41d2f82bcd3b60aaf2165) + * (GenCodeChecksum:979bca796163b9af253a7860d9d4a01d) */ /** @@ -698,15 +698,14 @@ public static function indices($localize = TRUE) { 'unique' => TRUE, 'sig' => 'civicrm_custom_group::1::title::extends', ], - 'UI_name_extends' => [ - 'name' => 'UI_name_extends', + 'UI_name' => [ + 'name' => 'UI_name', 'field' => [ 0 => 'name', - 1 => 'extends', ], 'localizable' => FALSE, 'unique' => TRUE, - 'sig' => 'civicrm_custom_group::1::name::extends', + 'sig' => 'civicrm_custom_group::1::name', ], ]; return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices; diff --git a/CRM/Upgrade/Incremental/php/FiveFortySeven.php b/CRM/Upgrade/Incremental/php/FiveFortySeven.php index 398e91d87e23..1f5fe04ea315 100644 --- a/CRM/Upgrade/Incremental/php/FiveFortySeven.php +++ b/CRM/Upgrade/Incremental/php/FiveFortySeven.php @@ -39,6 +39,13 @@ public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NU $preUpgradeMessage .= '

' . ts('The contact field preferred mail format is being phased out. Modern email clients can handle receiving both formats so CiviCRM is moving towards always sending both and the field will be incrementally removed from the UI.') . ' ' . ts('See the issue for more detail') . '

'; } + // Check for custom groups with duplicate names + $dupes = CRM_Core_DAO::singleValueQuery('SELECT COUNT(g1.id) FROM civicrm_custom_group g1, civicrm_custom_group g2 WHERE g1.name = g2.name AND g1.id > g2.id'); + if ($dupes) { + $preUpgradeMessage .= '

' . + ts('Your system has custom field groups with duplicate internal names. To ensure data integrity, the internal names will be automatically changed; user-facing titles will not be affected. Please review any custom code you may be using which relies on custom field group names.') . + '

'; + } } } @@ -63,6 +70,8 @@ public function upgrade_5_47_alpha1($rev): void { 'civicrm_event', 'event_tz', "text NULL DEFAULT NULL COMMENT 'Event\'s native time zone'" ); $this->addTask('core-issue#2122 - Set the timezone to the default for existing Events', 'setEventTZDefault'); + $this->addTask('Drop CustomGroup UI_name_extends index', 'dropIndex', 'civicrm_custom_group', 'UI_name_extends'); + $this->addTask('Add CustomGroup UI_name index', 'addIndex', 'civicrm_custom_group', ['name'], 'UI'); } /** diff --git a/CRM/Upgrade/Incremental/sql/5.47.alpha1.mysql.tpl b/CRM/Upgrade/Incremental/sql/5.47.alpha1.mysql.tpl index f5d36fc1b6cb..3943ae430873 100644 --- a/CRM/Upgrade/Incremental/sql/5.47.alpha1.mysql.tpl +++ b/CRM/Upgrade/Incremental/sql/5.47.alpha1.mysql.tpl @@ -26,3 +26,6 @@ ALTER TABLE `civicrm_event` MODIFY COLUMN `end_date` timestamp NULL DEFAULT NULL COMMENT 'Date and time that event ends. May be NULL if no defined end date/time', MODIFY COLUMN `registration_start_date` timestamp NULL DEFAULT NULL COMMENT 'Date and time that online registration starts.', MODIFY COLUMN `registration_end_date` timestamp NULL DEFAULT NULL COMMENT 'Date and time that online registration ends.'; + +{* Ensure CustomGroup.name is unique *} +UPDATE civicrm_custom_group g1, civicrm_custom_group g2 SET g1.name = CONCAT(g1.name, '_1') WHERE g1.name = g2.name AND g1.id > g2.id; diff --git a/tests/phpunit/api/v3/ContributionTest.php b/tests/phpunit/api/v3/ContributionTest.php index 720e48f52ec6..92955eb68737 100644 --- a/tests/phpunit/api/v3/ContributionTest.php +++ b/tests/phpunit/api/v3/ContributionTest.php @@ -506,8 +506,8 @@ public function testCreateWithCustom(): void { * @throws \CRM_Core_Exception */ public function testCreateGetFieldsWithCustom(): void { - $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__); - $idsContact = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ContactTest.php'); + $ids = $this->entityCustomGroupWithSingleFieldCreate('ContributionCustomFields', __FILE__); + $idsContact = $this->entityCustomGroupWithSingleFieldCreate('ContactCustomFields', 'ContactTest.php'); $result = $this->callAPISuccess('Contribution', 'getfields', []); $this->assertArrayHasKey('custom_' . $ids['custom_field_id'], $result['values']); $this->assertArrayNotHasKey('custom_' . $idsContact['custom_field_id'], $result['values']); diff --git a/xml/schema/Core/CustomGroup.xml b/xml/schema/Core/CustomGroup.xml index 3fd5522cdf1c..cd38ce067011 100644 --- a/xml/schema/Core/CustomGroup.xml +++ b/xml/schema/Core/CustomGroup.xml @@ -198,11 +198,10 @@ 2.1 - UI_name_extends + UI_name name - extends true - 2.1 + 5.47 created_id