From 0e2433cf5c00562b7f486eb30b1b709e6fe8187c Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sun, 21 Jun 2026 17:41:07 -0500 Subject: [PATCH] fix(install): use Joomla Installer API for plugin reinstall Replace raw ZipArchive extract with Joomla\CMS\Installer\Installer::install() which properly handles namespace registration, extension record creation, and all internal bookkeeping. Removes manual INSERT from enablePlugin() since the Installer handles it correctly. --- source/script.php | 78 ++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/source/script.php b/source/script.php index 2bf0a795..1d40fe8d 100644 --- a/source/script.php +++ b/source/script.php @@ -520,47 +520,8 @@ class Pkg_MokosuiteclientInstallerScript ->where($db->quoteName('element') . ' = ' . $db->quote($element)) ); - if ((int) $db->loadResult() > 0) - { - return; - } - - // No row exists — create one from the manifest XML on disk - $manifestFile = $pluginDir . '/' . $element . '.xml'; - - if (is_file($manifestFile)) - { - $xml = @simplexml_load_file($manifestFile); - $name = $xml ? (string) ($xml->name ?? $manifestName) : $manifestName; - $namespace = $xml ? (string) ($xml->namespace ?? '') : ''; - - $row = (object) [ - 'name' => $name, - 'type' => 'plugin', - 'element' => $element, - 'folder' => $group, - 'client_id' => 0, - 'enabled' => 1, - 'access' => 1, - 'protected' => 0, - 'locked' => 0, - 'params' => '{}', - 'manifest_cache' => '{}', - 'custom_data' => '', - 'state' => 0, - 'ordering' => 0, - 'checked_out' => null, - 'checked_out_time' => null, - ]; - - if (!empty($namespace)) - { - $row->namespace = $namespace; - } - - $db->insertObject('#__extensions', $row, 'extension_id'); - Log::add('Created extension record for plugin ' . $group . '/' . $element, Log::INFO, 'mokosuiteclient'); - } + // No row exists — reinstallBrokenPlugins() will handle it via + // Joomla's Installer which properly registers the namespace } catch (\Throwable $e) { @@ -679,8 +640,8 @@ class Pkg_MokosuiteclientInstallerScript try { - $installer = $this->installerParent->getParent(); - $sourceDir = $installer->getPath('source'); + $parentInstaller = $this->installerParent->getParent(); + $sourceDir = $parentInstaller->getPath('source'); if (empty($sourceDir) || !is_dir($sourceDir . '/packages')) { @@ -697,9 +658,6 @@ class Pkg_MokosuiteclientInstallerScript { foreach ($elements as $element) { - $pluginDir = JPATH_PLUGINS . '/' . $group . '/' . $element; - - // Always re-extract to ensure files are up to date $zipName = 'plg_' . $group . '_' . $element . '.zip'; $zipPath = $sourceDir . '/packages/' . $zipName; @@ -708,7 +666,17 @@ class Pkg_MokosuiteclientInstallerScript continue; } - // Extract the zip to the correct plugin directory + // Use Joomla's Installer to properly install the plugin + // This handles namespace registration, extension record, and file placement + $tmpDir = Factory::getConfig()->get('tmp_path', sys_get_temp_dir()) . '/mokosuiteclient_' . $element; + + if (is_dir($tmpDir)) + { + $this->rmdirRecursive($tmpDir); + } + + @mkdir($tmpDir, 0755, true); + $zip = new \ZipArchive(); if ($zip->open($zipPath) !== true) @@ -716,14 +684,20 @@ class Pkg_MokosuiteclientInstallerScript continue; } - if (is_dir($pluginDir)) + $zip->extractTo($tmpDir); + $zip->close(); + + $installer = new \Joomla\CMS\Installer\Installer(); + $installer->setOverwrite(true); + $installer->setUpgrade(true); + + if ($installer->install($tmpDir)) { - $this->rmdirRecursive($pluginDir); + Log::add("Installed {$group}/{$element} via Joomla Installer", Log::INFO, 'mokosuiteclient'); } - @mkdir($pluginDir, 0755, true); - $zip->extractTo($pluginDir); - $zip->close(); + // Clean up temp + $this->rmdirRecursive($tmpDir); } } }