diff --git a/source/script.php b/source/script.php new file mode 100644 index 0000000..0573c5a --- /dev/null +++ b/source/script.php @@ -0,0 +1,194 @@ +saveDownloadKey(); + + return true; + } + + public function postflight(string $type, InstallerAdapter $parent): void + { + $app = Factory::getApplication(); + + // Download the MokoSuite package + $tmpPath = Factory::getApplication()->get('tmp_path', sys_get_temp_dir()); + $zipFile = $tmpPath . '/pkg_mokosuite_migration.zip'; + + // Append dlid if we have one + $url = self::MOKOSUITE_URL; + + if ($this->savedDownloadKey) + { + $url .= (strpos($url, '?') === false ? '?' : '&') . $this->savedDownloadKey; + } + + try + { + $http = \Joomla\CMS\Http\HttpFactory::getHttp(); + $response = $http->get($url, [], 60); + + if ($response->code !== 200) + { + $app->enqueueMessage( + 'MokoSuite migration: Failed to download package (HTTP ' . $response->code . '). ' + . 'Please install MokoSuite manually from the Joomla extension manager.', + 'error' + ); + + return; + } + + file_put_contents($zipFile, $response->body); + } + catch (\Throwable $e) + { + $app->enqueueMessage( + 'MokoSuite migration: Download failed — ' . $e->getMessage() . '. ' + . 'Please install MokoSuite manually.', + 'error' + ); + + return; + } + + // Install the MokoSuite package (its postflight handles all migration) + try + { + $installer = Installer::getInstance(); + $result = $installer->install($zipFile); + + if ($result) + { + $app->enqueueMessage( + 'MokoSuite installed successfully! ' + . 'Your MokoWaaS installation has been migrated to MokoSuite. ' + . 'All settings, tickets, and data have been preserved.', + 'message' + ); + } + else + { + $app->enqueueMessage( + 'MokoSuite migration: Package install returned false. ' + . 'Please check the Joomla installer log and install MokoSuite manually if needed.', + 'warning' + ); + } + } + catch (\Throwable $e) + { + $app->enqueueMessage( + 'MokoSuite migration: Install failed — ' . $e->getMessage(), + 'error' + ); + } + finally + { + // Clean up temp file + if (is_file($zipFile)) + { + @unlink($zipFile); + } + } + + // Transfer the download key to the new MokoSuite update site + $this->restoreDownloadKey(); + } + + /** + * Save the download key from whichever update site exists. + */ + private function saveDownloadKey(): void + { + try + { + $db = Factory::getDbo(); + + foreach (['pkg_mokosuite', 'pkg_mokowaas'] as $element) + { + $db->setQuery( + $db->getQuery(true) + ->select($db->quoteName('us.extra_query')) + ->from($db->quoteName('#__update_sites', 'us')) + ->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON use.update_site_id = us.update_site_id') + ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id') + ->where($db->quoteName('e.element') . ' = ' . $db->quote($element)) + ->setLimit(1) + ); + $key = $db->loadResult(); + + if (!empty($key) && strpos($key, 'dlid=') !== false) + { + $this->savedDownloadKey = $key; + break; + } + } + } + catch (\Throwable $e) {} + } + + /** + * Copy the download key to the MokoSuite update site. + */ + private function restoreDownloadKey(): void + { + if ($this->savedDownloadKey === null) + { + return; + } + + try + { + $db = Factory::getDbo(); + $db->setQuery( + $db->getQuery(true) + ->select($db->quoteName('us.update_site_id')) + ->from($db->quoteName('#__update_sites', 'us')) + ->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON use.update_site_id = us.update_site_id') + ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id') + ->where($db->quoteName('e.element') . ' = ' . $db->quote('pkg_mokosuite')) + ->setLimit(1) + ); + $siteId = (int) $db->loadResult(); + + if ($siteId > 0) + { + $db->setQuery( + $db->getQuery(true) + ->update($db->quoteName('#__update_sites')) + ->set($db->quoteName('extra_query') . ' = ' . $db->quote($this->savedDownloadKey)) + ->where($db->quoteName('update_site_id') . ' = ' . $siteId) + )->execute(); + + Log::add('Migrated download key to MokoSuite update site', Log::INFO, 'mokosuite'); + } + } + catch (\Throwable $e) {} + } +}