getInput()->get('option', ''); $currentView = $app->getInput()->get('view', ''); // ── Static views for com_mokosuite ────────────────────────────────── $mokosuiteStaticViews = [ ['icon' => 'icon-cogs', 'title' => 'Dashboard', 'link' => 'index.php?option=com_mokosuite'], ['icon' => 'fa-solid fa-handshake-angle', 'title' => 'Helpdesk', 'link' => 'index.php?option=com_mokosuite&view=tickets'], ['icon' => 'icon-puzzle-piece', 'title' => 'Extensions', 'link' => 'index.php?option=com_mokosuite&view=extensions'], ['icon' => 'fa-solid fa-file-code', 'title' => '.htaccess Maker', 'link' => 'index.php?option=com_mokosuite&view=htaccess'], ['icon' => 'icon-lock', 'title' => 'Privacy Guard', 'link' => 'index.php?option=com_mokosuite&view=privacy'], ['icon' => 'icon-shield-alt', 'title' => 'WAF Log', 'link' => 'index.php?option=com_mokosuite&view=waflog'], ['icon' => 'icon-database', 'title' => 'Database Tools', 'link' => 'index.php?option=com_mokosuite&view=database'], ['icon' => 'icon-trash', 'title' => 'Cache Cleanup', 'link' => 'index.php?option=com_mokosuite&view=cleanup'], ['icon' => 'icon-power-off', 'title' => 'Feature Plugins', 'link' => 'index.php?option=com_plugins&filter[folder]=system&filter[search]=mokosuite'], ]; // ── Auto-discover all Moko components from #__menu ────────────────── $mokoComponents = []; try { $db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class); $db->setQuery( "SELECT m.id, m.title, m.link, m.level, m.parent_id, m.img, e.element" . " FROM " . $db->quoteName('#__menu') . " m" . " LEFT JOIN " . $db->quoteName('#__extensions') . " e ON m.component_id = e.extension_id" . " WHERE m.client_id = 1 AND m.level >= 1 AND m.published = 1" . " AND e.element LIKE 'com_moko%'" . " AND e.enabled = 1" . " ORDER BY e.element, m.level, m.lft" ); $menuItems = $db->loadObjectList() ?: []; // Load language files for discovered components $lang = Factory::getLanguage(); $loadedLangs = []; foreach ($menuItems as $m) { if (!isset($loadedLangs[$m->element])) { $lang->load($m->element . '.sys', JPATH_ADMINISTRATOR); $lang->load($m->element, JPATH_ADMINISTRATOR); $loadedLangs[$m->element] = true; } } // Group: level 1 = component parent, level 2 = children foreach ($menuItems as $m) { if ((int) $m->level === 1) { $mokoComponents[$m->element] = [ 'id' => $m->id, 'title' => Text::_($m->title), 'link' => $m->link, 'icon' => str_replace('class:', 'icon-', $m->img ?: 'class:puzzle-piece'), 'element' => $m->element, 'children' => [], ]; } elseif ((int) $m->level === 2 && isset($mokoComponents[$m->element])) { $mokoComponents[$m->element]['children'][] = [ 'title' => Text::_($m->title), 'link' => $m->link, 'icon' => str_replace('class:', 'icon-', $m->img ?: 'class:cog'), ]; } } } catch (\Throwable $e) { // Silent — menu works without auto-discovered components } // Override com_mokosuite children with static views if (isset($mokoComponents['com_mokosuite'])) { $mokoComponents['com_mokosuite']['children'] = $mokosuiteStaticViews; $mokoComponents['com_mokosuite']['icon'] = 'icon-shield-alt'; } else { // com_mokosuite not in admin menu — add it manually $mokoComponents['com_mokosuite'] = [ 'id' => 0, 'title' => 'MokoSuite', 'link' => 'index.php?option=com_mokosuite', 'icon' => 'icon-shield-alt', 'element' => 'com_mokosuite', 'children' => $mokosuiteStaticViews, ]; } // ── Sort: com_mokosuitehq first, then alphabetical by title ───────── $hq = null; $rest = []; foreach ($mokoComponents as $key => $comp) { if ($key === 'com_mokosuitehq') { $hq = $comp; } else { $rest[$key] = $comp; } } usort($rest, fn($a, $b) => strcasecmp($a['title'], $b['title'])); $sorted = []; if ($hq !== null) { $sorted[] = $hq; } foreach ($rest as $comp) { $sorted[] = $comp; } ?>