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.
*