FiveSixtyTwo - Refine upgrade steps for consolidating the "enable_components"
authorTim Otten <totten@civicrm.org>
Thu, 13 Apr 2023 20:11:30 +0000 (13:11 -0700)
committerTim Otten <totten@civicrm.org>
Thu, 13 Apr 2023 20:35:08 +0000 (13:35 -0700)
* Warn user if the upgrade is going to change behavior
* Don't assume that the web-user/CLI-user's domain has an explicit value for "enable_components"
* Don't assume that the web-user/CLI-user's domain is representative of all domains

CRM/Upgrade/Incremental/php/FiveSixtyTwo.php
CRM/Upgrade/Incremental/sql/5.62.alpha1.mysql.tpl

index d4f72372b246876ca14f2fb0d6fbfca25caa0a00..440e3901adb1633ffcd327ae06077b815d42da52 100644 (file)
  */
 class CRM_Upgrade_Incremental_php_FiveSixtyTwo extends CRM_Upgrade_Incremental_Base {
 
+  public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
+    if ($rev == '5.62.alpha1') {
+      $distinctComponentLists = CRM_Core_DAO::executeQuery('SELECT value, count(*) c FROM civicrm_setting WHERE name = "enable_components" GROUP BY value')
+        ->fetchMap('value', 'c');
+      if (count($distinctComponentLists) > 1) {
+        $message = ts('This site has multiple "Domains". The list of active "Components" is being consolidated across all "Domains". If you need different behavior in each "Domain", then consider updating the roles or permissions.');
+        // If you're investigating this - then maybe you should implement hook_permission_check() to dynamically adjust feature visibility?
+        // See also: https://lab.civicrm.org/dev/core/-/issues/3961
+        $preUpgradeMessage .= "<p>{$message}</p>";
+      }
+    }
+  }
+
   /**
    * Upgrade step; adds tasks including 'runSql'.
    *
@@ -29,7 +42,43 @@ class CRM_Upgrade_Incremental_php_FiveSixtyTwo extends CRM_Upgrade_Incremental_B
    */
   public function upgrade_5_62_alpha1($rev): void {
     $this->addTask('Make civicrm_setting.domain_id optional', 'alterColumn', 'civicrm_setting', 'domain_id', "int unsigned DEFAULT NULL COMMENT 'Which Domain does this setting belong to'");
+    $this->addTask('Consolidate the list of components', 'consolidateComponents');
     $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
   }
 
+  public static function consolidateComponents($ctx): bool {
+    $final = static::findAllEnabledComponents();
+    $lowestDomainId = CRM_Core_DAO::singleValueQuery('SELECT min(domain_id) FROM civicrm_setting WHERE name = "enable_components"');
+    if (!is_numeric($lowestDomainId)) {
+      return TRUE;
+    }
+
+    CRM_Core_DAO::executeQuery('UPDATE civicrm_setting SET domain_id = NULL, value = %3 WHERE domain_id = %1 AND name = %2', [
+      1 => [$lowestDomainId, 'Positive'],
+      2 => ['enable_components', 'String'],
+      3 => [serialize($final), 'String'],
+    ]);
+
+    CRM_Core_DAO::executeQuery('DELETE FROM civicrm_setting WHERE domain_id > %1 AND name = %2', [
+      1 => [$lowestDomainId, 'Positive'],
+      2 => ['enable_components', 'String'],
+    ]);
+
+    return TRUE;
+  }
+
+  /**
+   * @return array
+   *   Ex: ['CiviEvent', 'CiviMail']
+   */
+  public static function findAllEnabledComponents(): array {
+    $raw = CRM_Core_DAO::executeQuery('SELECT domain_id, value FROM civicrm_setting WHERE name = "enable_components"')
+      ->fetchMap('domain_id', 'value');
+    $all = [];
+    foreach ($raw as $value) {
+      $all = array_unique(array_merge($all, \CRM_Utils_String::unserialize($value)));
+    }
+    return array_values($all);
+  }
+
 }
index 39fa40600c2a3dc724420c90a7e61aa6e5fc109e..c07509a60c16a48a88a0b455097b4d408f205640 100644 (file)
@@ -1,4 +1 @@
 {* file to handle db changes in 5.62.alpha1 during upgrade *}
-
-UPDATE `civicrm_setting` SET `domain_id` = NULL WHERE `name` = 'enable_components' AND `domain_id` = {$domainID};
-DELETE FROM `civicrm_setting` WHERE `name` = 'enable_components' AND `domain_id` IS NOT NULL;