diff --git a/src/script.php b/src/script.php
index c6d0023..5fa417a 100644
--- a/src/script.php
+++ b/src/script.php
@@ -122,11 +122,14 @@ class Tpl_MokocassiopeiaInstallerScript implements InstallerScriptInterface
// 5. Redirect update server to MokoOnyx
$this->updateUpdateServer();
- // 6. Notify
+ // 6. Unlock MokoCassiopeia (allow uninstall) + lock MokoOnyx (prevent accidental uninstall)
+ $this->updateExtensionLocks();
+
+ // 7. Notify
$app->enqueueMessage(
'MokoOnyx has been installed as a replacement for MokoCassiopeia.
'
. 'Your template settings have been migrated. MokoOnyx is now your active site template.
'
- . 'You can safely uninstall MokoCassiopeia from Extensions → Manage.',
+ . 'MokoCassiopeia has been unlocked — you can uninstall it from Extensions → Manage.',
'success'
);
@@ -362,6 +365,42 @@ class Tpl_MokocassiopeiaInstallerScript implements InstallerScriptInterface
}
}
+ private function updateExtensionLocks(): void
+ {
+ $db = Factory::getDbo();
+
+ // Unlock MokoCassiopeia — allow uninstall
+ try {
+ $query = $db->getQuery(true)
+ ->update('#__extensions')
+ ->set($db->quoteName('locked') . ' = 0')
+ ->set($db->quoteName('protected') . ' = 0')
+ ->where($db->quoteName('element') . ' = ' . $db->quote(self::OLD_NAME))
+ ->where($db->quoteName('type') . ' = ' . $db->quote('template'));
+ $db->setQuery($query)->execute();
+ if ($db->getAffectedRows() > 0) {
+ $this->log('Bridge: unlocked MokoCassiopeia (can be uninstalled).');
+ }
+ } catch (\Throwable $e) {
+ $this->log('Bridge: failed to unlock MokoCassiopeia: ' . $e->getMessage(), 'warning');
+ }
+
+ // Lock MokoOnyx — prevent accidental uninstall
+ try {
+ $query = $db->getQuery(true)
+ ->update('#__extensions')
+ ->set($db->quoteName('locked') . ' = 1')
+ ->where($db->quoteName('element') . ' = ' . $db->quote(self::NEW_NAME))
+ ->where($db->quoteName('type') . ' = ' . $db->quote('template'));
+ $db->setQuery($query)->execute();
+ if ($db->getAffectedRows() > 0) {
+ $this->log('Bridge: locked MokoOnyx (protected from uninstall).');
+ }
+ } catch (\Throwable $e) {
+ $this->log('Bridge: failed to lock MokoOnyx: ' . $e->getMessage(), 'warning');
+ }
+ }
+
// ── Logging ────────────────────────────────────────────────────────
private function log(string $message, string $priority = 'info'): void