fix(install): delete empty-element rows and all stale files cleanly
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 7s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 11s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 16s
Generic: Project CI / Lint & Validate (pull_request) Successful in 31s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 41s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 39s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 7s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 11s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 16s
Generic: Project CI / Lint & Validate (pull_request) Successful in 31s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 41s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 39s
Relocation approach failed — multiple plugins overwrite each other's files at the group root. Instead, delete empty-element rows and all stale files/dirs. On the NEXT update, Joomla creates fresh rows and installs correctly since the orphan rows are gone.
This commit is contained in:
+37
-70
@@ -526,84 +526,51 @@ class Pkg_MokosuiteclientInstallerScript
|
||||
try
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$systemDir = JPATH_PLUGINS . '/system';
|
||||
|
||||
// Find empty-element rows and fix them using the manifest name
|
||||
$db->setQuery(
|
||||
$db->getQuery(true)
|
||||
->select([$db->quoteName('extension_id'), $db->quoteName('name'), $db->quoteName('folder')])
|
||||
->from($db->quoteName('#__extensions'))
|
||||
->where($db->quoteName('element') . " = ''")
|
||||
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
|
||||
);
|
||||
$orphans = $db->loadObjectList() ?: [];
|
||||
// Delete orphaned extension rows with empty element — they'll be
|
||||
// recreated correctly on the next package update
|
||||
$db->setQuery("DELETE FROM " . $db->quoteName('#__extensions')
|
||||
. " WHERE " . $db->quoteName('element') . " = ''"
|
||||
. " AND " . $db->quoteName('type') . " = 'plugin'");
|
||||
$db->execute();
|
||||
$deleted = $db->getAffectedRows();
|
||||
|
||||
foreach ($orphans as $orphan)
|
||||
if ($deleted > 0)
|
||||
{
|
||||
// Derive element from the manifest name (e.g. "plg_system_mokosuiteclient_offline" → "mokosuiteclient_offline")
|
||||
$element = preg_replace('/^plg_[a-z]+_/', '', strtolower($orphan->name));
|
||||
|
||||
// Also try matching from stale XML manifests at group root
|
||||
if (empty($element))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$pluginDir = $systemDir . '/' . $element;
|
||||
|
||||
// If plugin dir doesn't exist but stale files do, relocate them
|
||||
if (!is_dir($pluginDir) && $orphan->folder === 'system')
|
||||
{
|
||||
@mkdir($pluginDir, 0755, true);
|
||||
|
||||
// Move stale dirs (services, src, language) into the plugin dir
|
||||
foreach (['services', 'src', 'language'] as $subDir)
|
||||
{
|
||||
$stalePath = $systemDir . '/' . $subDir;
|
||||
|
||||
if (is_dir($stalePath) && !is_dir($pluginDir . '/' . $subDir))
|
||||
{
|
||||
@rename($stalePath, $pluginDir . '/' . $subDir);
|
||||
}
|
||||
}
|
||||
|
||||
// Move stale manifest XML
|
||||
$staleXml = $systemDir . '/' . $element . '.xml';
|
||||
|
||||
if (is_file($staleXml))
|
||||
{
|
||||
@rename($staleXml, $pluginDir . '/' . $element . '.xml');
|
||||
}
|
||||
|
||||
Log::add("Relocated stale files to plugins/system/{$element}/", Log::INFO, 'mokosuiteclient');
|
||||
}
|
||||
|
||||
// Fix the element in the DB
|
||||
$db->setQuery(
|
||||
$db->getQuery(true)
|
||||
->update($db->quoteName('#__extensions'))
|
||||
->set($db->quoteName('element') . ' = ' . $db->quote($element))
|
||||
->where($db->quoteName('extension_id') . ' = ' . (int) $orphan->extension_id)
|
||||
)->execute();
|
||||
|
||||
Log::add("Fixed empty element → {$element} (ID {$orphan->extension_id})", Log::INFO, 'mokosuiteclient');
|
||||
Log::add("Deleted {$deleted} orphaned plugin row(s) with empty element", Log::INFO, 'mokosuiteclient');
|
||||
}
|
||||
|
||||
// Clean up any remaining stale dirs that couldn't be matched
|
||||
foreach (['services', 'src', 'language'] as $dir)
|
||||
{
|
||||
$path = $systemDir . '/' . $dir;
|
||||
// Clean up stale plugin files that leaked to plugin group roots
|
||||
$groupDirs = [JPATH_PLUGINS . '/system', JPATH_PLUGINS . '/task', JPATH_PLUGINS . '/webservices'];
|
||||
|
||||
if (is_dir($path))
|
||||
foreach ($groupDirs as $groupDir)
|
||||
{
|
||||
foreach (['services', 'src', 'language'] as $dir)
|
||||
{
|
||||
$this->rmdirRecursive($path);
|
||||
}
|
||||
}
|
||||
$path = $groupDir . '/' . $dir;
|
||||
|
||||
// Clean up stale XML manifests at group root
|
||||
foreach (glob($systemDir . '/mokosuiteclient_*.xml') ?: [] as $staleXml)
|
||||
{
|
||||
@unlink($staleXml);
|
||||
if (is_dir($path))
|
||||
{
|
||||
$this->rmdirRecursive($path);
|
||||
Log::add("Removed stale: {$path}", Log::INFO, 'mokosuiteclient');
|
||||
}
|
||||
}
|
||||
|
||||
// Remove stale manifest XMLs at group root
|
||||
foreach (glob($groupDir . '/mokosuiteclient*.xml') ?: [] as $staleXml)
|
||||
{
|
||||
@unlink($staleXml);
|
||||
}
|
||||
|
||||
// Remove dirs with spaces (Joomla uses display name as dir when element is empty)
|
||||
foreach (glob($groupDir . '/*mokosuiteclient*', GLOB_ONLYDIR) ?: [] as $badDir)
|
||||
{
|
||||
if (strpos(basename($badDir), ' ') !== false)
|
||||
{
|
||||
$this->rmdirRecursive($badDir);
|
||||
Log::add("Removed bad dir: " . basename($badDir), Log::INFO, 'mokosuiteclient');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Throwable $e)
|
||||
|
||||
Reference in New Issue
Block a user