From 0cfcd8282cc6b7aa99f3a17d5bdd71dd311cf8b7 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 2 Jun 2026 10:16:12 -0500 Subject: [PATCH] feat: cascade enable/disable across all MokoWaaS extensions When the core system plugin is disabled, all feature plugins (firewall, tenant, devtools, monitor) and the cpanel module are automatically disabled too. Re-enabling cascades the same way. Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Extension/MokoWaaS.php | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php b/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php index 1e28743f..3562d176 100644 --- a/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php +++ b/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php @@ -1463,6 +1463,96 @@ class MokoWaaS extends CMSPlugin implements BootableExtensionInterface return true; } + /** + * Cascade enable/disable state across all MokoWaaS extensions. + * + * When the core system plugin (plg_system_mokowaas) is disabled, + * all feature plugins and the cpanel module are also disabled. + * When re-enabled, they are re-enabled too. + * + * @param string $context The extension context + * @param array $pks Extension IDs being changed + * @param int $value New state (1=enabled, 0=disabled) + * + * @return void + * + * @since 02.32.00 + */ + public function onExtensionChangeState($context, $pks, $value) + { + if (empty($pks)) + { + return; + } + + try + { + $db = Factory::getDbo(); + + // Check if the core MokoWaaS plugin is among the changed extensions + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('element') . ' = ' . $db->quote('mokowaas')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('system')); + $db->setQuery($query); + $coreId = (int) $db->loadResult(); + + if (!$coreId || !\in_array($coreId, array_map('intval', $pks), true)) + { + return; + } + + // Cascade to all MokoWaaS feature plugins + module + $mokoElements = [ + $db->quote('mokowaas_firewall'), + $db->quote('mokowaas_tenant'), + $db->quote('mokowaas_devtools'), + $db->quote('mokowaas_monitor'), + $db->quote('mod_mokowaas_cpanel'), + ]; + + $query = $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->quoteName('enabled') . ' = ' . (int) $value) + ->where($db->quoteName('element') . ' IN (' . implode(',', $mokoElements) . ')'); + $db->setQuery($query); + $db->execute(); + $affected = $db->getAffectedRows(); + + // Also update module published state + if ($value == 0) + { + $db->setQuery( + $db->getQuery(true) + ->update($db->quoteName('#__modules')) + ->set($db->quoteName('published') . ' = 0') + ->where($db->quoteName('module') . ' = ' . $db->quote('mod_mokowaas_cpanel')) + )->execute(); + } + else + { + $db->setQuery( + $db->getQuery(true) + ->update($db->quoteName('#__modules')) + ->set($db->quoteName('published') . ' = 1') + ->where($db->quoteName('module') . ' = ' . $db->quote('mod_mokowaas_cpanel')) + )->execute(); + } + + $state = $value ? 'enabled' : 'disabled'; + $this->app->enqueueMessage( + "MokoWaaS: {$state} {$affected} associated extensions.", + 'message' + ); + } + catch (\Throwable $e) + { + Log::add('MokoWaaS cascade state error: ' . $e->getMessage(), Log::WARNING, 'mokowaas'); + } + } + /** * Filter admin menu items for non-master users. *