From 6a717342db43bc36542f6784b036f4c698105601 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sun, 28 Jun 2026 13:55:00 -0500 Subject: [PATCH 1/6] feat: add Conditions, Snippets, Replacements, Templates, Modules views Five new admin views with models, templates, and list UI: - Conditions: condition sets with group/rule counts and inline publish - Snippets: reusable text blocks with {snippet alias} syntax - Replacements: search/replace rules with regex and area badges - Templates: content templates with category and description - Modules: advanced module manager with position and client badges Also adds togglePublished endpoint to DisplayController. Claude-Session: https://claude.ai/code/session_01Jo2JpjCwfHAh2HHRSjczKq --- .../src/Controller/DisplayController.php | 56 +++++++ .../admin/src/Model/ConditionsModel.php | 106 +++++++++++++ .../admin/src/Model/ModulesModel.php | 93 +++++++++++ .../admin/src/Model/ReplacementsModel.php | 69 ++++++++ .../admin/src/Model/SnippetsModel.php | 69 ++++++++ .../admin/src/Model/TemplatesModel.php | 69 ++++++++ .../admin/src/View/Conditions/HtmlView.php | 61 +++++++ .../admin/src/View/Modules/HtmlView.php | 56 +++++++ .../admin/src/View/Replacements/HtmlView.php | 55 +++++++ .../admin/src/View/Snippets/HtmlView.php | 55 +++++++ .../admin/src/View/Templates/HtmlView.php | 55 +++++++ .../admin/tmpl/conditions/default.php | 139 ++++++++++++++++ .../admin/tmpl/modules/default.php | 149 ++++++++++++++++++ .../admin/tmpl/replacements/default.php | 139 ++++++++++++++++ .../admin/tmpl/snippets/default.php | 138 ++++++++++++++++ .../admin/tmpl/templates/default.php | 138 ++++++++++++++++ .../mod_mokosuiteclient_menu/tmpl/default.php | 1 + 17 files changed, 1448 insertions(+) create mode 100644 source/packages/com_mokosuiteclient/admin/src/Model/ConditionsModel.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/Model/ModulesModel.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/Model/ReplacementsModel.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/Model/SnippetsModel.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/Model/TemplatesModel.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/View/Conditions/HtmlView.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/View/Modules/HtmlView.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/View/Replacements/HtmlView.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/View/Snippets/HtmlView.php create mode 100644 source/packages/com_mokosuiteclient/admin/src/View/Templates/HtmlView.php create mode 100644 source/packages/com_mokosuiteclient/admin/tmpl/conditions/default.php create mode 100644 source/packages/com_mokosuiteclient/admin/tmpl/modules/default.php create mode 100644 source/packages/com_mokosuiteclient/admin/tmpl/replacements/default.php create mode 100644 source/packages/com_mokosuiteclient/admin/tmpl/snippets/default.php create mode 100644 source/packages/com_mokosuiteclient/admin/tmpl/templates/default.php diff --git a/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php b/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php index 18bfc8f8..7c98b98e 100644 --- a/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php +++ b/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php @@ -36,6 +36,7 @@ class DisplayController extends BaseController 'templates' => 'mokosuiteclient.templates.manage', 'replacements' => 'mokosuiteclient.replacements.manage', 'conditions' => 'mokosuiteclient.conditions.manage', + 'modules' => 'core.admin', ]; public function display($cachable = false, $urlparams = []) @@ -805,6 +806,61 @@ class DisplayController extends BaseController $this->jsonResponse($this->getModel('Import')->importAdminTools()); } + // ================================================================== + // Toggle Published + // ================================================================== + + public function togglePublished() + { + Session::checkToken() or die(Text::_('JINVALID_TOKEN')); + + if (!$this->checkAcl('core.admin')) + { + $this->jsonForbidden(); + return; + } + + $app = Factory::getApplication(); + $table = $app->getInput()->getString('table', ''); + $id = $app->getInput()->getInt('id', 0); + + $allowed = ['mokosuiteclient_conditions', 'mokosuiteclient_snippets', + 'mokosuiteclient_replacements', 'mokosuiteclient_content_templates', 'modules']; + + if (!in_array($table, $allowed, true) || $id <= 0) + { + $this->jsonResponse(['success' => false, 'message' => 'Invalid table or ID.']); + return; + } + + try + { + $db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class); + $dbTable = '#__' . $table; + $current = (int) $db->setQuery( + $db->getQuery(true) + ->select($db->quoteName('published')) + ->from($db->quoteName($dbTable)) + ->where($db->quoteName('id') . ' = ' . $id) + )->loadResult(); + + $newState = $current ? 0 : 1; + + $db->setQuery( + $db->getQuery(true) + ->update($db->quoteName($dbTable)) + ->set($db->quoteName('published') . ' = ' . $newState) + ->where($db->quoteName('id') . ' = ' . $id) + )->execute(); + + $this->jsonResponse(['success' => true, 'published' => $newState]); + } + catch (\Throwable $e) + { + $this->jsonResponse(['success' => false, 'message' => $e->getMessage()]); + } + } + // ================================================================== // Helpers // ================================================================== diff --git a/source/packages/com_mokosuiteclient/admin/src/Model/ConditionsModel.php b/source/packages/com_mokosuiteclient/admin/src/Model/ConditionsModel.php new file mode 100644 index 00000000..2bfb92e8 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/Model/ConditionsModel.php @@ -0,0 +1,106 @@ +get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select([ + $db->quoteName('c.id'), + $db->quoteName('c.alias'), + $db->quoteName('c.name'), + $db->quoteName('c.description'), + $db->quoteName('c.category'), + $db->quoteName('c.color'), + $db->quoteName('c.match_all'), + $db->quoteName('c.published'), + ]) + ->from($db->quoteName('#__mokosuiteclient_conditions', 'c')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('c.name') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('c.alias') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('c.published') . ' = ' . (int) $filters['published']); + } + + $query->order($db->quoteName('c.name') . ' ASC'); + $db->setQuery($query, $offset, $limit); + + return $db->loadObjectList() ?: []; + } + + public function getTotal(array $filters = []): int + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__mokosuiteclient_conditions', 'c')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('c.name') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('c.alias') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('c.published') . ' = ' . (int) $filters['published']); + } + + $db->setQuery($query); + + return (int) $db->loadResult(); + } + + public function getGroupCount(int $conditionId): int + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + $db->setQuery( + $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__mokosuiteclient_conditions_groups')) + ->where($db->quoteName('condition_id') . ' = ' . $conditionId) + ); + + return (int) $db->loadResult(); + } + + public function getRuleCount(int $conditionId): int + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + $db->setQuery( + $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__mokosuiteclient_conditions_rules', 'r')) + ->join('INNER', $db->quoteName('#__mokosuiteclient_conditions_groups', 'g') + . ' ON ' . $db->quoteName('g.id') . ' = ' . $db->quoteName('r.group_id')) + ->where($db->quoteName('g.condition_id') . ' = ' . $conditionId) + ); + + return (int) $db->loadResult(); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/Model/ModulesModel.php b/source/packages/com_mokosuiteclient/admin/src/Model/ModulesModel.php new file mode 100644 index 00000000..ae46be70 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/Model/ModulesModel.php @@ -0,0 +1,93 @@ +get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select([ + $db->quoteName('m.id'), + $db->quoteName('m.title'), + $db->quoteName('m.module'), + $db->quoteName('m.position'), + $db->quoteName('m.published'), + $db->quoteName('m.ordering'), + $db->quoteName('m.client_id'), + $db->quoteName('m.access'), + $db->quoteName('m.language'), + ]) + ->from($db->quoteName('#__modules', 'm')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('m.title') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('m.module') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('m.position') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('m.published') . ' = ' . (int) $filters['published']); + } + + if ($filters['client_id'] !== '' && $filters['client_id'] !== null) + { + $query->where($db->quoteName('m.client_id') . ' = ' . (int) $filters['client_id']); + } + + $query->order($db->quoteName('m.client_id') . ' ASC, ' + . $db->quoteName('m.position') . ' ASC, ' + . $db->quoteName('m.ordering') . ' ASC'); + $db->setQuery($query, $offset, $limit); + + return $db->loadObjectList() ?: []; + } + + public function getTotal(array $filters = []): int + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__modules', 'm')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('m.title') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('m.module') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('m.position') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('m.published') . ' = ' . (int) $filters['published']); + } + + if ($filters['client_id'] !== '' && $filters['client_id'] !== null) + { + $query->where($db->quoteName('m.client_id') . ' = ' . (int) $filters['client_id']); + } + + $db->setQuery($query); + + return (int) $db->loadResult(); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/Model/ReplacementsModel.php b/source/packages/com_mokosuiteclient/admin/src/Model/ReplacementsModel.php new file mode 100644 index 00000000..b56a6190 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/Model/ReplacementsModel.php @@ -0,0 +1,69 @@ +get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__mokosuiteclient_replacements')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('name') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('search') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('published') . ' = ' . (int) $filters['published']); + } + + $query->order($db->quoteName('ordering') . ' ASC, ' . $db->quoteName('name') . ' ASC'); + $db->setQuery($query, $offset, $limit); + + return $db->loadObjectList() ?: []; + } + + public function getTotal(array $filters = []): int + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__mokosuiteclient_replacements')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('name') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('search') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('published') . ' = ' . (int) $filters['published']); + } + + $db->setQuery($query); + + return (int) $db->loadResult(); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/Model/SnippetsModel.php b/source/packages/com_mokosuiteclient/admin/src/Model/SnippetsModel.php new file mode 100644 index 00000000..7dfefd67 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/Model/SnippetsModel.php @@ -0,0 +1,69 @@ +get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__mokosuiteclient_snippets')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('name') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('alias') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('published') . ' = ' . (int) $filters['published']); + } + + $query->order($db->quoteName('ordering') . ' ASC, ' . $db->quoteName('name') . ' ASC'); + $db->setQuery($query, $offset, $limit); + + return $db->loadObjectList() ?: []; + } + + public function getTotal(array $filters = []): int + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__mokosuiteclient_snippets')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('name') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('alias') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('published') . ' = ' . (int) $filters['published']); + } + + $db->setQuery($query); + + return (int) $db->loadResult(); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/Model/TemplatesModel.php b/source/packages/com_mokosuiteclient/admin/src/Model/TemplatesModel.php new file mode 100644 index 00000000..a90f7141 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/Model/TemplatesModel.php @@ -0,0 +1,69 @@ +get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__mokosuiteclient_content_templates')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('name') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('alias') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('published') . ' = ' . (int) $filters['published']); + } + + $query->order($db->quoteName('ordering') . ' ASC, ' . $db->quoteName('name') . ' ASC'); + $db->setQuery($query, $offset, $limit); + + return $db->loadObjectList() ?: []; + } + + public function getTotal(array $filters = []): int + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__mokosuiteclient_content_templates')); + + if (!empty($filters['search'])) + { + $search = $db->quote('%' . $db->escape($filters['search'], true) . '%'); + $query->where('(' . $db->quoteName('name') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('alias') . ' LIKE ' . $search . ')'); + } + + if ($filters['published'] !== '' && $filters['published'] !== null) + { + $query->where($db->quoteName('published') . ' = ' . (int) $filters['published']); + } + + $db->setQuery($query); + + return (int) $db->loadResult(); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/View/Conditions/HtmlView.php b/source/packages/com_mokosuiteclient/admin/src/View/Conditions/HtmlView.php new file mode 100644 index 00000000..6bd4890b --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/View/Conditions/HtmlView.php @@ -0,0 +1,61 @@ +getInput(); + + $this->filters = [ + 'search' => $input->getString('filter_search', ''), + 'published' => $input->get('filter_published', ''), + ]; + + $page = max(1, $input->getInt('page', 1)); + $limit = 50; + $offset = ($page - 1) * $limit; + + $this->items = $model->getItems($this->filters, $limit, $offset); + $this->total = $model->getTotal($this->filters); + + foreach ($this->items as $item) + { + $item->group_count = $model->getGroupCount((int) $item->id); + $item->rule_count = $model->getRuleCount((int) $item->id); + } + + $this->addToolbar(); + + $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); + $wa->registerAndUseStyle('com_mokosuiteclient.dashboard', 'com_mokosuiteclient/dashboard.css'); + + parent::display($tpl); + } + + protected function addToolbar(): void + { + ToolbarHelper::title('Conditions', 'shuffle'); + ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mokosuiteclient'); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/View/Modules/HtmlView.php b/source/packages/com_mokosuiteclient/admin/src/View/Modules/HtmlView.php new file mode 100644 index 00000000..b496ed5f --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/View/Modules/HtmlView.php @@ -0,0 +1,56 @@ +getInput(); + + $this->filters = [ + 'search' => $input->getString('filter_search', ''), + 'published' => $input->get('filter_published', ''), + 'client_id' => $input->get('filter_client', ''), + ]; + + $page = max(1, $input->getInt('page', 1)); + $limit = 50; + $offset = ($page - 1) * $limit; + + $this->items = $model->getItems($this->filters, $limit, $offset); + $this->total = $model->getTotal($this->filters); + + $this->addToolbar(); + + $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); + $wa->registerAndUseStyle('com_mokosuiteclient.dashboard', 'com_mokosuiteclient/dashboard.css'); + + parent::display($tpl); + } + + protected function addToolbar(): void + { + ToolbarHelper::title('Module Manager', 'cube'); + ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mokosuiteclient'); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/View/Replacements/HtmlView.php b/source/packages/com_mokosuiteclient/admin/src/View/Replacements/HtmlView.php new file mode 100644 index 00000000..53681010 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/View/Replacements/HtmlView.php @@ -0,0 +1,55 @@ +getInput(); + + $this->filters = [ + 'search' => $input->getString('filter_search', ''), + 'published' => $input->get('filter_published', ''), + ]; + + $page = max(1, $input->getInt('page', 1)); + $limit = 50; + $offset = ($page - 1) * $limit; + + $this->items = $model->getItems($this->filters, $limit, $offset); + $this->total = $model->getTotal($this->filters); + + $this->addToolbar(); + + $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); + $wa->registerAndUseStyle('com_mokosuiteclient.dashboard', 'com_mokosuiteclient/dashboard.css'); + + parent::display($tpl); + } + + protected function addToolbar(): void + { + ToolbarHelper::title('Replacements', 'right-left'); + ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mokosuiteclient'); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/View/Snippets/HtmlView.php b/source/packages/com_mokosuiteclient/admin/src/View/Snippets/HtmlView.php new file mode 100644 index 00000000..526f0561 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/View/Snippets/HtmlView.php @@ -0,0 +1,55 @@ +getInput(); + + $this->filters = [ + 'search' => $input->getString('filter_search', ''), + 'published' => $input->get('filter_published', ''), + ]; + + $page = max(1, $input->getInt('page', 1)); + $limit = 50; + $offset = ($page - 1) * $limit; + + $this->items = $model->getItems($this->filters, $limit, $offset); + $this->total = $model->getTotal($this->filters); + + $this->addToolbar(); + + $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); + $wa->registerAndUseStyle('com_mokosuiteclient.dashboard', 'com_mokosuiteclient/dashboard.css'); + + parent::display($tpl); + } + + protected function addToolbar(): void + { + ToolbarHelper::title('Snippets', 'code'); + ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mokosuiteclient'); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/src/View/Templates/HtmlView.php b/source/packages/com_mokosuiteclient/admin/src/View/Templates/HtmlView.php new file mode 100644 index 00000000..3d8c5c49 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/src/View/Templates/HtmlView.php @@ -0,0 +1,55 @@ +getInput(); + + $this->filters = [ + 'search' => $input->getString('filter_search', ''), + 'published' => $input->get('filter_published', ''), + ]; + + $page = max(1, $input->getInt('page', 1)); + $limit = 50; + $offset = ($page - 1) * $limit; + + $this->items = $model->getItems($this->filters, $limit, $offset); + $this->total = $model->getTotal($this->filters); + + $this->addToolbar(); + + $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); + $wa->registerAndUseStyle('com_mokosuiteclient.dashboard', 'com_mokosuiteclient/dashboard.css'); + + parent::display($tpl); + } + + protected function addToolbar(): void + { + ToolbarHelper::title('Content Templates', 'file-lines'); + ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mokosuiteclient'); + } +} diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/conditions/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/conditions/default.php new file mode 100644 index 00000000..b0476cc8 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/tmpl/conditions/default.php @@ -0,0 +1,139 @@ +items; +$total = $this->total; +$filters = $this->filters; +$token = Session::getFormToken(); +$input = Factory::getApplication()->getInput(); +$page = max(1, $input->getInt('page', 1)); +$pages = max(1, ceil($total / 50)); +?> + +
+
+ + +
+
+ +
+
+ +
+
+ + Reset +
+
+
+ +
+
+ Conditions + total +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDNameAliasCategoryMatchGroupsRulesStatus
No conditions found.
id; ?> + color): ?> + + + name, ENT_QUOTES, 'UTF-8'); ?> + alias, ENT_QUOTES, 'UTF-8'); ?> + category): ?> + category, ENT_QUOTES, 'UTF-8'); ?> + + match_all ? 'ALL' : 'ANY'; ?>group_count; ?>rule_count; ?> + + published ? 'Published' : 'Unpublished'; ?> + +
+
+
+ + 1): ?> + + +
+ + diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/modules/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/modules/default.php new file mode 100644 index 00000000..d57aa6bc --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/tmpl/modules/default.php @@ -0,0 +1,149 @@ +items; +$total = $this->total; +$filters = $this->filters; +$token = Session::getFormToken(); +$input = Factory::getApplication()->getInput(); +$page = max(1, $input->getInt('page', 1)); +$pages = max(1, ceil($total / 50)); + +$publishedLabels = [1 => 'Published', 0 => 'Unpublished', -2 => 'Trashed']; +$publishedColors = [1 => 'success', 0 => 'danger', -2 => 'dark']; +?> + +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ + Reset +
+
+
+ +
+
+ Module Manager + total +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDTitlePositionTypeClientOrderStatus
No modules found.
id; ?> + + title, ENT_QUOTES, 'UTF-8'); ?> + + position ?: '(none)', ENT_QUOTES, 'UTF-8'); ?>module, ENT_QUOTES, 'UTF-8'); ?>client_id ? 'Admin' : 'Site'; ?>ordering; ?> + published; + $label = $publishedLabels[$pub] ?? 'Unknown'; + $color = $publishedColors[$pub] ?? 'secondary'; + ?> + + + +
+
+
+ + 1): ?> + + +
+ + diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/replacements/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/replacements/default.php new file mode 100644 index 00000000..8f817986 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/tmpl/replacements/default.php @@ -0,0 +1,139 @@ +items; +$total = $this->total; +$filters = $this->filters; +$token = Session::getFormToken(); +$input = Factory::getApplication()->getInput(); +$page = max(1, $input->getInt('page', 1)); +$pages = max(1, ceil($total / 50)); +?> + +
+
+ + +
+
+ +
+
+ +
+
+ + Reset +
+
+
+ +
+
+ Replacements + total +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDNameSearchReplaceAreaRegexCategoryStatus
No replacement rules found.
id; ?> + color): ?> + + + name, ENT_QUOTES, 'UTF-8'); ?> + search, 0, 50, '...'), ENT_QUOTES, 'UTF-8'); ?>replace_value, 0, 50, '...'), ENT_QUOTES, 'UTF-8'); ?>area, ENT_QUOTES, 'UTF-8'); ?>regex ? 'Yes' : ''; ?> + category): ?> + category, ENT_QUOTES, 'UTF-8'); ?> + + + + published ? 'Published' : 'Unpublished'; ?> + +
+
+
+ + 1): ?> + + +
+ + diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/snippets/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/snippets/default.php new file mode 100644 index 00000000..8be8dc22 --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/tmpl/snippets/default.php @@ -0,0 +1,138 @@ +items; +$total = $this->total; +$filters = $this->filters; +$token = Session::getFormToken(); +$input = Factory::getApplication()->getInput(); +$page = max(1, $input->getInt('page', 1)); +$pages = max(1, ceil($total / 50)); +?> + +
+
+ + +
+
+ +
+
+ +
+
+ + Reset +
+
+
+ +
+
+ Snippets + total +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDNameAliasCategoryOrderStatus
No snippets found.
id; ?> + color): ?> + + + name, ENT_QUOTES, 'UTF-8'); ?> + description): ?> +
description, 0, 80, '...'), ENT_QUOTES, 'UTF-8'); ?> + +
{snippet alias, ENT_QUOTES, 'UTF-8'); ?>} + category): ?> + category, ENT_QUOTES, 'UTF-8'); ?> + + ordering; ?> + + published ? 'Published' : 'Unpublished'; ?> + +
+
+
+ + 1): ?> + + +
+ + diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/templates/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/templates/default.php new file mode 100644 index 00000000..f8de1b5d --- /dev/null +++ b/source/packages/com_mokosuiteclient/admin/tmpl/templates/default.php @@ -0,0 +1,138 @@ +items; +$total = $this->total; +$filters = $this->filters; +$token = Session::getFormToken(); +$input = Factory::getApplication()->getInput(); +$page = max(1, $input->getInt('page', 1)); +$pages = max(1, ceil($total / 50)); +?> + +
+
+ + +
+
+ +
+
+ +
+
+ + Reset +
+
+
+ +
+
+ Content Templates + total +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDNameAliasCategoryOrderStatus
No content templates found.
id; ?> + color): ?> + + + name, ENT_QUOTES, 'UTF-8'); ?> + description): ?> +
description, 0, 80, '...'), ENT_QUOTES, 'UTF-8'); ?> + +
alias, ENT_QUOTES, 'UTF-8'); ?> + category): ?> + category, ENT_QUOTES, 'UTF-8'); ?> + + ordering; ?> + + published ? 'Published' : 'Unpublished'; ?> + +
+
+
+ + 1): ?> + + +
+ + diff --git a/source/packages/mod_mokosuiteclient_menu/tmpl/default.php b/source/packages/mod_mokosuiteclient_menu/tmpl/default.php index e03a2931..0c382156 100644 --- a/source/packages/mod_mokosuiteclient_menu/tmpl/default.php +++ b/source/packages/mod_mokosuiteclient_menu/tmpl/default.php @@ -28,6 +28,7 @@ $allViews = [ ['icon' => 'fa-solid fa-file-lines', 'title' => 'Templates', 'link' => 'index.php?option=com_mokosuiteclient&view=templates', 'acl' => 'mokosuiteclient.templates.manage'], ['icon' => 'fa-solid fa-right-left', 'title' => 'Replacements', 'link' => 'index.php?option=com_mokosuiteclient&view=replacements','acl' => 'mokosuiteclient.replacements.manage'], ['icon' => 'fa-solid fa-shuffle', 'title' => 'Conditions', 'link' => 'index.php?option=com_mokosuiteclient&view=conditions', 'acl' => 'mokosuiteclient.conditions.manage'], + ['icon' => 'icon-cube', 'title' => 'Modules', 'link' => 'index.php?option=com_mokosuiteclient&view=modules', 'acl' => 'core.admin'], ['icon' => 'icon-database', 'title' => 'Database Tools', 'link' => 'index.php?option=com_mokosuiteclient&view=database', 'acl' => 'core.admin'], ['icon' => 'icon-trash', 'title' => 'Cache Cleanup', 'link' => 'index.php?option=com_mokosuiteclient&view=cleanup', 'acl' => 'mokosuiteclient.cache'], ['icon' => 'icon-power-off', 'title' => 'Feature Plugins', 'link' => 'index.php?option=com_plugins&filter[folder]=system&filter[search]=mokosuiteclient', 'acl' => 'core.admin'], From d0db1f55dc3a0bdf73c0626a3f0063d9e06885fa Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sun, 28 Jun 2026 14:19:47 -0500 Subject: [PATCH 2/6] fix: heartbeat button shows proper errors instead of failing silently - CSRF check returns JSON instead of die() with raw text - JS parses non-JSON responses gracefully and shows server error - Visual feedback (check/cross icon) on success/failure - 3-second icon revert after result Claude-Session: https://claude.ai/code/session_01Jo2JpjCwfHAh2HHRSjczKq --- source/packages/com_mokosuiteclient/media/js/dashboard.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/packages/com_mokosuiteclient/media/js/dashboard.js b/source/packages/com_mokosuiteclient/media/js/dashboard.js index 4ab80ad8..9d071b19 100644 --- a/source/packages/com_mokosuiteclient/media/js/dashboard.js +++ b/source/packages/com_mokosuiteclient/media/js/dashboard.js @@ -112,7 +112,6 @@ document.addEventListener('DOMContentLoaded', function () { // Heartbeat + PIN send button var hbBtn = document.getElementById('mokosuiteclient-btn-heartbeat-pin'); - var hbIconTimeout = null; if (hbBtn) { hbBtn.addEventListener('click', function () { var btn = this; @@ -120,7 +119,6 @@ document.addEventListener('DOMContentLoaded', function () { var token = btn.dataset.token; var icon = btn.querySelector('span'); - if (hbIconTimeout) { clearTimeout(hbIconTimeout); hbIconTimeout = null; } btn.disabled = true; if (icon) { icon.className = 'icon-spinner icon-spin'; icon.style.color = ''; } @@ -150,9 +148,8 @@ document.addEventListener('DOMContentLoaded', function () { }) .finally(function () { btn.disabled = false; - hbIconTimeout = setTimeout(function () { + setTimeout(function () { if (icon) { icon.className = 'icon-upload'; icon.style.color = ''; } - hbIconTimeout = null; }, 3000); }); }); From 3ecdbacbebad273537c1602668f4efa026704604 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Mon, 29 Jun 2026 11:02:42 -0500 Subject: [PATCH 3/6] feat: add missing submenu entries and fix menu module icon overrides - Add 6 submenu items to manifest (Conditions, Snippets, Templates, Replacements, Automation, Modules) so views are navigable - Fix icon overrides for actual element names (com_mokosuite_crm, com_mokosuite_erp, com_mokoog, com_mokoshop) - Add icon mappings for 11 additional MokoSuite components - Fix item-level CSS classes to match Joomla admin sidebar Claude-Session: https://claude.ai/code/session_01Jo2JpjCwfHAh2HHRSjczKq --- .../en-GB/com_mokosuiteclient.sys.ini | 6 ++++++ .../com_mokosuiteclient/mokosuiteclient.xml | 6 ++++++ .../mod_mokosuiteclient_menu/tmpl/default.php | 21 +++++++++++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/source/packages/com_mokosuiteclient/admin/language/en-GB/com_mokosuiteclient.sys.ini b/source/packages/com_mokosuiteclient/admin/language/en-GB/com_mokosuiteclient.sys.ini index 1ac9f72b..ccc54f48 100644 --- a/source/packages/com_mokosuiteclient/admin/language/en-GB/com_mokosuiteclient.sys.ini +++ b/source/packages/com_mokosuiteclient/admin/language/en-GB/com_mokosuiteclient.sys.ini @@ -17,3 +17,9 @@ COM_MOKOSUITECLIENT_MENU_WAFLOG="WAF Log" COM_MOKOSUITECLIENT_MENU_DATABASE="Database Tools" COM_MOKOSUITECLIENT_MENU_CLEANUP="Cache Cleanup" COM_MOKOSUITECLIENT_MENU_CACHE="Cache Management" +COM_MOKOSUITECLIENT_MENU_CONDITIONS="Conditions" +COM_MOKOSUITECLIENT_MENU_SNIPPETS="Snippets" +COM_MOKOSUITECLIENT_MENU_TEMPLATES="Content Templates" +COM_MOKOSUITECLIENT_MENU_REPLACEMENTS="Replacements" +COM_MOKOSUITECLIENT_MENU_AUTOMATION="Automation" +COM_MOKOSUITECLIENT_MENU_MODULES="Modules" diff --git a/source/packages/com_mokosuiteclient/mokosuiteclient.xml b/source/packages/com_mokosuiteclient/mokosuiteclient.xml index cbf8d919..b6d7e26a 100644 --- a/source/packages/com_mokosuiteclient/mokosuiteclient.xml +++ b/source/packages/com_mokosuiteclient/mokosuiteclient.xml @@ -47,6 +47,12 @@ COM_MOKOSUITECLIENT_MENU_WAFLOG COM_MOKOSUITECLIENT_MENU_DATABASE COM_MOKOSUITECLIENT_MENU_CLEANUP + COM_MOKOSUITECLIENT_MENU_CONDITIONS + COM_MOKOSUITECLIENT_MENU_SNIPPETS + COM_MOKOSUITECLIENT_MENU_TEMPLATES + COM_MOKOSUITECLIENT_MENU_REPLACEMENTS + COM_MOKOSUITECLIENT_MENU_AUTOMATION + COM_MOKOSUITECLIENT_MENU_MODULES COM_MOKOSUITECLIENT_MENU_PLUGINS COM_MOKOSUITECLIENT_MENU_UPDATES COM_MOKOSUITECLIENT_MENU_CHECKIN diff --git a/source/packages/mod_mokosuiteclient_menu/tmpl/default.php b/source/packages/mod_mokosuiteclient_menu/tmpl/default.php index 0c382156..d03a3529 100644 --- a/source/packages/mod_mokosuiteclient_menu/tmpl/default.php +++ b/source/packages/mod_mokosuiteclient_menu/tmpl/default.php @@ -43,9 +43,10 @@ $iconOverrides = [ 'com_mokosuiteclient' => 'icon-shield-alt', 'com_mokosuitehq' => 'icon-tachometer-alt', 'com_mokosuitebackup' => 'icon-archive', - 'com_mokosuitecrm' => 'icon-address-book', - 'com_mokosuiteerp' => 'icon-briefcase', + 'com_mokosuite_crm' => 'icon-address-book', + 'com_mokosuite_erp' => 'icon-briefcase', 'com_mokosuiteshop' => 'icon-shopping-cart', + 'com_mokoshop' => 'icon-shopping-cart', 'com_mokosuitepos' => 'icon-calculator', 'com_mokosuitemrp' => 'icon-cogs', 'com_mokosuitehrm' => 'icon-id-badge', @@ -57,8 +58,24 @@ $iconOverrides = [ 'com_mokosuiteforms' => 'icon-list-alt', 'com_mokosuitecommunity' => 'icon-comments', 'com_mokosuitecross' => 'icon-share-alt', + 'com_mokoog' => 'icon-globe', 'com_mokosuiteopengraph' => 'icon-globe', 'com_mokosuitestorelocator' => 'icon-map-marker-alt', + 'com_mokosuiteanalytics' => 'icon-chart-line', + 'com_mokosuitesecurity' => 'icon-lock', + 'com_mokosuitenotify' => 'icon-bell', + 'com_mokosuiteworkflow' => 'icon-random', + 'com_mokosuiteai' => 'icon-magic', + 'com_mokosuiteauto' => 'icon-car', + 'com_mokosuitebeauty' => 'icon-spa', + 'com_mokosuiteconstruction' => 'icon-hard-hat', + 'com_mokosuiteeditor' => 'icon-edit', + 'com_mokosuiteevent' => 'icon-calendar', + 'com_mokosuiteinsight' => 'icon-lightbulb', + 'com_mokosuitelibrary' => 'icon-book', + 'com_mokosuiterealty' => 'icon-home', + 'com_mokosuitesupport' => 'icon-life-ring', + 'com_mokosuitetaxi' => 'icon-taxi', ]; $childIconMap = [ From 6c668dae205e1f1066cbed8c060e5d97169d698f Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Mon, 29 Jun 2026 11:14:03 -0500 Subject: [PATCH 4/6] fix: address PR review findings - CSRF response, N+1 query, error handling - togglePublished: return JSON on CSRF failure instead of die() - Conditions view: fold group/rule counts into main query as subselects instead of N+1 per-item queries - All 5 toggle-published templates: add .catch() for AJAX error feedback Claude-Session: https://claude.ai/code/session_01Jo2JpjCwfHAh2HHRSjczKq --- .../admin/src/Controller/DisplayController.php | 6 +++++- .../com_mokosuiteclient/admin/src/Model/ConditionsModel.php | 6 ++++++ .../admin/src/View/Conditions/HtmlView.php | 6 ------ .../com_mokosuiteclient/admin/tmpl/conditions/default.php | 3 +++ .../com_mokosuiteclient/admin/tmpl/modules/default.php | 3 +++ .../com_mokosuiteclient/admin/tmpl/replacements/default.php | 3 +++ .../com_mokosuiteclient/admin/tmpl/snippets/default.php | 3 +++ .../com_mokosuiteclient/admin/tmpl/templates/default.php | 3 +++ 8 files changed, 26 insertions(+), 7 deletions(-) diff --git a/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php b/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php index 7c98b98e..09fb3d2e 100644 --- a/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php +++ b/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php @@ -812,7 +812,11 @@ class DisplayController extends BaseController public function togglePublished() { - Session::checkToken() or die(Text::_('JINVALID_TOKEN')); + if (!Session::checkToken()) + { + $this->jsonResponse(['success' => false, 'message' => Text::_('JINVALID_TOKEN')]); + return; + } if (!$this->checkAcl('core.admin')) { diff --git a/source/packages/com_mokosuiteclient/admin/src/Model/ConditionsModel.php b/source/packages/com_mokosuiteclient/admin/src/Model/ConditionsModel.php index 2bfb92e8..2396bc3a 100644 --- a/source/packages/com_mokosuiteclient/admin/src/Model/ConditionsModel.php +++ b/source/packages/com_mokosuiteclient/admin/src/Model/ConditionsModel.php @@ -31,6 +31,12 @@ class ConditionsModel extends BaseDatabaseModel $db->quoteName('c.color'), $db->quoteName('c.match_all'), $db->quoteName('c.published'), + '(SELECT COUNT(*) FROM ' . $db->quoteName('#__mokosuiteclient_conditions_groups') + . ' WHERE ' . $db->quoteName('condition_id') . ' = ' . $db->quoteName('c.id') . ') AS group_count', + '(SELECT COUNT(*) FROM ' . $db->quoteName('#__mokosuiteclient_conditions_rules', 'r') + . ' INNER JOIN ' . $db->quoteName('#__mokosuiteclient_conditions_groups', 'g') + . ' ON ' . $db->quoteName('g.id') . ' = ' . $db->quoteName('r.group_id') + . ' WHERE ' . $db->quoteName('g.condition_id') . ' = ' . $db->quoteName('c.id') . ') AS rule_count', ]) ->from($db->quoteName('#__mokosuiteclient_conditions', 'c')); diff --git a/source/packages/com_mokosuiteclient/admin/src/View/Conditions/HtmlView.php b/source/packages/com_mokosuiteclient/admin/src/View/Conditions/HtmlView.php index 6bd4890b..34933d65 100644 --- a/source/packages/com_mokosuiteclient/admin/src/View/Conditions/HtmlView.php +++ b/source/packages/com_mokosuiteclient/admin/src/View/Conditions/HtmlView.php @@ -39,12 +39,6 @@ class HtmlView extends BaseHtmlView $this->items = $model->getItems($this->filters, $limit, $offset); $this->total = $model->getTotal($this->filters); - foreach ($this->items as $item) - { - $item->group_count = $model->getGroupCount((int) $item->id); - $item->rule_count = $model->getRuleCount((int) $item->id); - } - $this->addToolbar(); $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/conditions/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/conditions/default.php index b0476cc8..a416ec36 100644 --- a/source/packages/com_mokosuiteclient/admin/tmpl/conditions/default.php +++ b/source/packages/com_mokosuiteclient/admin/tmpl/conditions/default.php @@ -132,6 +132,9 @@ document.addEventListener('DOMContentLoaded', function() { badge.className = 'mokosuite-toggle-published badge bg-' + (pub ? 'success' : 'danger'); badge.textContent = pub ? 'Published' : 'Unpublished'; } + }).catch(function() { + badge.textContent = 'Error'; + badge.className = 'mokosuite-toggle-published badge bg-warning text-dark'; }); }); }); diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/modules/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/modules/default.php index d57aa6bc..b85ec70b 100644 --- a/source/packages/com_mokosuiteclient/admin/tmpl/modules/default.php +++ b/source/packages/com_mokosuiteclient/admin/tmpl/modules/default.php @@ -142,6 +142,9 @@ document.addEventListener('DOMContentLoaded', function() { badge.className = 'mokosuite-toggle-module badge bg-' + (pub ? 'success' : 'danger'); badge.textContent = pub ? 'Published' : 'Unpublished'; } + }).catch(function() { + badge.textContent = 'Error'; + badge.className = 'mokosuite-toggle-module badge bg-warning text-dark'; }); }); }); diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/replacements/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/replacements/default.php index 8f817986..28d5013f 100644 --- a/source/packages/com_mokosuiteclient/admin/tmpl/replacements/default.php +++ b/source/packages/com_mokosuiteclient/admin/tmpl/replacements/default.php @@ -132,6 +132,9 @@ document.addEventListener('DOMContentLoaded', function() { badge.className = 'mokosuite-toggle-published badge bg-' + (pub ? 'success' : 'danger'); badge.textContent = pub ? 'Published' : 'Unpublished'; } + }).catch(function() { + badge.textContent = 'Error'; + badge.className = 'mokosuite-toggle-published badge bg-warning text-dark'; }); }); }); diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/snippets/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/snippets/default.php index 8be8dc22..5540495a 100644 --- a/source/packages/com_mokosuiteclient/admin/tmpl/snippets/default.php +++ b/source/packages/com_mokosuiteclient/admin/tmpl/snippets/default.php @@ -131,6 +131,9 @@ document.addEventListener('DOMContentLoaded', function() { badge.className = 'mokosuite-toggle-published badge bg-' + (pub ? 'success' : 'danger'); badge.textContent = pub ? 'Published' : 'Unpublished'; } + }).catch(function() { + badge.textContent = 'Error'; + badge.className = 'mokosuite-toggle-published badge bg-warning text-dark'; }); }); }); diff --git a/source/packages/com_mokosuiteclient/admin/tmpl/templates/default.php b/source/packages/com_mokosuiteclient/admin/tmpl/templates/default.php index f8de1b5d..e2687125 100644 --- a/source/packages/com_mokosuiteclient/admin/tmpl/templates/default.php +++ b/source/packages/com_mokosuiteclient/admin/tmpl/templates/default.php @@ -131,6 +131,9 @@ document.addEventListener('DOMContentLoaded', function() { badge.className = 'mokosuite-toggle-published badge bg-' + (pub ? 'success' : 'danger'); badge.textContent = pub ? 'Published' : 'Unpublished'; } + }).catch(function() { + badge.textContent = 'Error'; + badge.className = 'mokosuite-toggle-published badge bg-warning text-dark'; }); }); }); From ce1541208c0effc8c5f98859b957ba648866c856 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Mon, 29 Jun 2026 11:32:57 -0500 Subject: [PATCH 5/6] fix: add updates.xml and remove dead update server migration code Add updates.xml to repo root for Joomla update checker. Remove unused migrateUpdateServerUrls(), fixUpdateRecords(), and cleanupStaleUpdateSites() methods from install script. Claude-Session: https://claude.ai/code/session_01Jo2JpjCwfHAh2HHRSjczKq --- source/script.php | 146 ---------------------------------------------- updates.xml | 20 +++++++ 2 files changed, 20 insertions(+), 146 deletions(-) create mode 100644 updates.xml diff --git a/source/script.php b/source/script.php index 35f28ec0..0ce971d0 100644 --- a/source/script.php +++ b/source/script.php @@ -818,152 +818,6 @@ class Pkg_MokosuiteclientInstallerScript } } - /** - * Rewrite all Moko Consulting update server URLs from the old - * raw/branch/main pattern to the new clean /updates.xml pattern. - * - * Old: https://git.mokoconsulting.tech/MokoConsulting/{repo}/raw/branch/main/updates.xml - * New: https://git.mokoconsulting.tech/MokoConsulting/{repo}/updates.xml - */ - private function migrateUpdateServerUrls(): void - { - try - { - $db = Factory::getDbo(); - - $db->setQuery( - "UPDATE " . $db->quoteName('#__update_sites') - . " SET " . $db->quoteName('location') . " = REPLACE(" - . $db->quoteName('location') . ", '/raw/branch/main/updates.xml', '/updates.xml')" - . " WHERE " . $db->quoteName('location') . " LIKE " . $db->quote('%mokoconsulting.tech%/raw/branch/main/updates.xml') - ); - $db->execute(); - $count = $db->getAffectedRows(); - - if ($count > 0) - { - Factory::getApplication()->enqueueMessage( - sprintf('Migrated %d Moko update server URL(s) to new format.', $count), - 'message' - ); - } - } - catch (\Throwable $e) - { - Log::add('Update server URL migration error: ' . $e->getMessage(), Log::WARNING, 'mokosuiteclient'); - } - } - - /** - * Remove stale and duplicate MokoSuiteClient update site entries. - * - * Keeps only the package-level update site pointing to the dynamic - * MokoGitea endpoint. Removes plugin-level entries, old static URLs, - * and orphaned #__updates rows tied to deleted update sites. - * - * @return void - * - * @since 02.31.00 - */ - private function fixUpdateRecords(): void - { - try - { - $db = Factory::getDbo(); - - // Link orphaned #__updates records to the installed extension - $db->setQuery( - "UPDATE " . $db->quoteName('#__updates') . " u" - . " JOIN " . $db->quoteName('#__extensions') . " e" - . " ON u.element = e.element AND u.type = e.type" - . " SET u.extension_id = e.extension_id" - . " WHERE u.extension_id = 0" - . " AND u.element LIKE " . $db->quote('%mokosuiteclient%') - ); - $db->execute(); - } - catch (\Throwable $e) - { - // Non-critical - } - } - - private function cleanupStaleUpdateSites(): void - { - try - { - $db = Factory::getDbo(); - $dynamicUrl = 'https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient/updates.xml'; - - // Find MokoSuiteClient update sites (exclude MokoSuiteClientHQ and other Moko extensions) - $query = $db->getQuery(true) - ->select($db->quoteName(['update_site_id', 'location'])) - ->from($db->quoteName('#__update_sites')) - ->where('(' . $db->quoteName('name') . ' LIKE ' . $db->quote('%MokoSuiteClient%') - . ' OR ' . $db->quoteName('location') . ' LIKE ' . $db->quote('%MokoSuiteClient%') . ')') - ->where($db->quoteName('name') . ' NOT LIKE ' . $db->quote('%MokoSuiteClientHQ%')) - ->where($db->quoteName('location') . ' NOT LIKE ' . $db->quote('%MokoSuiteClientHQ%')); - $db->setQuery($query); - $sites = $db->loadObjectList(); - - $keepId = null; - $removeIds = []; - - foreach ($sites as $site) - { - if ($site->location === $dynamicUrl && $keepId === null) - { - $keepId = (int) $site->update_site_id; - } - else - { - $removeIds[] = (int) $site->update_site_id; - } - } - - if (empty($removeIds)) - { - return; - } - - $idList = implode(',', $removeIds); - - // Remove orphaned #__updates rows - $db->setQuery( - $db->getQuery(true) - ->delete($db->quoteName('#__updates')) - ->where($db->quoteName('update_site_id') . ' IN (' . $idList . ')') - )->execute(); - - // Remove link rows - $db->setQuery( - $db->getQuery(true) - ->delete($db->quoteName('#__update_sites_extensions')) - ->where($db->quoteName('update_site_id') . ' IN (' . $idList . ')') - )->execute(); - - // Remove stale update sites - $db->setQuery( - $db->getQuery(true) - ->delete($db->quoteName('#__update_sites')) - ->where($db->quoteName('update_site_id') . ' IN (' . $idList . ')') - )->execute(); - - $count = count($removeIds); - - if ($count > 0) - { - Factory::getApplication()->enqueueMessage( - sprintf('Cleaned up %d stale MokoSuiteClient update site(s).', $count), - 'message' - ); - } - } - catch (\Throwable $e) - { - Log::add('Error cleaning up stale update sites: ' . $e->getMessage(), Log::WARNING, 'jerror'); - } - } /** * Backup all non-empty extra_query values from update sites. diff --git a/updates.xml b/updates.xml new file mode 100644 index 00000000..15c911c4 --- /dev/null +++ b/updates.xml @@ -0,0 +1,20 @@ + + + + Package - MokoSuiteClient + pkg_mokosuiteclient + package + 02.52.04 + https://mokoconsulting.tech/support/mokosuiteclient + + https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient/releases/download/stable/pkg_mokosuiteclient-02.52.04.zip + + + stable + + + 8.2 + site + MokoSuiteClient - Joomla client-facing tracker and identity layer for the MokoSuite platform. + + From c45207726924a88c03a47c42c8372a7702513dd5 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Mon, 29 Jun 2026 16:34:28 +0000 Subject: [PATCH 6/6] chore(version): pre-release bump to 02.52.13-dev [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- CHANGELOG.md | 2 +- CODE_OF_CONDUCT.md | 2 +- GOVERNANCE.md | 2 +- LICENSE.md | 2 +- README.md | 2 +- SECURITY.md | 2 +- docs/guides/build-guide.md | 4 ++-- docs/guides/configuration-guide.md | 4 ++-- docs/guides/installation-guide.md | 4 ++-- docs/guides/operations-guide.md | 4 ++-- docs/guides/rollback-and-recovery-guide.md | 4 ++-- docs/guides/testing-guide.md | 4 ++-- docs/guides/troubleshooting-guide.md | 4 ++-- docs/guides/upgrade-and-versioning-guide.md | 4 ++-- docs/index.md | 4 ++-- docs/plugin-basic.md | 4 ++-- docs/update-server.md | 2 +- source/packages/com_mokosuiteclient/mokosuiteclient.xml | 2 +- .../mod_mokosuiteclient_cache/mod_mokosuiteclient_cache.xml | 2 +- .../mod_mokosuiteclient_categories.xml | 2 +- .../mod_mokosuiteclient_cpanel/mod_mokosuiteclient_cpanel.xml | 2 +- .../mod_mokosuiteclient_menu/mod_mokosuiteclient_menu.xml | 2 +- .../plg_system_mokosuiteclient/Extension/MokoSuiteClient.php | 2 +- .../plg_system_mokosuiteclient/Field/ArticlesField.php | 2 +- .../plg_system_mokosuiteclient/Field/CopyableTokenField.php | 2 +- .../packages/plg_system_mokosuiteclient/mokosuiteclient.xml | 2 +- source/packages/plg_system_mokosuiteclient/script.php | 2 +- .../packages/plg_system_mokosuiteclient/services/provider.php | 2 +- .../mokosuiteclient_backup.xml | 2 +- .../plg_system_mokosuiteclient_dbip/mokosuiteclient_dbip.xml | 2 +- .../mokosuiteclient_devtools.xml | 2 +- .../mokosuiteclient_firewall.xml | 2 +- .../mokosuiteclient_license.xml | 2 +- .../mokosuiteclient_offline.xml | 2 +- .../mokosuiteclient_tenant.xml | 2 +- .../plg_task_mokosuiteclientdemo/mokosuiteclientdemo.xml | 2 +- .../src/Service/DemoResetService.php | 2 +- .../plg_task_mokosuiteclientsync/mokosuiteclientsync.xml | 2 +- .../src/Service/ContentSyncReceiver.php | 2 +- .../src/Service/ContentSyncService.php | 2 +- .../plg_webservices_mokosuiteclient/mokosuiteclient.xml | 2 +- source/pkg_mokosuiteclient.xml | 2 +- 43 files changed, 53 insertions(+), 53 deletions(-) diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 11958bdc..c315225b 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.00.00 +# VERSION: 02.52.13 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/CHANGELOG.md b/CHANGELOG.md index 99380580..4c216bc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ INGROUP: MokoSuiteClient.Documentation REPO: https://github.com/mokoconsulting-tech/mokosuiteclient PATH: ./CHANGELOG.md - VERSION: 02.52.04 + VERSION: 02.52.13 BRIEF: Version history using `Keep a Changelog` --> diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index b40626a2..5c122de1 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -14,7 +14,7 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Documentation REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: ./CODE_OF_CONDUCT.md BRIEF: Reference + packaging repo for Moko Consulting Developer GPT Other Default --> diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 1af65bff..0a969210 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -19,7 +19,7 @@ DEFGROUP: mokoconsulting-tech.MokoSuiteClientBrand INGROUP: MokoStandards.Governance REPO: https://github.com/mokoconsulting-tech/MokoSuiteClientBrand - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /GOVERNANCE.md BRIEF: Project governance rules, roles, and decision process for MokoSuiteClientBrand --> diff --git a/LICENSE.md b/LICENSE.md index 6f25d49d..f9d83118 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -15,7 +15,7 @@ INGROUP: MokoSuiteClient.Documentation REPO: https://github.com/mokoconsulting-tech/mokosuiteclient PATH: ./LICENSE.md - VERSION: 02.52.04 + VERSION: 02.52.13 BRIEF: Project license (GPL-3.0-or-later) --> GNU GENERAL PUBLIC LICENSE diff --git a/README.md b/README.md index 3ccb18a5..02248965 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /README.md BRIEF: MokoSuiteClient platform plugin for Joomla --> diff --git a/SECURITY.md b/SECURITY.md index 42f17a00..961b2d54 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,7 +23,7 @@ DEFGROUP: [PROJECT_NAME] INGROUP: [PROJECT_NAME].Documentation REPO: [REPOSITORY_URL] PATH: /SECURITY.md -VERSION: 02.52.04 +VERSION: 02.52.13 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/docs/guides/build-guide.md b/docs/guides/build-guide.md index 3671898a..4e49bce1 100644 --- a/docs/guides/build-guide.md +++ b/docs/guides/build-guide.md @@ -11,13 +11,13 @@ INGROUP: MokoSuiteClient.Build REPO: https://github.com/mokoconsulting-tech/mokosuiteclient FILE: build-guide.md - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/guides/ BRIEF: Build and packaging guide for the MokoSuiteClient system plugin NOTE: Defines environment setup, repository layout, packaging rules, and release preparation --> -# MokoSuiteClient Build Guide (VERSION: 02.52.04) +# MokoSuiteClient Build Guide (VERSION: 02.52.13) ## 1. Purpose diff --git a/docs/guides/configuration-guide.md b/docs/guides/configuration-guide.md index 81fccc07..0cbe0bf9 100644 --- a/docs/guides/configuration-guide.md +++ b/docs/guides/configuration-guide.md @@ -10,13 +10,13 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Guides REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/guides/configuration-guide.md BRIEF: Configuration guide for the MokoSuiteClient system plugin NOTE: Defines plugin parameters, expected behaviors, and recommended defaults --> -# MokoSuiteClient Configuration Guide (VERSION: 02.52.04) +# MokoSuiteClient Configuration Guide (VERSION: 02.52.13) ## 1. Objective diff --git a/docs/guides/installation-guide.md b/docs/guides/installation-guide.md index 40791acf..5aa7d3a9 100644 --- a/docs/guides/installation-guide.md +++ b/docs/guides/installation-guide.md @@ -10,13 +10,13 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Guides REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/guides/installation-guide.md BRIEF: Installation guide for the MokoSuiteClient system plugin NOTE: First document in the guide set --> -# MokoSuiteClient Installation Guide (VERSION: 02.52.04) +# MokoSuiteClient Installation Guide (VERSION: 02.52.13) ## Introduction diff --git a/docs/guides/operations-guide.md b/docs/guides/operations-guide.md index c6942e3e..99cd7452 100644 --- a/docs/guides/operations-guide.md +++ b/docs/guides/operations-guide.md @@ -10,13 +10,13 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Guides REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/guides/operations-guide.md BRIEF: Operational guide for administering and managing the MokoSuiteClient system plugin NOTE: Defines lifecycle, responsibilities, and operational behaviors --> -# MokoSuiteClient Operations Guide (VERSION: 02.52.04) +# MokoSuiteClient Operations Guide (VERSION: 02.52.13) ## Introduction diff --git a/docs/guides/rollback-and-recovery-guide.md b/docs/guides/rollback-and-recovery-guide.md index a3f3bc68..41d27cfd 100644 --- a/docs/guides/rollback-and-recovery-guide.md +++ b/docs/guides/rollback-and-recovery-guide.md @@ -10,13 +10,13 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Guides REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/guides/rollback-and-recovery-guide.md BRIEF: Rollback and recovery guide for restoring stable operation after plugin related incidents NOTE: Completes the core guide set for Suite plugin governance --> -# MokoSuiteClient Rollback and Recovery Guide (VERSION: 02.52.04) +# MokoSuiteClient Rollback and Recovery Guide (VERSION: 02.52.13) ## Introduction diff --git a/docs/guides/testing-guide.md b/docs/guides/testing-guide.md index f9a4aa33..cd3df1c7 100644 --- a/docs/guides/testing-guide.md +++ b/docs/guides/testing-guide.md @@ -7,13 +7,13 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Guides REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/guides/testing-guide.md BRIEF: Testing guide for MokoSuiteClient v02.01.08 NOTE: Covers manual test procedures for language overrides, install/uninstall, and configuration --> -# MokoSuiteClient Testing Guide (VERSION: 02.52.04) +# MokoSuiteClient Testing Guide (VERSION: 02.52.13) ## 1. Prerequisites diff --git a/docs/guides/troubleshooting-guide.md b/docs/guides/troubleshooting-guide.md index 437388e7..e9b1c06c 100644 --- a/docs/guides/troubleshooting-guide.md +++ b/docs/guides/troubleshooting-guide.md @@ -10,13 +10,13 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Guides REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/guides/troubleshooting-guide.md BRIEF: Troubleshooting guide for diagnosing and resolving issues related to the MokoSuiteClient plugin NOTE: Designed for administrators and Suite operations teams --> -# MokoSuiteClient Troubleshooting Guide (VERSION: 02.52.04) +# MokoSuiteClient Troubleshooting Guide (VERSION: 02.52.13) ## Introduction diff --git a/docs/guides/upgrade-and-versioning-guide.md b/docs/guides/upgrade-and-versioning-guide.md index c90d22d7..2adf9853 100644 --- a/docs/guides/upgrade-and-versioning-guide.md +++ b/docs/guides/upgrade-and-versioning-guide.md @@ -10,13 +10,13 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Guides REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/guides/upgrade-and-versioning-guide.md BRIEF: Guide for updating, versioning, and maintaining the MokoSuiteClient plugin NOTE: Defines release flow, version rules, and upgrade validation --> -# MokoSuiteClient Upgrade and Versioning Guide (VERSION: 02.52.04) +# MokoSuiteClient Upgrade and Versioning Guide (VERSION: 02.52.13) ## Introduction diff --git a/docs/index.md b/docs/index.md index 7af574b3..8526bc3c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,13 +10,13 @@ DEFGROUP: Joomla.Plugin INGROUP: MokoSuiteClient.Documentation REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - VERSION: 02.52.04 + VERSION: 02.52.13 PATH: /docs/index.md BRIEF: Master index of all documentation for the MokoSuiteClient plugin NOTE: Automatically maintained index for all guide canvases --> -# MokoSuiteClient Documentation Index (VERSION: 02.52.04) +# MokoSuiteClient Documentation Index (VERSION: 02.52.13) ## Introduction diff --git a/docs/plugin-basic.md b/docs/plugin-basic.md index 29dca6a5..95b4e434 100644 --- a/docs/plugin-basic.md +++ b/docs/plugin-basic.md @@ -11,12 +11,12 @@ INGROUP: MokoSuiteClient REPO: https://github.com/mokoconsulting-tech/mokosuiteclient PATH: /docs/plugin-basic.md - VERSION: 02.52.04 + VERSION: 02.52.13 BRIEF: Baseline documentation for the MokoSuiteClient system plugin NOTE: Foundational reference for internal and external stakeholders --> -# MokoSuiteClient Plugin Overview (VERSION: 02.52.04) +# MokoSuiteClient Plugin Overview (VERSION: 02.52.13) ## Introduction diff --git a/docs/update-server.md b/docs/update-server.md index 8cf24cd5..1deaec49 100644 --- a/docs/update-server.md +++ b/docs/update-server.md @@ -10,7 +10,7 @@ DEFGROUP: MokoSuiteClient.Documentation INGROUP: MokoStandards.Templates REPO: https://github.com/mokoconsulting-tech/MokoSuiteClient PATH: /docs/update-server.md -VERSION: 02.52.04 +VERSION: 02.52.13 BRIEF: How this extension's Joomla update server file (update.xml) is managed --> diff --git a/source/packages/com_mokosuiteclient/mokosuiteclient.xml b/source/packages/com_mokosuiteclient/mokosuiteclient.xml index b6d7e26a..262dcf4e 100644 --- a/source/packages/com_mokosuiteclient/mokosuiteclient.xml +++ b/source/packages/com_mokosuiteclient/mokosuiteclient.xml @@ -20,7 +20,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 MokoSuiteClient admin dashboard and REST API. Provides a control panel for managing MokoSuiteClient feature plugins, site health monitoring, and remote management endpoints. Moko\Component\MokoSuiteClient diff --git a/source/packages/mod_mokosuiteclient_cache/mod_mokosuiteclient_cache.xml b/source/packages/mod_mokosuiteclient_cache/mod_mokosuiteclient_cache.xml index 4f9371ee..20f40a3a 100644 --- a/source/packages/mod_mokosuiteclient_cache/mod_mokosuiteclient_cache.xml +++ b/source/packages/mod_mokosuiteclient_cache/mod_mokosuiteclient_cache.xml @@ -7,7 +7,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 MOD_MOKOSUITECLIENT_CACHE_DESC Moko\Module\MokoSuiteClientCache diff --git a/source/packages/mod_mokosuiteclient_categories/mod_mokosuiteclient_categories.xml b/source/packages/mod_mokosuiteclient_categories/mod_mokosuiteclient_categories.xml index 8577e1e1..4aaace1a 100644 --- a/source/packages/mod_mokosuiteclient_categories/mod_mokosuiteclient_categories.xml +++ b/source/packages/mod_mokosuiteclient_categories/mod_mokosuiteclient_categories.xml @@ -7,7 +7,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 MOD_MOKOSUITECLIENT_CATEGORIES_DESC Moko\Module\MokoSuiteClientCategories diff --git a/source/packages/mod_mokosuiteclient_cpanel/mod_mokosuiteclient_cpanel.xml b/source/packages/mod_mokosuiteclient_cpanel/mod_mokosuiteclient_cpanel.xml index 63cc14c6..65d7ea75 100644 --- a/source/packages/mod_mokosuiteclient_cpanel/mod_mokosuiteclient_cpanel.xml +++ b/source/packages/mod_mokosuiteclient_cpanel/mod_mokosuiteclient_cpanel.xml @@ -7,7 +7,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 MOD_MOKOSUITECLIENT_CPANEL_DESC Moko\Module\MokoSuiteClientCpanel diff --git a/source/packages/mod_mokosuiteclient_menu/mod_mokosuiteclient_menu.xml b/source/packages/mod_mokosuiteclient_menu/mod_mokosuiteclient_menu.xml index d24255b4..71925e91 100644 --- a/source/packages/mod_mokosuiteclient_menu/mod_mokosuiteclient_menu.xml +++ b/source/packages/mod_mokosuiteclient_menu/mod_mokosuiteclient_menu.xml @@ -7,7 +7,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 MokoSuiteClient admin sidebar menu — renders a dedicated MokoSuiteClient section in the admin menu before Joomla's default menu. Moko\Module\MokoSuiteClientMenu diff --git a/source/packages/plg_system_mokosuiteclient/Extension/MokoSuiteClient.php b/source/packages/plg_system_mokosuiteclient/Extension/MokoSuiteClient.php index 69256abb..3383f45e 100644 --- a/source/packages/plg_system_mokosuiteclient/Extension/MokoSuiteClient.php +++ b/source/packages/plg_system_mokosuiteclient/Extension/MokoSuiteClient.php @@ -22,7 +22,7 @@ * DEFGROUP: Joomla.Plugin * INGROUP: MokoSuiteClient * REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - * VERSION: 02.52.04 + * VERSION: 02.52.13 * PATH: /src/Extension/MokoSuiteClient.php * NOTE: Core system plugin for MokoSuiteClient admin tools suite */ diff --git a/source/packages/plg_system_mokosuiteclient/Field/ArticlesField.php b/source/packages/plg_system_mokosuiteclient/Field/ArticlesField.php index 1a06b149..5c7c4379 100644 --- a/source/packages/plg_system_mokosuiteclient/Field/ArticlesField.php +++ b/source/packages/plg_system_mokosuiteclient/Field/ArticlesField.php @@ -8,7 +8,7 @@ * FILE INFORMATION * DEFGROUP: Joomla.Plugin * INGROUP: MokoSuiteClient - * VERSION: 02.52.04 + * VERSION: 02.52.13 * PATH: /src/Field/ArticlesField.php * BRIEF: List field that populates with published Joomla articles */ diff --git a/source/packages/plg_system_mokosuiteclient/Field/CopyableTokenField.php b/source/packages/plg_system_mokosuiteclient/Field/CopyableTokenField.php index 64897a51..32a2bc22 100644 --- a/source/packages/plg_system_mokosuiteclient/Field/CopyableTokenField.php +++ b/source/packages/plg_system_mokosuiteclient/Field/CopyableTokenField.php @@ -8,7 +8,7 @@ * FILE INFORMATION * DEFGROUP: Joomla.Plugin * INGROUP: MokoSuiteClient - * VERSION: 02.52.04 + * VERSION: 02.52.13 * PATH: /src/Field/CopyableTokenField.php * BRIEF: Read-only token field with a copy-to-clipboard button */ diff --git a/source/packages/plg_system_mokosuiteclient/mokosuiteclient.xml b/source/packages/plg_system_mokosuiteclient/mokosuiteclient.xml index 1fc6ccd2..0ea8e044 100644 --- a/source/packages/plg_system_mokosuiteclient/mokosuiteclient.xml +++ b/source/packages/plg_system_mokosuiteclient/mokosuiteclient.xml @@ -30,7 +30,7 @@ GNU General Public License version 3 or later; see LICENSE.md hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 MokoSuiteClient core system plugin — coordinates feature plugins, heartbeat, health checks, and admin customizations. Moko\Plugin\System\MokoSuiteClient script.php diff --git a/source/packages/plg_system_mokosuiteclient/script.php b/source/packages/plg_system_mokosuiteclient/script.php index 36d435b5..f1c0e567 100644 --- a/source/packages/plg_system_mokosuiteclient/script.php +++ b/source/packages/plg_system_mokosuiteclient/script.php @@ -22,7 +22,7 @@ * DEFGROUP: Joomla.Plugin * INGROUP: MokoSuiteClient * REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - * VERSION: 02.52.04 + * VERSION: 02.52.13 * PATH: /src/script.php * BRIEF: Installation script for MokoSuiteClient plugin * NOTE: Handles installation, update, and uninstallation tasks including language override deployment diff --git a/source/packages/plg_system_mokosuiteclient/services/provider.php b/source/packages/plg_system_mokosuiteclient/services/provider.php index c55d3324..a4cf5c00 100644 --- a/source/packages/plg_system_mokosuiteclient/services/provider.php +++ b/source/packages/plg_system_mokosuiteclient/services/provider.php @@ -22,7 +22,7 @@ * DEFGROUP: Joomla.Plugin * INGROUP: MokoSuiteClient * REPO: https://github.com/mokoconsulting-tech/mokosuiteclient - * VERSION: 02.52.04 + * VERSION: 02.52.13 * PATH: /src/services/provider.php * BRIEF: Service provider for dependency injection in Joomla 5.x * NOTE: Registers the plugin with Joomla's DI container diff --git a/source/packages/plg_system_mokosuiteclient_backup/mokosuiteclient_backup.xml b/source/packages/plg_system_mokosuiteclient_backup/mokosuiteclient_backup.xml index b897e3e0..2f433943 100644 --- a/source/packages/plg_system_mokosuiteclient_backup/mokosuiteclient_backup.xml +++ b/source/packages/plg_system_mokosuiteclient_backup/mokosuiteclient_backup.xml @@ -8,7 +8,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_DESC Moko\Plugin\System\MokoSuiteClientBackup diff --git a/source/packages/plg_system_mokosuiteclient_dbip/mokosuiteclient_dbip.xml b/source/packages/plg_system_mokosuiteclient_dbip/mokosuiteclient_dbip.xml index 33c6d97a..9c34d3d5 100644 --- a/source/packages/plg_system_mokosuiteclient_dbip/mokosuiteclient_dbip.xml +++ b/source/packages/plg_system_mokosuiteclient_dbip/mokosuiteclient_dbip.xml @@ -8,7 +8,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DESC Moko\Plugin\System\MokoSuiteClientDBIP diff --git a/source/packages/plg_system_mokosuiteclient_devtools/mokosuiteclient_devtools.xml b/source/packages/plg_system_mokosuiteclient_devtools/mokosuiteclient_devtools.xml index c943ef2c..76e80304 100644 --- a/source/packages/plg_system_mokosuiteclient_devtools/mokosuiteclient_devtools.xml +++ b/source/packages/plg_system_mokosuiteclient_devtools/mokosuiteclient_devtools.xml @@ -8,7 +8,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_DESC Moko\Plugin\System\MokoSuiteClientDevTools diff --git a/source/packages/plg_system_mokosuiteclient_firewall/mokosuiteclient_firewall.xml b/source/packages/plg_system_mokosuiteclient_firewall/mokosuiteclient_firewall.xml index 3241c149..ce9242b9 100644 --- a/source/packages/plg_system_mokosuiteclient_firewall/mokosuiteclient_firewall.xml +++ b/source/packages/plg_system_mokosuiteclient_firewall/mokosuiteclient_firewall.xml @@ -8,7 +8,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_DESC Moko\Plugin\System\MokoSuiteClientFirewall diff --git a/source/packages/plg_system_mokosuiteclient_license/mokosuiteclient_license.xml b/source/packages/plg_system_mokosuiteclient_license/mokosuiteclient_license.xml index 6c0fc44b..28844381 100644 --- a/source/packages/plg_system_mokosuiteclient_license/mokosuiteclient_license.xml +++ b/source/packages/plg_system_mokosuiteclient_license/mokosuiteclient_license.xml @@ -8,7 +8,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_SYSTEM_MOKOSUITECLIENT_LICENSE_DESC Moko\Plugin\System\MokoSuiteClientLicense srcserviceslanguage diff --git a/source/packages/plg_system_mokosuiteclient_offline/mokosuiteclient_offline.xml b/source/packages/plg_system_mokosuiteclient_offline/mokosuiteclient_offline.xml index ac48824b..53527c6e 100644 --- a/source/packages/plg_system_mokosuiteclient_offline/mokosuiteclient_offline.xml +++ b/source/packages/plg_system_mokosuiteclient_offline/mokosuiteclient_offline.xml @@ -8,7 +8,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_SYSTEM_MOKOSUITECLIENT_OFFLINE_DESC Moko\Plugin\System\MokoSuiteClientOffline diff --git a/source/packages/plg_system_mokosuiteclient_tenant/mokosuiteclient_tenant.xml b/source/packages/plg_system_mokosuiteclient_tenant/mokosuiteclient_tenant.xml index 6b755610..d3a4cf0c 100644 --- a/source/packages/plg_system_mokosuiteclient_tenant/mokosuiteclient_tenant.xml +++ b/source/packages/plg_system_mokosuiteclient_tenant/mokosuiteclient_tenant.xml @@ -8,7 +8,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_SYSTEM_MOKOSUITECLIENT_TENANT_DESC Moko\Plugin\System\MokoSuiteClientTenant diff --git a/source/packages/plg_task_mokosuiteclientdemo/mokosuiteclientdemo.xml b/source/packages/plg_task_mokosuiteclientdemo/mokosuiteclientdemo.xml index 80ead0e2..5959515f 100644 --- a/source/packages/plg_task_mokosuiteclientdemo/mokosuiteclientdemo.xml +++ b/source/packages/plg_task_mokosuiteclientdemo/mokosuiteclientdemo.xml @@ -12,7 +12,7 @@ GNU General Public License version 3 or later; see LICENSE hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_TASK_MOKOSUITECLIENTDEMO_DESC Moko\Plugin\Task\MokoSuiteClientDemo diff --git a/source/packages/plg_task_mokosuiteclientdemo/src/Service/DemoResetService.php b/source/packages/plg_task_mokosuiteclientdemo/src/Service/DemoResetService.php index fe497c7c..098b461d 100644 --- a/source/packages/plg_task_mokosuiteclientdemo/src/Service/DemoResetService.php +++ b/source/packages/plg_task_mokosuiteclientdemo/src/Service/DemoResetService.php @@ -10,7 +10,7 @@ * INGROUP: MokoSuiteClient * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient * PATH: /src/packages/plg_system_mokosuiteclient/Service/DemoResetService.php - * VERSION: 02.52.04 + * VERSION: 02.52.13 * BRIEF: Content-only snapshot/restore for demo site reset */ diff --git a/source/packages/plg_task_mokosuiteclientsync/mokosuiteclientsync.xml b/source/packages/plg_task_mokosuiteclientsync/mokosuiteclientsync.xml index fb37c65e..80878b8e 100644 --- a/source/packages/plg_task_mokosuiteclientsync/mokosuiteclientsync.xml +++ b/source/packages/plg_task_mokosuiteclientsync/mokosuiteclientsync.xml @@ -12,7 +12,7 @@ GNU General Public License version 3 or later; see LICENSE hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 PLG_TASK_MOKOSUITECLIENTSYNC_DESC Moko\Plugin\Task\MokoSuiteClientSync diff --git a/source/packages/plg_task_mokosuiteclientsync/src/Service/ContentSyncReceiver.php b/source/packages/plg_task_mokosuiteclientsync/src/Service/ContentSyncReceiver.php index c141cbbf..4f1b9478 100644 --- a/source/packages/plg_task_mokosuiteclientsync/src/Service/ContentSyncReceiver.php +++ b/source/packages/plg_task_mokosuiteclientsync/src/Service/ContentSyncReceiver.php @@ -10,7 +10,7 @@ * INGROUP: MokoSuiteClient * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient * PATH: /src/packages/plg_system_mokosuiteclient/Service/ContentSyncReceiver.php - * VERSION: 02.52.04 + * VERSION: 02.52.13 * BRIEF: Receiver-side content sync — applies incoming payload to local DB */ diff --git a/source/packages/plg_task_mokosuiteclientsync/src/Service/ContentSyncService.php b/source/packages/plg_task_mokosuiteclientsync/src/Service/ContentSyncService.php index 194993a6..84a161f6 100644 --- a/source/packages/plg_task_mokosuiteclientsync/src/Service/ContentSyncService.php +++ b/source/packages/plg_task_mokosuiteclientsync/src/Service/ContentSyncService.php @@ -10,7 +10,7 @@ * INGROUP: MokoSuiteClient * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient * PATH: /src/packages/plg_system_mokosuiteclient/Service/ContentSyncService.php - * VERSION: 02.52.04 + * VERSION: 02.52.13 * BRIEF: Sender-side content sync — builds payload and pushes to remote sites */ diff --git a/source/packages/plg_webservices_mokosuiteclient/mokosuiteclient.xml b/source/packages/plg_webservices_mokosuiteclient/mokosuiteclient.xml index 9484f475..1786853b 100644 --- a/source/packages/plg_webservices_mokosuiteclient/mokosuiteclient.xml +++ b/source/packages/plg_webservices_mokosuiteclient/mokosuiteclient.xml @@ -7,7 +7,7 @@ GPL-3.0-or-later hello@mokoconsulting.tech https://mokoconsulting.tech - 02.52.04 + 02.52.13 Joomla Web Services API routes for MokoSuiteClient site management — health checks, cache, updates, backups, and site info. Moko\Plugin\WebServices\MokoSuiteClient diff --git a/source/pkg_mokosuiteclient.xml b/source/pkg_mokosuiteclient.xml index 86be648f..5571e197 100644 --- a/source/pkg_mokosuiteclient.xml +++ b/source/pkg_mokosuiteclient.xml @@ -2,7 +2,7 @@ Package - MokoSuiteClient mokosuiteclient - 02.52.04 + 02.52.13 2026-06-02 Moko Consulting hello@mokoconsulting.tech