diff --git a/source/packages/com_mokowaas/admin/sql/install.mysql.sql b/source/packages/com_mokowaas/admin/sql/install.mysql.sql index af34efcc..f6841edb 100644 --- a/source/packages/com_mokowaas/admin/sql/install.mysql.sql +++ b/source/packages/com_mokowaas/admin/sql/install.mysql.sql @@ -134,18 +134,3 @@ INSERT IGNORE INTO `#__mokowaas_retention_policies` (`id`, `content_type`, `rete (4, 'inactive_users', 730, 'anonymize', 0, 'Anonymize users inactive for 2 years (disabled by default)'), (5, 'closed_tickets', 365, 'anonymize', 0, 'Anonymize closed tickets older than 1 year (disabled by default)'); --- --- Download Key Storage — persistent backup of extension download keys --- that survives Joomla update site recreation --- -CREATE TABLE IF NOT EXISTS `#__mokowaas_download_keys` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `element` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'Extension element name', - `location` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'Update server URL', - `dlid` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Download key value', - `created` DATETIME NOT NULL, - `modified` DATETIME NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_dlkey_element` (`element`), - KEY `idx_dlkey_location` (`location`(191)) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/source/packages/com_mokowaas/admin/sql/uninstall.mysql.sql b/source/packages/com_mokowaas/admin/sql/uninstall.mysql.sql new file mode 100644 index 00000000..b58b727d --- /dev/null +++ b/source/packages/com_mokowaas/admin/sql/uninstall.mysql.sql @@ -0,0 +1,13 @@ +-- +-- MokoWaaS component uninstall — drop all tables +-- +DROP TABLE IF EXISTS `#__mokowaas_download_keys`; +DROP TABLE IF EXISTS `#__mokowaas_retention_policies`; +DROP TABLE IF EXISTS `#__mokowaas_data_requests`; +DROP TABLE IF EXISTS `#__mokowaas_consent_log`; +DROP TABLE IF EXISTS `#__mokowaas_waf_log`; +DROP TABLE IF EXISTS `#__mokowaas_ticket_automation`; +DROP TABLE IF EXISTS `#__mokowaas_ticket_canned`; +DROP TABLE IF EXISTS `#__mokowaas_ticket_replies`; +DROP TABLE IF EXISTS `#__mokowaas_tickets`; +DROP TABLE IF EXISTS `#__mokowaas_ticket_categories`; diff --git a/source/packages/com_mokowaas/admin/sql/updates/mysql/02.35.00.sql b/source/packages/com_mokowaas/admin/sql/updates/mysql/02.35.00.sql index 44aad811..bb1decec 100644 --- a/source/packages/com_mokowaas/admin/sql/updates/mysql/02.35.00.sql +++ b/source/packages/com_mokowaas/admin/sql/updates/mysql/02.35.00.sql @@ -1,11 +1,2 @@ -CREATE TABLE IF NOT EXISTS `#__mokowaas_download_keys` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `element` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'Extension element name', - `location` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'Update server URL', - `dlid` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Download key value', - `created` DATETIME NOT NULL, - `modified` DATETIME NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_dlkey_element` (`element`), - KEY `idx_dlkey_location` (`location`(191)) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +-- Remove download_keys table (feature reverted — preflight handles key preservation) +DROP TABLE IF EXISTS `#__mokowaas_download_keys`; diff --git a/source/packages/com_mokowaas/admin/src/Model/ExtensionsModel.php b/source/packages/com_mokowaas/admin/src/Model/ExtensionsModel.php index 0095f702..77024bf6 100644 --- a/source/packages/com_mokowaas/admin/src/Model/ExtensionsModel.php +++ b/source/packages/com_mokowaas/admin/src/Model/ExtensionsModel.php @@ -369,139 +369,6 @@ class ExtensionsModel extends BaseDatabaseModel } } - /** - * Save a download key for a Moko extension. - * - * @param string $element Extension element name. - * @param string $dlid Download key value. - * @param string $location Update server URL (optional). - */ - public function saveDownloadKey(string $element, string $dlid, string $location = ''): void - { - $db = $this->getDatabase(); - $now = gmdate('Y-m-d H:i:s'); - - // Upsert — update if exists, insert if not - $db->setQuery( - $db->getQuery(true) - ->select('COUNT(*)') - ->from($db->quoteName('#__mokowaas_download_keys')) - ->where($db->quoteName('element') . ' = ' . $db->quote($element)) - ); - - if ((int) $db->loadResult() > 0) - { - $db->setQuery( - $db->getQuery(true) - ->update($db->quoteName('#__mokowaas_download_keys')) - ->set($db->quoteName('dlid') . ' = ' . $db->quote($dlid)) - ->set($db->quoteName('location') . ' = ' . $db->quote($location)) - ->set($db->quoteName('modified') . ' = ' . $db->quote($now)) - ->where($db->quoteName('element') . ' = ' . $db->quote($element)) - )->execute(); - } - else - { - $db->setQuery( - $db->getQuery(true) - ->insert($db->quoteName('#__mokowaas_download_keys')) - ->columns([$db->quoteName('element'), $db->quoteName('location'), $db->quoteName('dlid'), $db->quoteName('created'), $db->quoteName('modified')]) - ->values(implode(',', [ - $db->quote($element), - $db->quote($location), - $db->quote($dlid), - $db->quote($now), - $db->quote($now), - ])) - )->execute(); - } - - // Immediately apply to Joomla's update site - $this->applyDownloadKey($element, $dlid); - } - - /** - * Apply a stored download key to Joomla's update site for an extension. - */ - public function applyDownloadKey(string $element, string $dlid): void - { - $db = $this->getDatabase(); - - $db->setQuery( - $db->getQuery(true) - ->select('us.' . $db->quoteName('update_site_id')) - ->from($db->quoteName('#__update_sites', 'us')) - ->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON us.update_site_id = use.update_site_id') - ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id') - ->where($db->quoteName('e.element') . ' = ' . $db->quote($element)) - ); - $siteIds = $db->loadColumn() ?: []; - - foreach ($siteIds as $siteId) - { - $db->setQuery( - $db->getQuery(true) - ->update($db->quoteName('#__update_sites')) - ->set($db->quoteName('extra_query') . ' = ' . $db->quote('dlid=' . $dlid)) - ->where($db->quoteName('update_site_id') . ' = ' . (int) $siteId) - )->execute(); - } - } - - /** - * Re-apply all stored Moko download keys to Joomla's update sites. - * Called after updates that may have wiped extra_query. - * - * @return int Number of keys re-applied. - */ - public static function reapplyAllDownloadKeys(): int - { - try - { - $db = Factory::getDbo(); - - $db->setQuery( - $db->getQuery(true) - ->select('*') - ->from($db->quoteName('#__mokowaas_download_keys')) - ->where($db->quoteName('dlid') . ' != ' . $db->quote('')) - ); - $keys = $db->loadObjectList() ?: []; - - $applied = 0; - - foreach ($keys as $key) - { - $db->setQuery( - $db->getQuery(true) - ->select('us.' . $db->quoteName('update_site_id')) - ->from($db->quoteName('#__update_sites', 'us')) - ->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON us.update_site_id = use.update_site_id') - ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id') - ->where($db->quoteName('e.element') . ' = ' . $db->quote($key->element)) - ); - $siteIds = $db->loadColumn() ?: []; - - foreach ($siteIds as $siteId) - { - $db->setQuery( - $db->getQuery(true) - ->update($db->quoteName('#__update_sites')) - ->set($db->quoteName('extra_query') . ' = ' . $db->quote('dlid=' . $key->dlid)) - ->where($db->quoteName('update_site_id') . ' = ' . (int) $siteId) - )->execute(); - $applied++; - } - } - - return $applied; - } - catch (\Throwable $e) - { - return 0; - } - } - /** * Get the extension_id for an element (for uninstall links). * diff --git a/source/packages/com_mokowaas/mokowaas.xml b/source/packages/com_mokowaas/mokowaas.xml index 54fbf140..61588358 100644 --- a/source/packages/com_mokowaas/mokowaas.xml +++ b/source/packages/com_mokowaas/mokowaas.xml @@ -25,6 +25,12 @@ Moko\Component\MokoWaaS + + sql/install.mysql.sql + + + sql/uninstall.mysql.sql + sql/updates/mysql diff --git a/source/packages/plg_system_mokowaas/Extension/MokoWaaS.php b/source/packages/plg_system_mokowaas/Extension/MokoWaaS.php index 90a577de..d782f3df 100644 --- a/source/packages/plg_system_mokowaas/Extension/MokoWaaS.php +++ b/source/packages/plg_system_mokowaas/Extension/MokoWaaS.php @@ -2239,138 +2239,8 @@ class MokoWaaS extends CMSPlugin implements BootableExtensionInterface */ protected function preserveDownloadKeys(): void { - try - { - $db = Factory::getDbo(); - - // Sync: copy any new download keys FROM Joomla's update_sites TO our table - $this->syncKeysToTable($db); - - // Apply: re-apply all stored keys FROM our table TO Joomla's update_sites - $this->applyKeysFromTable($db); - } - catch (\Throwable $e) - { - // Non-critical - } + // Download key preservation is handled by the install script's + // preflight/postflight (backupDownloadKeys/restoreDownloadKeys). + // No runtime action needed — the preflight fix catches the wipe. } - - /** - * Copy non-empty download keys from Joomla's update_sites to our persistent table. - */ - private function syncKeysToTable($db): void - { - // Find all update sites with download keys - $db->setQuery( - $db->getQuery(true) - ->select([ - 'us.' . $db->quoteName('extra_query'), - 'us.' . $db->quoteName('location'), - 'e.' . $db->quoteName('element'), - ]) - ->from($db->quoteName('#__update_sites', 'us')) - ->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON us.update_site_id = use.update_site_id') - ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id') - ->where($db->quoteName('us.extra_query') . ' LIKE ' . $db->quote('%dlid=%')) - ); - $rows = $db->loadObjectList() ?: []; - - $now = gmdate('Y-m-d H:i:s'); - - foreach ($rows as $row) - { - parse_str($row->extra_query, $parsed); - $dlid = $parsed['dlid'] ?? ''; - - if (empty($dlid)) - { - continue; - } - - // Upsert into our table - $db->setQuery( - $db->getQuery(true) - ->select('COUNT(*)') - ->from($db->quoteName('#__mokowaas_download_keys')) - ->where($db->quoteName('element') . ' = ' . $db->quote($row->element)) - ); - - if ((int) $db->loadResult() > 0) - { - $db->setQuery( - $db->getQuery(true) - ->update($db->quoteName('#__mokowaas_download_keys')) - ->set($db->quoteName('dlid') . ' = ' . $db->quote($dlid)) - ->set($db->quoteName('location') . ' = ' . $db->quote($row->location)) - ->set($db->quoteName('modified') . ' = ' . $db->quote($now)) - ->where($db->quoteName('element') . ' = ' . $db->quote($row->element)) - )->execute(); - } - else - { - $db->setQuery( - $db->getQuery(true) - ->insert($db->quoteName('#__mokowaas_download_keys')) - ->columns([$db->quoteName('element'), $db->quoteName('location'), $db->quoteName('dlid'), $db->quoteName('created'), $db->quoteName('modified')]) - ->values(implode(',', [ - $db->quote($row->element), - $db->quote($row->location), - $db->quote($dlid), - $db->quote($now), - $db->quote($now), - ])) - )->execute(); - } - } - } - - /** - * Re-apply all stored download keys from our table to Joomla's update_sites. - */ - private function applyKeysFromTable($db): void - { - try - { - $db->setQuery( - $db->getQuery(true) - ->select('*') - ->from($db->quoteName('#__mokowaas_download_keys')) - ->where($db->quoteName('dlid') . ' != ' . $db->quote('')) - ); - } - catch (\Throwable $e) - { - // Table might not exist yet (before install SQL runs) - return; - } - - $keys = $db->loadObjectList() ?: []; - - foreach ($keys as $key) - { - // Find update sites for this extension that are missing the key - $db->setQuery( - $db->getQuery(true) - ->select('us.' . $db->quoteName('update_site_id')) - ->from($db->quoteName('#__update_sites', 'us')) - ->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON us.update_site_id = use.update_site_id') - ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id') - ->where($db->quoteName('e.element') . ' = ' . $db->quote($key->element)) - ->where('(' . $db->quoteName('us.extra_query') . ' = ' . $db->quote('') - . ' OR ' . $db->quoteName('us.extra_query') . ' NOT LIKE ' . $db->quote('%dlid=%') . ')') - ); - $siteIds = $db->loadColumn() ?: []; - - foreach ($siteIds as $siteId) - { - $db->setQuery( - $db->getQuery(true) - ->update($db->quoteName('#__update_sites')) - ->set($db->quoteName('extra_query') . ' = ' . $db->quote('dlid=' . $key->dlid)) - ->where($db->quoteName('update_site_id') . ' = ' . (int) $siteId) - )->execute(); - } - } - } - } diff --git a/source/script.php b/source/script.php index e13c52d6..1cf217fe 100644 --- a/source/script.php +++ b/source/script.php @@ -109,12 +109,8 @@ class Pkg_MokowaasInstallerScript // Clean up stale/duplicate update sites $this->cleanupStaleUpdateSites(); - // Ensure download keys table exists (belt-and-suspenders with schema update) - $this->ensureDownloadKeysTable(); - - // Restore download keys: first from preflight backup, then from DB table + // Restore download keys saved in preflight (before Joomla wiped them) $this->restoreDownloadKeys($this->savedDownloadKeys); - $this->reapplyKeysFromDatabase(); // Fix orphaned update records (extension_id=0) $this->fixUpdateRecords(); @@ -676,33 +672,6 @@ class Pkg_MokowaasInstallerScript * * @return array Map of update_site_id => extra_query */ - /** - * Ensure the download keys table exists. - */ - private function ensureDownloadKeysTable(): void - { - try - { - $db = Factory::getDbo(); - $db->setQuery("CREATE TABLE IF NOT EXISTS `#__mokowaas_download_keys` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `element` VARCHAR(100) NOT NULL DEFAULT '', - `location` VARCHAR(512) NOT NULL DEFAULT '', - `dlid` VARCHAR(255) NOT NULL DEFAULT '', - `created` DATETIME NOT NULL, - `modified` DATETIME NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_dlkey_element` (`element`), - KEY `idx_dlkey_location` (`location`(191)) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); - $db->execute(); - } - catch (\Throwable $e) - { - // Non-critical - } - } - private function backupDownloadKeys(): array { $keys = []; @@ -735,8 +704,6 @@ class Pkg_MokowaasInstallerScript $keys['id_' . $row->update_site_id] = $row->extra_query; } - // Also save to our persistent database table - $this->syncKeysToDatabase($db, $rows); } catch (\Throwable $e) { @@ -746,154 +713,6 @@ class Pkg_MokowaasInstallerScript return $keys; } - /** - * Sync current download keys to the persistent #__mokowaas_download_keys table. - */ - private function syncKeysToDatabase($db, array $rows): void - { - try - { - // Check if table exists - $tables = $db->getTableList(); - $prefix = $db->getPrefix(); - - if (!\in_array($prefix . 'mokowaas_download_keys', $tables, true)) - { - return; - } - - $now = gmdate('Y-m-d H:i:s'); - - foreach ($rows as $row) - { - parse_str($row->extra_query, $parsed); - $dlid = $parsed['dlid'] ?? ''; - - if (empty($dlid)) - { - continue; - } - - // Find the element for this update site - $db->setQuery( - $db->getQuery(true) - ->select('e.' . $db->quoteName('element')) - ->from($db->quoteName('#__update_sites_extensions', 'use')) - ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id') - ->where($db->quoteName('use.update_site_id') . ' = ' . (int) $row->update_site_id), - 0, 1 - ); - $element = (string) $db->loadResult(); - - if (empty($element)) - { - continue; - } - - // Upsert - $db->setQuery( - $db->getQuery(true) - ->select('COUNT(*)') - ->from($db->quoteName('#__mokowaas_download_keys')) - ->where($db->quoteName('element') . ' = ' . $db->quote($element)) - ); - - if ((int) $db->loadResult() > 0) - { - $db->setQuery( - $db->getQuery(true) - ->update($db->quoteName('#__mokowaas_download_keys')) - ->set($db->quoteName('dlid') . ' = ' . $db->quote($dlid)) - ->set($db->quoteName('location') . ' = ' . $db->quote($row->location)) - ->set($db->quoteName('modified') . ' = ' . $db->quote($now)) - ->where($db->quoteName('element') . ' = ' . $db->quote($element)) - )->execute(); - } - else - { - $db->setQuery( - $db->getQuery(true) - ->insert($db->quoteName('#__mokowaas_download_keys')) - ->columns([$db->quoteName('element'), $db->quoteName('location'), $db->quoteName('dlid'), $db->quoteName('created'), $db->quoteName('modified')]) - ->values(implode(',', [ - $db->quote($element), $db->quote($row->location), $db->quote($dlid), $db->quote($now), $db->quote($now), - ])) - )->execute(); - } - } - } - catch (\Throwable $e) - { - // Non-critical — table may not exist yet - } - } - - /** - * Re-apply all download keys from our persistent database table. - */ - private function reapplyKeysFromDatabase(): void - { - try - { - $db = Factory::getDbo(); - $tables = $db->getTableList(); - $prefix = $db->getPrefix(); - - if (!\in_array($prefix . 'mokowaas_download_keys', $tables, true)) - { - return; - } - - $db->setQuery( - $db->getQuery(true) - ->select('*') - ->from($db->quoteName('#__mokowaas_download_keys')) - ->where($db->quoteName('dlid') . ' != ' . $db->quote('')) - ); - $keys = $db->loadObjectList() ?: []; - - $restored = 0; - - foreach ($keys as $key) - { - $db->setQuery( - $db->getQuery(true) - ->select('us.' . $db->quoteName('update_site_id')) - ->from($db->quoteName('#__update_sites', 'us')) - ->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON us.update_site_id = use.update_site_id') - ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id') - ->where($db->quoteName('e.element') . ' = ' . $db->quote($key->element)) - ->where('(' . $db->quoteName('us.extra_query') . ' = ' . $db->quote('') - . ' OR ' . $db->quoteName('us.extra_query') . ' NOT LIKE ' . $db->quote('%dlid=%') . ')') - ); - $siteIds = $db->loadColumn() ?: []; - - foreach ($siteIds as $siteId) - { - $db->setQuery( - $db->getQuery(true) - ->update($db->quoteName('#__update_sites')) - ->set($db->quoteName('extra_query') . ' = ' . $db->quote('dlid=' . $key->dlid)) - ->where($db->quoteName('update_site_id') . ' = ' . (int) $siteId) - )->execute(); - $restored++; - } - } - - if ($restored > 0) - { - Factory::getApplication()->enqueueMessage( - sprintf('Re-applied %d download key(s) from persistent storage.', $restored), - 'message' - ); - } - } - catch (\Throwable $e) - { - // Non-critical - } - } - /** * Restore download keys that were cleared by update site cleanup. *