4b9a675d0f
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Project CI / Lint & Validate (push) Successful in 36s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 40s
Generic: Project CI / Tests (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: moko-platform CI / Gate 4: Governance (push) Has been cancelled
Platform: moko-platform CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: moko-platform CI / CI Summary (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
All Joomla element names, PHP classes, language files, folder structure, and manifest references renamed from mokosuite to mokosuiteclient. This repo is now the client-facing tracker for the MokoSuite platform.
146 lines
3.9 KiB
PHP
146 lines
3.9 KiB
PHP
<?php
|
|
/**
|
|
* @package MokoSuiteClient
|
|
* @subpackage com_mokosuiteclient
|
|
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
|
* @license GNU General Public License version 3 or later; see LICENSE
|
|
*/
|
|
|
|
namespace Moko\Component\MokoSuiteClient\Api\Controller;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\MVC\Controller\BaseController;
|
|
use Joomla\CMS\Plugin\PluginHelper;
|
|
use Joomla\CMS\Uri\Uri;
|
|
use Joomla\CMS\Version;
|
|
use Joomla\Registry\Registry;
|
|
|
|
/**
|
|
* Dashboard summary API controller.
|
|
*
|
|
* GET /api/index.php/v1/mokosuiteclient/dashboard
|
|
*
|
|
* Returns a combined payload of site info and feature plugin states,
|
|
* suitable for remote dashboards and monitoring.
|
|
*
|
|
* @since 02.32.00
|
|
*/
|
|
class DashboardController extends BaseController
|
|
{
|
|
/**
|
|
* Return dashboard summary data.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function displayList(): void
|
|
{
|
|
$app = Factory::getApplication();
|
|
$user = $app->getIdentity();
|
|
|
|
if (!$user->authorise('core.manage', 'com_plugins'))
|
|
{
|
|
$this->sendJson(403, ['error' => 'Not authorized']);
|
|
|
|
return;
|
|
}
|
|
|
|
$config = Factory::getConfig();
|
|
$db = Factory::getDbo();
|
|
|
|
// Package version
|
|
$query = $db->getQuery(true)
|
|
->select($db->quoteName('manifest_cache'))
|
|
->from($db->quoteName('#__extensions'))
|
|
->where($db->quoteName('element') . ' = ' . $db->quote('pkg_mokosuiteclient'))
|
|
->where($db->quoteName('type') . ' = ' . $db->quote('package'));
|
|
$db->setQuery($query);
|
|
$pkgCache = json_decode($db->loadResult() ?? '{}');
|
|
|
|
// Feature plugins
|
|
$query = $db->getQuery(true)
|
|
->select([
|
|
$db->quoteName('extension_id'),
|
|
$db->quoteName('name'),
|
|
$db->quoteName('element'),
|
|
$db->quoteName('folder'),
|
|
$db->quoteName('enabled'),
|
|
$db->quoteName('manifest_cache'),
|
|
])
|
|
->from($db->quoteName('#__extensions'))
|
|
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
|
|
->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
|
|
->where('(' . $db->quoteName('element') . ' = ' . $db->quote('mokosuiteclient')
|
|
. ' OR ' . $db->quoteName('element') . ' LIKE ' . $db->quote('mokosuiteclient\\_%') . ')')
|
|
->order($db->quoteName('element') . ' ASC');
|
|
$db->setQuery($query);
|
|
$pluginRows = $db->loadObjectList() ?: [];
|
|
|
|
$plugins = [];
|
|
|
|
foreach ($pluginRows as $row)
|
|
{
|
|
$manifest = json_decode($row->manifest_cache ?? '{}');
|
|
$plugins[] = [
|
|
'extension_id' => (int) $row->extension_id,
|
|
'name' => $row->name,
|
|
'element' => $row->element,
|
|
'enabled' => (bool) $row->enabled,
|
|
'version' => $manifest->version ?? '',
|
|
];
|
|
}
|
|
|
|
// Quick health checks
|
|
$dbOk = true;
|
|
|
|
try
|
|
{
|
|
$db->setQuery('SELECT 1');
|
|
$db->loadResult();
|
|
}
|
|
catch (\Throwable $e)
|
|
{
|
|
$dbOk = false;
|
|
}
|
|
|
|
$freeDiskMb = null;
|
|
$free = @disk_free_space(JPATH_ROOT);
|
|
|
|
if ($free !== false)
|
|
{
|
|
$freeDiskMb = round($free / 1048576);
|
|
}
|
|
|
|
$this->sendJson(200, [
|
|
'status' => 'ok',
|
|
'timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
|
|
'site' => [
|
|
'name' => $config->get('sitename', ''),
|
|
'url' => rtrim(Uri::root(), '/'),
|
|
'mokosuiteclient_version' => $pkgCache->version ?? '',
|
|
'joomla_version' => (new Version())->getShortVersion(),
|
|
'php_version' => PHP_VERSION,
|
|
'db_type' => $db->getServerType(),
|
|
'debug' => (bool) $config->get('debug'),
|
|
'offline' => (bool) $config->get('offline'),
|
|
'caching' => (int) $config->get('caching'),
|
|
],
|
|
'health' => [
|
|
'database' => $dbOk ? 'ok' : 'error',
|
|
'free_disk_mb' => $freeDiskMb,
|
|
],
|
|
'plugins' => $plugins,
|
|
]);
|
|
}
|
|
|
|
private function sendJson(int $code, array $payload): void
|
|
{
|
|
$app = Factory::getApplication();
|
|
$app->setHeader('Content-Type', 'application/json', true);
|
|
$app->setHeader('Status', (string) $code, true);
|
|
echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
|
|
$app->close();
|
|
}
|
|
}
|