diff --git a/CRM/Core/Component.php b/CRM/Core/Component.php index a837ca92ab83..f9f91e8a086c 100644 --- a/CRM/Core/Component.php +++ b/CRM/Core/Component.php @@ -416,7 +416,44 @@ public static function isEnabled(string $component): bool { } /** - * Callback for the "enable_components" setting + * Callback for the "enable_components" setting (pre change) + * + * Before a component is disabled, disable reverse-dependencies (all extensions dependent on it). + * + * This is imperfect because it only goes one-level deep: + * it doesn't deal with any extensions that depend on the ones being disabled. + * The proper fix for that would probably be something like a CASCADE mode for + * disabling an extension with all its reverse dependencies (which would render this function moot). + * + * @param array $oldValue + * List of component names. + * @param array $newValue + * List of component names. + * + * @throws \CRM_Core_Exception. + */ + public static function preToggleComponents($oldValue, $newValue): void { + if (is_array($oldValue) && is_array($newValue)) { + $disabledComponents = array_diff($oldValue, $newValue); + } + if (empty($disabledComponents)) { + return; + } + $disabledExtensions = array_map(['CRM_Utils_String', 'convertStringToSnakeCase'], $disabledComponents); + $manager = CRM_Extension_System::singleton()->getManager(); + $extensions = $manager->getStatuses(); + foreach ($extensions as $extension => $status) { + if ($status === CRM_Extension_Manager::STATUS_INSTALLED) { + $info = $manager->mapper->keyToInfo($extension); + if (array_intersect($info->requires, $disabledExtensions)) { + $manager->disable($extension); + } + } + } + } + + /** + * Callback for the "enable_components" setting (post change) * * When a component is enabled or disabled, ensure the corresponding module-extension is also enabled/disabled. * @@ -427,7 +464,7 @@ public static function isEnabled(string $component): bool { * * @throws \CRM_Core_Exception. */ - public static function onToggleComponents($oldValue, $newValue): void { + public static function postToggleComponents($oldValue, $newValue): void { if (CRM_Core_Config::isUpgradeMode()) { return; } diff --git a/CRM/Extension/Upgrader/Component.php b/CRM/Extension/Upgrader/Component.php index d4e3b07e3e63..b445c964a3ad 100644 --- a/CRM/Extension/Upgrader/Component.php +++ b/CRM/Extension/Upgrader/Component.php @@ -1,5 +1,4 @@ setting-php@1.0.0 + + civi_contribute + CRM/Financialacls 23.02.1 diff --git a/settings/Core.setting.php b/settings/Core.setting.php index 9106338b1eb9..2864da74d7ba 100644 --- a/settings/Core.setting.php +++ b/settings/Core.setting.php @@ -800,9 +800,10 @@ 'help_text' => NULL, 'on_change' => [ 'CRM_Case_Info::onToggleComponents', + 'CRM_Core_Component::preToggleComponents', ], 'post_change' => [ - 'CRM_Core_Component::onToggleComponents', + 'CRM_Core_Component::postToggleComponents', ], 'pseudoconstant' => [ 'callback' => 'CRM_Core_SelectValues::getComponentSelectValues',