diff --git a/CHANGELOG.md b/CHANGELOG.md index 0da58f6b..6dc1a18b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,11 @@ - **Update server migration** — removed migrateUpdateServerUrls, cleanupStaleUpdateSites, fixUpdateRecords, enableUpdateServer calls ### Fixed +- **Regular Labs import** — destination tables missing from SQL update files; sites that upgraded never got the tables, causing "No data found" on import +- **Regular Labs import banner** — detection now requires both source AND destination tables before showing the import button +- **DB-IP auto-enrichment** — all IPs in `` tags in admin backend now show country flag emoji and geo tooltip on hover +- **MokoSuiteBackup quick action** — dashboard now includes MokoSuiteBackup button when component is installed +- **PIN copy** — fixed duplicate click handlers (4 toast messages), "Copied!" not reverting, added "Click to copy" hover tooltip - Health endpoint cron check SQL error — orphan `setQuery(getQuery(true), 0, 5)` produced bare `LIMIT 5`, returning 503 for all health polls - License plugin missing `src/` and `language/` directories causing install failure - PIN generation inconsistency — controller used `floor(now/TTL)` while display used `floor(requestedAt/TTL)` diff --git a/source/packages/com_mokosuiteclient/admin/sql/updates/mysql/02.48.20.sql b/source/packages/com_mokosuiteclient/admin/sql/updates/mysql/02.48.20.sql new file mode 100644 index 00000000..2e4ef82f --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/sql/updates/mysql/02.48.20.sql @@ -0,0 +1,108 @@ +-- Regular Labs replacement tables (conditions, snippets, replacements, content templates) +-- These were in install.mysql.sql but missing from updates, so existing installs never got them. + +CREATE TABLE IF NOT EXISTS `#__mokosuiteclient_conditions` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `alias` VARCHAR(100) NOT NULL DEFAULT '', + `name` VARCHAR(100) NOT NULL DEFAULT '', + `description` TEXT NOT NULL, + `category` VARCHAR(50) NOT NULL DEFAULT '', + `color` VARCHAR(8) DEFAULT NULL, + `match_all` TINYINT(1) NOT NULL DEFAULT 1, + `published` TINYINT(1) NOT NULL DEFAULT 1, + `hash` VARCHAR(32) NOT NULL DEFAULT '', + `checked_out` INT UNSIGNED DEFAULT NULL, + `checked_out_time` DATETIME DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_published` (`published`), + KEY `idx_alias` (`alias`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `#__mokosuiteclient_conditions_groups` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `condition_id` INT UNSIGNED NOT NULL, + `match_all` TINYINT(1) NOT NULL DEFAULT 1, + `ordering` INT UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_condition` (`condition_id`), + KEY `idx_ordering` (`condition_id`, `ordering`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `#__mokosuiteclient_conditions_rules` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `group_id` INT UNSIGNED NOT NULL, + `type` VARCHAR(50) NOT NULL DEFAULT '', + `exclude` TINYINT(1) NOT NULL DEFAULT 0, + `params` TEXT NOT NULL, + `ordering` INT UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_group` (`group_id`), + KEY `idx_type` (`type`), + KEY `idx_ordering` (`group_id`, `ordering`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `#__mokosuiteclient_conditions_map` ( + `condition_id` INT UNSIGNED NOT NULL, + `extension` VARCHAR(50) NOT NULL DEFAULT '', + `item_id` INT UNSIGNED NOT NULL DEFAULT 0, + UNIQUE KEY `idx_unique` (`condition_id`, `item_id`, `extension`), + KEY `idx_ext_item` (`extension`, `item_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `#__mokosuiteclient_snippets` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `alias` VARCHAR(100) NOT NULL DEFAULT '', + `name` VARCHAR(100) NOT NULL DEFAULT '', + `description` TEXT NOT NULL, + `category` VARCHAR(50) NOT NULL DEFAULT '', + `color` VARCHAR(8) DEFAULT NULL, + `content` MEDIUMTEXT NOT NULL, + `params` TEXT NOT NULL, + `published` TINYINT(1) NOT NULL DEFAULT 0, + `ordering` INT NOT NULL DEFAULT 0, + `checked_out` INT UNSIGNED DEFAULT NULL, + `checked_out_time` DATETIME DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_alias` (`alias`), + KEY `idx_published` (`published`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `#__mokosuiteclient_replacements` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(100) NOT NULL DEFAULT '', + `search` TEXT NOT NULL, + `replace_value` TEXT NOT NULL, + `area` VARCHAR(20) NOT NULL DEFAULT 'both', + `regex` TINYINT(1) NOT NULL DEFAULT 0, + `casesensitive` TINYINT(1) NOT NULL DEFAULT 0, + `category` VARCHAR(50) NOT NULL DEFAULT '', + `published` TINYINT(1) NOT NULL DEFAULT 0, + `description` TEXT NOT NULL, + `enable_in_admin` TINYINT(1) NOT NULL DEFAULT 0, + `color` VARCHAR(8) DEFAULT NULL, + `ordering` INT NOT NULL DEFAULT 0, + `checked_out` INT UNSIGNED DEFAULT NULL, + `checked_out_time` DATETIME DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_published` (`published`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `#__mokosuiteclient_content_templates` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `alias` VARCHAR(100) NOT NULL DEFAULT '', + `name` VARCHAR(255) NOT NULL DEFAULT '', + `description` TEXT NOT NULL, + `category` VARCHAR(50) NOT NULL DEFAULT '', + `color` VARCHAR(8) DEFAULT NULL, + `template_data` MEDIUMTEXT NOT NULL, + `joomla_category_id` INT NOT NULL DEFAULT 0, + `access` INT UNSIGNED NOT NULL DEFAULT 1, + `published` TINYINT(1) NOT NULL DEFAULT 1, + `ordering` INT NOT NULL DEFAULT 0, + `checked_out` INT UNSIGNED DEFAULT NULL, + `checked_out_time` DATETIME DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_published` (`published`), + KEY `idx_alias` (`alias`), + KEY `idx_category` (`joomla_category_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/source/packages/com_mokosuiteclient/admin/src/View/Dashboard/HtmlView.php b/source/packages/com_mokosuiteclient/admin/src/View/Dashboard/HtmlView.php index 2a0fde1f..60ce45b3 100644 --- a/source/packages/com_mokosuiteclient/admin/src/View/Dashboard/HtmlView.php +++ b/source/packages/com_mokosuiteclient/admin/src/View/Dashboard/HtmlView.php @@ -44,15 +44,16 @@ class HtmlView extends BaseHtmlView $this->supportPinAvailable = $pinState['available']; $this->supportPin = $pinState['pin']; - // Detect Regular Labs data for import + // Detect Regular Labs data for import (source table must exist AND our destination table) try { $rlDb = \Joomla\CMS\Factory::getDbo(); $rlTables = $rlDb->getTableList(); $rlPrefix = $rlDb->getPrefix(); - $this->regularLabsAvailable = in_array($rlPrefix . 'conditions', $rlTables) - || in_array($rlPrefix . 'snippets', $rlTables) - || in_array($rlPrefix . 'rereplacer', $rlTables) - || in_array($rlPrefix . 'contenttemplater', $rlTables); + $this->regularLabsAvailable = + (in_array($rlPrefix . 'conditions', $rlTables) && in_array($rlPrefix . 'mokosuiteclient_conditions', $rlTables)) + || (in_array($rlPrefix . 'snippets', $rlTables) && in_array($rlPrefix . 'mokosuiteclient_snippets', $rlTables)) + || (in_array($rlPrefix . 'rereplacer', $rlTables) && in_array($rlPrefix . 'mokosuiteclient_replacements', $rlTables)) + || (in_array($rlPrefix . 'contenttemplater', $rlTables) && in_array($rlPrefix . 'mokosuiteclient_content_templates', $rlTables)); } catch (\Throwable $e) {} $this->recentLogins = $model->getRecentLogins(10);