Skip to content
Snippets Groups Projects
Commit 6542d699 authored by totten's avatar totten
Browse files

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.
parent df7a1988
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
}
......
......@@ -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 {
......
......@@ -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,
......
......@@ -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,
......
{
"org.civicrm.api4": {
"obsolete": "5.19",
"disable": true,
"uninstall": true
"force-uninstall": true
},
"uk.squiffle.kam": {
"obsolete": "5.12",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment