diff --git a/src/packages/com_mokowaas/admin/language/en-GB/com_mokowaas.sys.ini b/src/packages/com_mokowaas/admin/language/en-GB/com_mokowaas.sys.ini index 0218a06c..3c71dbd1 100644 --- a/src/packages/com_mokowaas/admin/language/en-GB/com_mokowaas.sys.ini +++ b/src/packages/com_mokowaas/admin/language/en-GB/com_mokowaas.sys.ini @@ -14,4 +14,6 @@ COM_MOKOWAAS_MENU_TICKETS="Helpdesk" COM_MOKOWAAS_MENU_HTACCESS=".htaccess Maker" COM_MOKOWAAS_MENU_PRIVACY="Privacy Guard" COM_MOKOWAAS_MENU_WAFLOG="WAF Log" +COM_MOKOWAAS_MENU_DATABASE="Database Tools" +COM_MOKOWAAS_MENU_CLEANUP="Cache Cleanup" COM_MOKOWAAS_MENU_CACHE="Cache Management" diff --git a/src/packages/com_mokowaas/admin/src/Controller/DisplayController.php b/src/packages/com_mokowaas/admin/src/Controller/DisplayController.php index c9eaa008..dd77f61f 100644 --- a/src/packages/com_mokowaas/admin/src/Controller/DisplayController.php +++ b/src/packages/com_mokowaas/admin/src/Controller/DisplayController.php @@ -34,6 +34,8 @@ class DisplayController extends BaseController 'categories' => 'mokowaas.tickets', 'canned' => 'mokowaas.tickets', 'automation' => 'core.admin', + 'database' => 'core.admin', + 'cleanup' => 'mokowaas.cache', ]; public function display($cachable = false, $urlparams = []) @@ -282,6 +284,43 @@ class DisplayController extends BaseController } } + // ================================================================== + // Maintenance (#127, #128) + // ================================================================== + + public function optimizeDb() + { + Session::checkToken() or die(Text::_('JINVALID_TOKEN')); + if (!$this->checkAcl('core.admin')) { $this->jsonForbidden(); return; } + $model = new \Moko\Component\MokoWaaS\Administrator\Model\MaintenanceModel(); + $this->jsonResponse($model->optimizeTables()); + } + + public function repairDb() + { + Session::checkToken() or die(Text::_('JINVALID_TOKEN')); + if (!$this->checkAcl('core.admin')) { $this->jsonForbidden(); return; } + $model = new \Moko\Component\MokoWaaS\Administrator\Model\MaintenanceModel(); + $this->jsonResponse($model->repairTables()); + } + + public function purgeSessions() + { + Session::checkToken() or die(Text::_('JINVALID_TOKEN')); + if (!$this->checkAcl('core.admin')) { $this->jsonForbidden(); return; } + $model = new \Moko\Component\MokoWaaS\Administrator\Model\MaintenanceModel(); + $this->jsonResponse($model->purgeSessions()); + } + + public function cleanDirectory() + { + Session::checkToken() or die(Text::_('JINVALID_TOKEN')); + if (!$this->checkAcl('mokowaas.cache')) { $this->jsonForbidden(); return; } + $dirKey = Factory::getApplication()->getInput()->getString('dir_key', ''); + $model = new \Moko\Component\MokoWaaS\Administrator\Model\MaintenanceModel(); + $this->jsonResponse($model->cleanDirectory($dirKey)); + } + // ================================================================== // Helpdesk CRUD (#137, #138, #139) // ================================================================== diff --git a/src/packages/com_mokowaas/admin/tmpl/cleanup/default.php b/src/packages/com_mokowaas/admin/tmpl/cleanup/default.php new file mode 100644 index 00000000..073c623d --- /dev/null +++ b/src/packages/com_mokowaas/admin/tmpl/cleanup/default.php @@ -0,0 +1,63 @@ +dirs; +$token = Session::getFormToken(); +$cleanUrl = Route::_('index.php?option=com_mokowaas&task=display.cleanDirectory&format=json'); + +$dirKeys = ['site_cache', 'admin_cache', 'tmp', 'logs']; +$totalMb = 0; +$totalFiles = 0; +foreach ($dirs as $d) { $totalMb += $d->size_mb; $totalFiles += $d->files; } +?> + +
+
+
MBTotal Size
+
Total Files
+
+ +
+ $d): ?> +
+
+
+
label); ?>
+

size_mb, 1); ?> MB

+

files); ?> files

+ writable): ?> + Not writable + + + +
+
+
+ +
+
+ + diff --git a/src/packages/com_mokowaas/admin/tmpl/database/default.php b/src/packages/com_mokowaas/admin/tmpl/database/default.php new file mode 100644 index 00000000..0d0c9357 --- /dev/null +++ b/src/packages/com_mokowaas/admin/tmpl/database/default.php @@ -0,0 +1,72 @@ +tableData; +$tables = $data['tables'] ?? []; +$token = Session::getFormToken(); +$optimizeUrl = Route::_('index.php?option=com_mokowaas&task=display.optimizeDb&format=json'); +$repairUrl = Route::_('index.php?option=com_mokowaas&task=display.repairDb&format=json'); +$purgeUrl = Route::_('index.php?option=com_mokowaas&task=display.purgeSessions&format=json'); +?> + +
+
+
Tables
+
MBTotal Size
+
KBOverhead
+
+
+ + + +
+
+
+ +
+
+ + + + + + + + + + + + + +
TableEngineRowsSizeOverhead
name); ?>engine); ?>rows); ?>size_mb; ?> MBoverhead_kb > 0 ? $t->overhead_kb . ' KB' : '—'; ?>
+
+
+
+ + diff --git a/src/packages/com_mokowaas/mokowaas.xml b/src/packages/com_mokowaas/mokowaas.xml index 4a50cfc5..d88f93e1 100644 --- a/src/packages/com_mokowaas/mokowaas.xml +++ b/src/packages/com_mokowaas/mokowaas.xml @@ -34,6 +34,8 @@ COM_MOKOWAAS_MENU_HTACCESS COM_MOKOWAAS_MENU_PRIVACY COM_MOKOWAAS_MENU_WAFLOG + COM_MOKOWAAS_MENU_DATABASE + COM_MOKOWAAS_MENU_CLEANUP COM_MOKOWAAS_MENU_PLUGINS COM_MOKOWAAS_MENU_UPDATES COM_MOKOWAAS_MENU_CHECKIN diff --git a/src/packages/mod_mokowaas_cpanel/src/Helper/CpanelHelper.php b/src/packages/mod_mokowaas_cpanel/src/Helper/CpanelHelper.php index a50d895e..87fff882 100644 --- a/src/packages/mod_mokowaas_cpanel/src/Helper/CpanelHelper.php +++ b/src/packages/mod_mokowaas_cpanel/src/Helper/CpanelHelper.php @@ -87,10 +87,11 @@ class CpanelHelper public function getCounts(DatabaseInterface $db): object { $counts = (object) [ - 'articles' => 0, - 'users' => 0, - 'extensions' => 0, - 'updates' => 0, + 'articles' => 0, + 'users' => 0, + 'extensions' => 0, + 'updates' => 0, + 'moko_updates' => 0, ]; try @@ -106,6 +107,20 @@ class CpanelHelper $db->setQuery($db->getQuery(true)->select('COUNT(*)')->from($db->quoteName('#__updates'))->where($db->quoteName('extension_id') . ' != 0')); $counts->updates = (int) $db->loadResult(); + + // MokoWaaS-specific updates + $db->setQuery( + $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__updates', 'u')) + ->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = u.extension_id') + ->where('(' . $db->quoteName('e.element') . ' LIKE ' . $db->quote('mokowaas%') + . ' OR ' . $db->quoteName('e.element') . ' LIKE ' . $db->quote('pkg_mokowaas%') + . ' OR ' . $db->quoteName('e.element') . ' LIKE ' . $db->quote('com_mokowaas%') + . ' OR ' . $db->quoteName('e.element') . ' LIKE ' . $db->quote('mod_mokowaas%') + . ' OR ' . $db->quoteName('e.element') . ' = ' . $db->quote('mokoonyx') . ')') + ); + $counts->moko_updates = (int) $db->loadResult(); } catch (\Throwable $e) { diff --git a/src/packages/mod_mokowaas_cpanel/tmpl/default.php b/src/packages/mod_mokowaas_cpanel/tmpl/default.php index a65553f5..66eea9f4 100644 --- a/src/packages/mod_mokowaas_cpanel/tmpl/default.php +++ b/src/packages/mod_mokowaas_cpanel/tmpl/default.php @@ -67,6 +67,16 @@ $diskColor = ($diskPct !== null && $diskPct > 90) ? 'bg-danger' : (($diskPct !== offline)): ?> Offline + moko_updates ?? 0) > 0): ?> + + moko_updates; ?> MokoWaaS updatemoko_updates > 1 ? 's' : ''; ?> + + + updates > 0 && $counts->updates !== ($counts->moko_updates ?? 0)): ?> + + updates - ($counts->moko_updates ?? 0); ?> updateupdates - ($counts->moko_updates ?? 0)) > 1 ? 's' : ''; ?> + + diff --git a/src/packages/mod_mokowaas_menu/tmpl/default.php b/src/packages/mod_mokowaas_menu/tmpl/default.php index 0c7eca76..d95b4df2 100644 --- a/src/packages/mod_mokowaas_menu/tmpl/default.php +++ b/src/packages/mod_mokowaas_menu/tmpl/default.php @@ -17,6 +17,8 @@ $items = [ ['icon' => 'icon-file-code', 'title' => '.htaccess Maker', 'link' => 'index.php?option=com_mokowaas&view=htaccess'], ['icon' => 'icon-lock', 'title' => 'Privacy Guard', 'link' => 'index.php?option=com_mokowaas&view=privacy'], ['icon' => 'icon-shield-alt', 'title' => 'WAF Log', 'link' => 'index.php?option=com_mokowaas&view=waflog'], + ['icon' => 'icon-database', 'title' => 'Database Tools', 'link' => 'index.php?option=com_mokowaas&view=database'], + ['icon' => 'icon-trash', 'title' => 'Cache Cleanup', 'link' => 'index.php?option=com_mokowaas&view=cleanup'], ['icon' => 'icon-power-off', 'title' => 'Feature Plugins', 'link' => 'index.php?option=com_plugins&filter[folder]=system&filter[search]=mokowaas'], ]; diff --git a/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php b/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php index 0000d4ad..3d03f803 100644 --- a/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php +++ b/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php @@ -939,55 +939,6 @@ class MokoWaaS extends CMSPlugin implements BootableExtensionInterface } $this->protectPlugin(); - $this->warnMissingLicenseKey(); - } - - /** - * Warn on every admin page load if no license key is configured. - * Non-dismissable — shows on every request, not cached per session. - */ - protected function warnMissingLicenseKey(): void - { - if (!$this->isMasterUser()) - { - return; - } - - try - { - $db = Factory::getDbo(); - - $query = $db->getQuery(true) - ->select($db->quoteName('extra_query')) - ->from($db->quoteName('#__update_sites')) - ->where('(' . $db->quoteName('name') . ' LIKE ' . $db->quote('%MokoWaaS%') - . ' OR ' . $db->quoteName('location') . ' LIKE ' . $db->quote('%MokoWaaS%') . ')') - ->setLimit(1); - $db->setQuery($query); - $extraQuery = (string) $db->loadResult(); - - if (!empty($extraQuery) && strpos($extraQuery, 'dlid=') !== false) - { - parse_str($extraQuery, $parsed); - - if (!empty($parsed['dlid'])) - { - return; - } - } - - $this->app->enqueueMessage( - 'Moko Consulting License Key Required — ' - . 'No download key is configured. Updates will not be available until a valid license key is entered. ' - . 'Go to System → Update Sites ' - . 'and enter your license key in the Download Key field for the MokoWaaS update site.', - 'warning' - ); - } - catch (\Throwable $e) - { - // Silent - } } // ------------------------------------------------------------------ diff --git a/src/script.php b/src/script.php index 9a2a541c..8d659f98 100644 --- a/src/script.php +++ b/src/script.php @@ -69,6 +69,9 @@ class Pkg_MokowaasInstallerScript // Trigger heartbeat registration $this->sendHeartbeat(); + + // Warn if no license key is configured + $this->warnMissingLicenseKey(); } /** @@ -996,4 +999,57 @@ class Pkg_MokowaasInstallerScript Log::add('Feature param migration error: ' . $e->getMessage(), Log::WARNING, 'mokowaas'); } } + + /** + * Warn after install/update if no license key (dlid) is configured on the update site. + */ + private function warnMissingLicenseKey(): void + { + try + { + $db = Factory::getDbo(); + $app = Factory::getApplication(); + + $query = $db->getQuery(true) + ->select([$db->quoteName('update_site_id'), $db->quoteName('extra_query')]) + ->from($db->quoteName('#__update_sites')) + ->where('(' . $db->quoteName('name') . ' LIKE ' . $db->quote('%MokoWaaS%') + . ' OR ' . $db->quoteName('location') . ' LIKE ' . $db->quote('%MokoWaaS%') . ')') + ->setLimit(1); + $db->setQuery($query); + $site = $db->loadObject(); + + if ($site) + { + $extraQuery = (string) ($site->extra_query ?? ''); + + if (!empty($extraQuery) && strpos($extraQuery, 'dlid=') !== false) + { + parse_str($extraQuery, $parsed); + + if (!empty($parsed['dlid'])) + { + return; + } + } + + $editUrl = 'index.php?option=com_installer&task=updatesite.edit&update_site_id=' . (int) $site->update_site_id; + } + else + { + $editUrl = 'index.php?option=com_installer&view=updatesites'; + } + + $app->enqueueMessage( + 'Moko Consulting License Key Required — ' + . 'No download key is configured. Updates will not be available until a valid license key is entered. ' + . 'Enter License Key', + 'warning' + ); + } + catch (\Throwable $e) + { + // Silent + } + } }