feat: always install MokoOnyx and unlock MokoCassiopeia on update
Repo Health / Access control (push) Failing after 2s
Repo Health / Release configuration (push) Has been skipped
Repo Health / Scripts governance (push) Has been skipped
Repo Health / Repository health (push) Has been skipped

- Rewrite ensureMokoCassiopeia() to always install+lock MokoOnyx
  and always unlock MokoCassiopeia (allow uninstall)
- Bundle MokoOnyx 01.00.17 stable payload (replaces MokoCassiopeia)
- Update payload workflow to fetch MokoOnyx from Gitea releases
- Bump version to 02.01.18

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan Miller
2026-04-23 11:14:16 -05:00
parent 2eea9a4f3c
commit fccaf67024
5 changed files with 55 additions and 81 deletions
+38 -61
View File
@@ -210,11 +210,11 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
}
/**
* Ensure the active Moko template is installed and locked.
* Ensure MokoOnyx is installed, locked, and set as default.
*
* Prefers MokoOnyx (successor). Falls back to MokoCassiopeia.
* If MokoOnyx is found, lock it and unlock MokoCassiopeia.
* If only MokoCassiopeia is found, lock it as before.
* Always installs MokoOnyx from bundled payload if not present,
* locks it, sets it as default site template, and unlocks
* MokoCassiopeia so it can be uninstalled.
*
* @return void
*
@@ -224,14 +224,23 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
{
$db = Factory::getDbo();
// Check for MokoOnyx first (successor template)
// Check whether MokoOnyx is already installed
$query = $db->getQuery(true)
->select([$db->quoteName('extension_id'), $db->quoteName('enabled')])
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('element') . ' = ' . $db->quote('mokoonyx'))
->where($db->quoteName('type') . ' = ' . $db->quote('template'));
$onyx = $db->setQuery($query)->loadObject();
// Install from payload if missing
if (!$onyx)
{
$this->installMokoOnyxFromPayload();
// Re-check after install
$onyx = $db->setQuery($query)->loadObject();
}
if ($onyx)
{
// Lock and protect MokoOnyx
@@ -245,56 +254,31 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
)->execute();
$this->setDefaultTemplate('mokoonyx', 0);
// Unlock MokoCassiopeia if present (allow uninstall)
$db->setQuery(
$db->getQuery(true)
->update($db->quoteName('#__extensions'))
->set($db->quoteName('locked') . ' = 0')
->set($db->quoteName('protected') . ' = 0')
->where($db->quoteName('element') . ' = ' . $db->quote('mokocassiopeia'))
->where($db->quoteName('type') . ' = ' . $db->quote('template'))
)->execute();
return;
}
// Fallback: MokoCassiopeia
$query = $db->getQuery(true)
->select([$db->quoteName('extension_id'), $db->quoteName('enabled')])
->from($db->quoteName('#__extensions'))
->where($db->quoteName('element') . ' = ' . $db->quote('mokocassiopeia'))
->where($db->quoteName('type') . ' = ' . $db->quote('template'));
$template = $db->setQuery($query)->loadObject();
// Always unlock MokoCassiopeia (allow uninstall)
$db->setQuery(
$db->getQuery(true)
->update($db->quoteName('#__extensions'))
->set($db->quoteName('locked') . ' = 0')
->set($db->quoteName('protected') . ' = 0')
->where($db->quoteName('element') . ' = ' . $db->quote('mokocassiopeia'))
->where($db->quoteName('type') . ' = ' . $db->quote('template'))
)->execute();
}
if ($template)
{
// Lock, protect, and set as default
$db->setQuery(
$db->getQuery(true)
->update($db->quoteName('#__extensions'))
->set($db->quoteName('enabled') . ' = 1')
->set($db->quoteName('locked') . ' = 1')
->set($db->quoteName('protected') . ' = 1')
->where($db->quoteName('extension_id') . ' = '
. (int) $template->extension_id)
);
$db->execute();
$this->setDefaultTemplate('mokocassiopeia', 0);
return;
}
// Template not installed — install from bundled payload
/**
* Install MokoOnyx from the bundled payload zip.
*
* @return void
*
* @since 02.01.17
*/
private function installMokoOnyxFromPayload()
{
$pluginPath = JPATH_PLUGINS . '/system/mokowaas';
$payloadZip = $pluginPath . '/payload/mokoonyx.zip';
// Fallback to legacy name
if (!file_exists($payloadZip)) {
$payloadZip = $pluginPath . '/payload/mokocassiopeia.zip';
}
if (!file_exists($payloadZip))
{
Factory::getApplication()->enqueueMessage(
@@ -310,13 +294,9 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
try
{
// Extract the bundled zip
$archive = new \Joomla\Archive\Archive();
$archive->extract($payloadZip, $tmpDir);
// Release zips should have templateDetails.xml at root
// or one level deep
$installDir = $tmpDir;
if (!file_exists($tmpDir . '/templateDetails.xml'))
@@ -330,8 +310,7 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
else
{
Factory::getApplication()->enqueueMessage(
'MokoCassiopeia: templateDetails.xml not '
. 'found in archive.',
'MokoOnyx: templateDetails.xml not found in archive.',
'warning'
);
@@ -343,17 +322,15 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
if ($installer->install($installDir))
{
$this->ensureMokoCassiopeia();
Factory::getApplication()->enqueueMessage(
'MokoCassiopeia installed and locked.',
'MokoOnyx installed successfully.',
'message'
);
}
else
{
Factory::getApplication()->enqueueMessage(
'MokoCassiopeia installation failed.',
'MokoOnyx installation from payload failed.',
'warning'
);
}
@@ -361,7 +338,7 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
catch (\Exception $e)
{
Factory::getApplication()->enqueueMessage(
'MokoCassiopeia error: ' . $e->getMessage(),
'MokoOnyx error: ' . $e->getMessage(),
'warning'
);
}