diff --git a/CRM/Upgrade/Incremental/php/FiveTwentyOne.php b/CRM/Upgrade/Incremental/php/FiveTwentyOne.php
index 6cbffc39d9a4..499aa9a68f5e 100644
--- a/CRM/Upgrade/Incremental/php/FiveTwentyOne.php
+++ b/CRM/Upgrade/Incremental/php/FiveTwentyOne.php
@@ -40,10 +40,20 @@ public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NU
* an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
*/
public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
- // Example: Generate a post-upgrade message.
- // if ($rev == '5.12.34') {
- // $postUpgradeMessage .= '
' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'.");
- // }
+ if ($rev == '5.21.alpha1') {
+ // Find any option groups that were not converted during the upgrade.
+ $notConverted = [];
+ $optionGroups = \Civi\Api4\OptionGroup::get()->setCheckPermissions(FALSE)->execute();
+ foreach ($optionGroups as $optionGroup) {
+ $trimmedName = trim($optionGroup['name']);
+ if (strpos($trimmedName, ' ') !== FALSE) {
+ $notConverted[] = $optionGroup['title'];
+ }
+ }
+ if (count($notConverted)) {
+ $postUpgradeMessage .= '
' . ts("The Following option Groups have not been converted due to there being already another option group with the same name in the database") . "
- " . implode('
- ', $notConverted) . "
";
+ }
+ }
}
/*
@@ -83,12 +93,19 @@ public static function fixOptionGroupName() {
$name = trim($optionGroup['name']);
if (strpos($name, ' ') !== FALSE) {
$fixedName = CRM_Utils_String::titleToVar(strtolower($name));
- \Civi::log()->debug('5.21 Upgrade Option Group name ' . $name . ' converted to ' . $fixedName);
- \Civi\Api4\OptionGroup::update()
- ->addWhere('id', '=', $optionGroup['id'])
- ->addValue('name', $fixedName)
+ $check = \Civi\Api4\OptionGroup::get()
+ ->addWhere('name', '=', $fixedName)
->setCheckPermissions(FALSE)
->execute();
+ // Fix hard fail in upgrade due to name already in database dev/core#1447
+ if (!count($check)) {
+ \Civi::log()->debug('5.21 Upgrade Option Group name ' . $name . ' converted to ' . $fixedName);
+ \Civi\Api4\OptionGroup::update()
+ ->addWhere('id', '=', $optionGroup['id'])
+ ->addValue('name', $fixedName)
+ ->setCheckPermissions(FALSE)
+ ->execute();
+ }
}
}
return TRUE;
diff --git a/tests/phpunit/CRM/Upgrade/Incremental/BaseTest.php b/tests/phpunit/CRM/Upgrade/Incremental/BaseTest.php
index 9510e4f77d8c..238816045d21 100644
--- a/tests/phpunit/CRM/Upgrade/Incremental/BaseTest.php
+++ b/tests/phpunit/CRM/Upgrade/Incremental/BaseTest.php
@@ -488,6 +488,35 @@ public function testFixOptionGroupName() {
$postUpgrade = $this->callAPISuccess('OptionGroup', 'getsingle', ['id' => $optionGroup['id']]);
$this->assertEquals($fixedName, $postUpgrade['name'], 'Ensure that the spaces have been removed from OptionGroup name');
$this->assertEquals($postUpgrade['name'], $optionGroup['values'][$optionGroup['id']]['name'], 'Ensure that the fixed name matches what the API would produce');
+ $this->callAPISuccess('OptionGroup', 'delete', ['id' => $optionGroup['id']]);
+ }
+
+ /**
+ * Test that if there is an option group name as the same as the proposed fix name that doesn't cause a hard fail in the upgrade
+ */
+ public function testFixOptionGroupNameWithFixedNameInDatabase() {
+ $name = 'This is a test Name';
+ $fixedName = CRM_Utils_String::titleToVar(strtolower($name));
+ $optionGroup = $this->callAPISuccess('OptionGroup', 'create', [
+ 'title' => 'Test Option Group',
+ 'name' => $name,
+ ]);
+ // API is hardened to strip the spaces to lets re-add in now
+ CRM_Core_DAO::executeQuery("UPDATE civicrm_option_group SET name = %1 WHERE id = %2", [
+ 1 => [$name, 'String'],
+ 2 => [$optionGroup['id'], 'Positive'],
+ ]);
+ $optionGroup2 = $this->callAPISuccess('OptionGroup', 'create', [
+ 'title' => 'Test Option Group 2',
+ 'name' => $name,
+ ]);
+ $preUpgrade = $this->callAPISuccess('OptionGroup', 'getsingle', ['id' => $optionGroup['id']]);
+ $this->assertEquals($name, $preUpgrade['name']);
+ $preUpgrade = $this->callAPISuccess('OptionGroup', 'getsingle', ['id' => $optionGroup2['id']]);
+ $this->assertEquals($fixedName, $preUpgrade['name']);
+ CRM_Upgrade_Incremental_php_FiveTwentyOne::fixOptionGroupName();
+ $this->callAPISuccess('OptionGroup', 'delete', ['id' => $optionGroup['id']]);
+ $this->callAPISuccess('OptionGroup', 'delete', ['id' => $optionGroup2['id']]);
}
}