From 6542d699505a306cfd0a0100298133b2440da302 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 2 Oct 2019 17:15:24 +0100 Subject: [PATCH] extension-compatibility - Add 'force-uninstall' mode for api4 transition There is a compatibility problem when upgrading a system which has an old copy of api4: the top level `api4.php` indiscriminately declares the function `civicrm_api4()`, which eventually provokes a conflict with the copy that is now in `civicrm-core`. Using the normal disable/uninstall actions doesn't resolve this because the error arises too early during boot (before the upgrader gets a chance to remove the extension). The 'force-uninstall' option will make the system behave as if the extension is uninstalled, regardless of what files exist and what state may be stored in the `civicrm_extension` table. This commit technically does ~3 things: 1. Changes the policy for `org.civicrm.api4` to use `force-uninstall` 2. Makes the extension-cache version-dependent. During an upgrade, you might have a stale cache that claims that the old extension is active. This ensures that (as soon as you drop in new code) it begins working with a fresh cache. 3. Update any spots which query the table `civicrm_extensions` for extension status. Have it consult `extension-compatibility.json` for `force-uninstall`ed items. --- CRM/Core/PseudoConstant.php | 4 ++++ CRM/Extension/Manager.php | 7 ++++++- CRM/Extension/Mapper.php | 5 +++++ CRM/Extension/System.php | 2 +- extension-compatibility.json | 3 +-- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CRM/Core/PseudoConstant.php b/CRM/Core/PseudoConstant.php index 14e2e7fcf2..cb5f8d1759 100644 --- a/CRM/Core/PseudoConstant.php +++ b/CRM/Core/PseudoConstant.php @@ -1454,6 +1454,7 @@ WHERE id = %1 */ public static function &getExtensions() { if (!self::$extensions) { + $compat = CRM_Extension_System::getCompatibilityInfo(); self::$extensions = []; $sql = ' SELECT full_name, label @@ -1462,6 +1463,9 @@ WHERE id = %1 '; $dao = CRM_Core_DAO::executeQuery($sql); while ($dao->fetch()) { + if (!empty($compat[$dao->full_name]['force-uninstall'])) { + continue; + } self::$extensions[$dao->full_name] = $dao->label; } } diff --git a/CRM/Extension/Manager.php b/CRM/Extension/Manager.php index 152f54df21..234b3d8fc0 100644 --- a/CRM/Extension/Manager.php +++ b/CRM/Extension/Manager.php @@ -465,6 +465,8 @@ class CRM_Extension_Manager { */ public function getStatuses() { if (!is_array($this->statuses)) { + $compat = CRM_Extension_System::getCompatibilityInfo(); + $this->statuses = []; foreach ($this->fullContainer->getKeys() as $key) { @@ -484,7 +486,10 @@ class CRM_Extension_Manager { catch (CRM_Extension_Exception $e) { $codeExists = FALSE; } - if ($dao->is_active) { + if (!empty($compat[$dao->full_name]['force-uninstall'])) { + $this->statuses[$dao->full_name] = self::STATUS_UNINSTALLED; + } + elseif ($dao->is_active) { $this->statuses[$dao->full_name] = $codeExists ? self::STATUS_INSTALLED : self::STATUS_INSTALLED_MISSING; } else { diff --git a/CRM/Extension/Mapper.php b/CRM/Extension/Mapper.php index b9cc7ed182..fd828e4fe7 100644 --- a/CRM/Extension/Mapper.php +++ b/CRM/Extension/Mapper.php @@ -286,6 +286,8 @@ class CRM_Extension_Mapper { } if (!is_array($moduleExtensions)) { + $compat = CRM_Extension_System::getCompatibilityInfo(); + // Check canonical module list $moduleExtensions = []; $sql = ' @@ -296,6 +298,9 @@ class CRM_Extension_Mapper { '; $dao = CRM_Core_DAO::executeQuery($sql); while ($dao->fetch()) { + if (!empty($compat[$dao->full_name]['force-uninstall'])) { + continue; + } try { $moduleExtensions[] = [ 'prefix' => $dao->file, diff --git a/CRM/Extension/System.php b/CRM/Extension/System.php index 305f08f19b..a45cbfbadf 100644 --- a/CRM/Extension/System.php +++ b/CRM/Extension/System.php @@ -264,7 +264,7 @@ class CRM_Extension_System { */ public function getCache() { if ($this->cache === NULL) { - $cacheGroup = md5(serialize(['ext', $this->parameters])); + $cacheGroup = md5(serialize(['ext', $this->parameters, CRM_Utils_System::version()])); // Extension system starts before container. Manage our own cache. $this->cache = CRM_Utils_Cache::create([ 'name' => $cacheGroup, diff --git a/extension-compatibility.json b/extension-compatibility.json index 6b7c9c814e..60be476584 100644 --- a/extension-compatibility.json +++ b/extension-compatibility.json @@ -1,8 +1,7 @@ { "org.civicrm.api4": { "obsolete": "5.19", - "disable": true, - "uninstall": true + "force-uninstall": true }, "uk.squiffle.kam": { "obsolete": "5.12", -- 2.25.1