fix: auto-cleanup stale plugin update site on install/update
Joomla: Repo Health / Access control (push) Has been cancelled
Universal: PR Check / Branch Policy (pull_request) Has been cancelled
Joomla: Repo Health / Access control (pull_request) Has been cancelled
Joomla: Extension CI / Release Readiness Check (pull_request) Has been cancelled
Universal: Auto Version Bump / Version Bump (push) Has been cancelled
Joomla: Extension CI / Lint & Validate (pull_request) Has been cancelled
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Has been cancelled
Universal: PR Check / Validate PR (pull_request) Has been cancelled
Universal: PR Check / Changelog Updated (pull_request) Has been cancelled
Update Server / Update updates.xml (push) Has been cancelled
Joomla: Repo Health / Release configuration (push) Has been cancelled
Joomla: Repo Health / Scripts governance (push) Has been cancelled
Joomla: Repo Health / Repository health (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Joomla: Repo Health / Release configuration (pull_request) Has been cancelled
Joomla: Repo Health / Scripts governance (pull_request) Has been cancelled
Joomla: Repo Health / Repository health (pull_request) Has been cancelled

Add cleanupPluginUpdateSite() to script.php postflight that removes
the plugin-level update site entry from #__update_sites and
#__update_sites_extensions. This prevents Joomla from checking for
plugin-level updates that don't exist, which caused download failures
on stable-only sites.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan Miller
2026-05-28 10:28:53 -05:00
parent c19d4da411
commit 1d2252e8b4
2 changed files with 73 additions and 0 deletions
+1
View File
@@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Trusted IP session bypass: moved from `onAfterInitialise` to `boot()` so Joomla's session lifetime is extended before the session handler validates it (was too late, Joomla expired the session first)
- updates.xml: removed stale pre-release entries pointing to non-existent dev artifacts, legacy plugin update entry that caused stable sites to attempt dev downloads
- Removed duplicate `<updateservers>` from inner plugin manifest — only the package-level manifest should register the update server
- Auto-cleanup of stale plugin-level update site entries on install/update (cleans `#__update_sites` and `#__update_sites_extensions`)
## [02.06.00] - 2026-05-25
@@ -123,6 +123,7 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
if ($type === 'install' || $type === 'update')
{
$this->enableAndLockPlugin();
$this->cleanupPluginUpdateSite();
$this->ensureMokoCassiopeia();
$this->installLanguageOverrides();
$this->updateLoginSupportUrls();
@@ -210,6 +211,77 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
$db->execute();
}
/**
* Remove the plugin-level update site so only the package-level one remains.
*
* Earlier versions registered an update server in the plugin manifest
* (plg_system_mokowaas) in addition to the package manifest (pkg_mokowaas).
* This caused Joomla to check for plugin-level updates that don't exist,
* leading to failed downloads. Only the package update site should exist.
*
* @return void
*
* @since 02.11.02
*/
private function cleanupPluginUpdateSite()
{
$db = Factory::getDbo();
// Find the extension_id for the plugin
$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);
$pluginId = (int) $db->loadResult();
if (!$pluginId)
{
return;
}
// Find update_site_ids linked to the plugin (not the package)
$query = $db->getQuery(true)
->select($db->quoteName('update_site_id'))
->from($db->quoteName('#__update_sites_extensions'))
->where($db->quoteName('extension_id') . ' = ' . $pluginId);
$db->setQuery($query);
$siteIds = $db->loadColumn();
if (empty($siteIds))
{
return;
}
// Delete the link rows
$db->setQuery(
$db->getQuery(true)
->delete($db->quoteName('#__update_sites_extensions'))
->where($db->quoteName('extension_id') . ' = ' . $pluginId)
)->execute();
// Delete orphaned update_sites rows (only if no other extension uses them)
foreach ($siteIds as $siteId)
{
$query = $db->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__update_sites_extensions'))
->where($db->quoteName('update_site_id') . ' = ' . (int) $siteId);
$db->setQuery($query);
if ((int) $db->loadResult() === 0)
{
$db->setQuery(
$db->getQuery(true)
->delete($db->quoteName('#__update_sites'))
->where($db->quoteName('update_site_id') . ' = ' . (int) $siteId)
)->execute();
}
}
}
/**
* Ensure MokoOnyx is installed, locked, and set as default.
*