From: Coleman Watts Date: Tue, 25 Jan 2022 16:54:40 +0000 (-0500) Subject: ExtensionUpgrades - Skip trying to upgrade missing dependencies X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=13182e01c95912ac6a872296287f2134d8a86e39;p=civicrm-core.git ExtensionUpgrades - Skip trying to upgrade missing dependencies Before: Missing dependencies would be added and then the extension upgrader would try and fail to upgrade them After: They are skipped, as missing extension dependencies are handled elsewhere This allows the extension upgrade to proceed without error, even if there are missing dependencies. The user will be prompted to install the missing dependencies afterward. --- diff --git a/CRM/Extension/Mapper.php b/CRM/Extension/Mapper.php index e056a7b24d..550091a84e 100644 --- a/CRM/Extension/Mapper.php +++ b/CRM/Extension/Mapper.php @@ -441,7 +441,7 @@ class CRM_Extension_Mapper { } /** - * @return array + * @return CRM_Extension_Info[] * Ex: $result['org.civicrm.foobar'] = new CRM_Extension_Info(...). * @throws \CRM_Extension_Exception * @throws \Exception diff --git a/CRM/Extension/Upgrades.php b/CRM/Extension/Upgrades.php index adf3b1f494..6d5991fa55 100644 --- a/CRM/Extension/Upgrades.php +++ b/CRM/Extension/Upgrades.php @@ -127,7 +127,10 @@ class CRM_Extension_Upgrades { } /** + * Sorts active extensions according to their dependencies + * * @param string[] $keys + * Names of all active modules * * @return string[] * @throws \CRM_Extension_Exception @@ -137,30 +140,25 @@ class CRM_Extension_Upgrades { protected static function sortKeys($keys) { $infos = CRM_Extension_System::singleton()->getMapper()->getAllInfos(); - // Start with our inputs in a normalized form. + // Ensure a stable starting order. $todoKeys = array_unique($keys); sort($todoKeys); - // Goal: Add all active items to $sorter and flag $doneKeys['org.example.foobar']=1. - $doneKeys = []; $sorter = new \MJS\TopSort\Implementations\FixedArraySort(); - while (!empty($todoKeys)) { - $key = array_shift($todoKeys); - if (isset($doneKeys[$key])) { - continue; - } - $doneKeys[$key] = 1; - + foreach ($todoKeys as $key) { /** @var CRM_Extension_Info $info */ - $info = @$infos[$key]; + $info = $infos[$key] ?? NULL; - if ($info && $info->requires) { - $sorter->add($key, $info->requires); - $todoKeys = array_merge($todoKeys, $info->requires); + // Add dependencies + if ($info) { + // Filter out missing dependencies; missing modules cannot be upgraded + $requires = array_intersect($info->requires ?? [], $keys); + $sorter->add($key, $requires); } + // This shouldn't ever happen if this function is being passed a list of active extensions. else { - $sorter->add($key, []); + throw new CRM_Extension_Exception('Invalid extension key: "' . $key . '"'); } } return $sorter->sort();