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));
+?>
+
+
+
+
+
+
+
+
+
+
+ | ID |
+ Name |
+ Alias |
+ Category |
+ Match |
+ Groups |
+ Rules |
+ Status |
+
+
+
+
+ | 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'];
+?>
+
+
+
+
+
+
+
+
+
+
+ | ID |
+ Title |
+ Position |
+ Type |
+ Client |
+ Order |
+ Status |
+
+
+
+
+ | 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));
+?>
+
+
+
+
+
+
+
+
+
+
+ | ID |
+ Name |
+ Search |
+ Replace |
+ Area |
+ Regex |
+ Category |
+ Status |
+
+
+
+
+ | 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));
+?>
+
+
+
+
+
+
+
+
+
+
+ | ID |
+ Name |
+ Alias |
+ Category |
+ Order |
+ Status |
+
+
+
+
+ | 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));
+?>
+
+
+
+
+
+
+
+
+
+
+ | ID |
+ Name |
+ Alias |
+ Category |
+ Order |
+ Status |
+
+
+
+
+ | 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'],