diff --git a/source/script.php b/source/script.php index 1d40fe8d..ba99bb8e 100644 --- a/source/script.php +++ b/source/script.php @@ -666,17 +666,7 @@ class Pkg_MokosuiteclientInstallerScript continue; } - // 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); - + // Extract to plugin dir $zip = new \ZipArchive(); if ($zip->open($zipPath) !== true) @@ -684,20 +674,101 @@ class Pkg_MokosuiteclientInstallerScript continue; } - $zip->extractTo($tmpDir); - $zip->close(); - - $installer = new \Joomla\CMS\Installer\Installer(); - $installer->setOverwrite(true); - $installer->setUpgrade(true); - - if ($installer->install($tmpDir)) + if (is_dir($pluginDir)) { - Log::add("Installed {$group}/{$element} via Joomla Installer", Log::INFO, 'mokosuiteclient'); + $this->rmdirRecursive($pluginDir); } - // Clean up temp - $this->rmdirRecursive($tmpDir); + @mkdir($pluginDir, 0755, true); + $zip->extractTo($pluginDir); + $zip->close(); + } + } + + // Step 2: Create DB records for plugins that have files but no record + $db = Factory::getDbo(); + + foreach ($expected as $group => $elements) + { + foreach ($elements as $element) + { + $pluginDir = JPATH_PLUGINS . '/' . $group . '/' . $element; + $manifestFile = $pluginDir . '/' . $element . '.xml'; + + if (!is_file($manifestFile)) + { + continue; + } + + // Check if record exists + $db->setQuery( + $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' = ' . $db->quote($group)) + ->where($db->quoteName('element') . ' = ' . $db->quote($element)) + ); + + if ((int) $db->loadResult() > 0) + { + continue; + } + + // Parse manifest for name and namespace + $xml = @simplexml_load_file($manifestFile); + $name = $xml ? (string) ($xml->name ?? '') : ''; + $namespace = $xml ? (string) ($xml->namespace ?? '') : ''; + $version = $xml ? (string) ($xml->version ?? '') : ''; + + if (empty($name)) + { + $name = 'plg_' . $group . '_' . $element; + } + + // Build manifest cache + $cache = json_encode([ + 'name' => $name, + 'type' => 'plugin', + 'version' => $version, + 'group' => $group, + ]); + + // INSERT with all required fields including namespace + $columns = 'name, type, element, folder, client_id, enabled, access, protected, locked, params, manifest_cache, custom_data, state, ordering'; + $values = $db->quote($name) . ', ' + . $db->quote('plugin') . ', ' + . $db->quote($element) . ', ' + . $db->quote($group) . ', ' + . '0, 1, 1, 0, 0, ' + . $db->quote('{}') . ', ' + . $db->quote($cache) . ', ' + . $db->quote('') . ', 0, 0'; + + $sql = "INSERT INTO " . $db->quoteName('#__extensions') + . " ({$columns}) VALUES ({$values})"; + $db->setQuery($sql)->execute(); + $newId = $db->insertid(); + + // Set namespace if column exists + if (!empty($namespace)) + { + try + { + $db->setQuery( + $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->quoteName('namespace') . ' = ' . $db->quote($namespace)) + ->where($db->quoteName('extension_id') . ' = ' . (int) $newId) + )->execute(); + } + catch (\Throwable $e) + { + // namespace column may not exist in this Joomla version + } + } + + Log::add("Created extension record for {$group}/{$element} (ID {$newId})", Log::INFO, 'mokosuiteclient'); } } }