api = $api; } /** * Geeft de plugin-configuratie terug. * * @since 2.6.4 * @return array Plugin-configuratie met title, viewable en type. */ public function getConfig(): array { return [ 'title' => 'Dashboard', 'viewable' => false, 'type' => 'system', ]; } /** * Geeft de admin-menu-items voor deze plugin. * * @since 2.6.4 * @return array> Lijst met admin-menu-item configuraties. */ public function getAdminMenu(): array { return [ [ 'plugin' => 'Dashboard', 'route' => 'dashboard', 'label' => 'Dashboard', 'label_key' => 'menu_label', 'icon' => 'bi-speedometer2', 'section' => 'general', 'permission' => 'dashboard', ], ]; } /** * Verwerkt een admin-route en toont het dashboard. * * Geeft een HTML-weergave van site-informatie, content-statistieken * en een plugin-overzicht. * * @since 2.6.4 * @param string $action De uit te voeren actie. * @return string|null De HTML-uitvoer van het dashboard, of null. */ public function handleAdminRoute(string $action): ?string { $siteConfig = $this->getSiteConfig(); $contentDir = $this->api ? $this->api->getContentDir() : ''; $pluginsDir = $this->api ? $this->api->getPluginsDir() : ''; $enabledPlugins = $this->api ? $this->api->getEnabledPlugins() : []; $versionInfo = $this->api ? $this->api->getVersionInfo() : ['version' => '0.0.0']; // Plugin translations (admin context). Falls back to plugin default_language. $t = $this->api ? $this->api->getPluginTranslations('Dashboard') : []; $tr = function (string $key) use ($t): string { return $t[$key] ?? $key; }; $stats = [ 'pages' => $this->countFiles($contentDir, ['md', 'php', 'html']), 'directories' => $this->countDirs($contentDir), 'content_size' => $this->formatSize($this->dirSize($contentDir)), 'config_exists' => !empty($siteConfig), 'php_version' => PHP_VERSION, 'cms_version' => $versionInfo['version'] ?? '0.0.0', 'os' => PHP_OS_FAMILY . ' (' . php_uname('r') . ')', ]; // Build plugin overview $pluginOverview = []; if (is_dir($pluginsDir)) { foreach (glob($pluginsDir . '/*', GLOB_ONLYDIR) as $pluginDir) { $pluginName = basename($pluginDir); $pluginType = $this->getPluginType($pluginDir, $pluginName); $pluginOverview[$pluginName] = [ 'enabled' => in_array($pluginName, $enabledPlugins, true), 'type' => $pluginType, ]; } } ksort($pluginOverview); $siteTitle = $siteConfig['site_title'] ?? 'CodePress'; $defaultLang = $siteConfig['language']['default'] ?? 'nl'; ob_start(); ?>

$info): ?>
De site-configuratie, of een lege array. */ private function getSiteConfig(): array { if ($this->api === null) { return []; } // AdminPluginAPI holds the full site config if ($this->api instanceof AdminPluginAPI) { return $this->api->getConfig('', []) ?? []; } return []; } /** * Bepaalt het type (system of content) van een plugin door het hoofdbestand te lezen. * * @since 2.6.4 * @param string $pluginDir Pad naar de plugin-map. * @param string $pluginName Naam van de plugin. * @return string Het plugin-type ('system' of 'content'). */ private function getPluginType(string $pluginDir, string $pluginName): string { $pluginFile = $pluginDir . '/' . $pluginName . '.php'; if (!file_exists($pluginFile)) { return 'content'; } // Read the file to find 'type' in the config array $source = file_get_contents($pluginFile); if (preg_match("/'type'\s*=>\s*'([^']+)'/", $source, $m)) { return $m[1]; } return 'content'; } /** * Telt het aantal bestanden in een map, eventueel gefilterd op extensie. * * Slaat verborgen en met '-' voorafgegane bestanden en mappen over. * * @since 2.6.4 * @param string $dir Pad naar de map die doorzocht moet worden. * @param string[] $extensions Optionele lijst van toegestane extensies. * @return int Het aantal gevonden bestanden. */ private function countFiles(string $dir, array $extensions = []): int { if (!is_dir($dir)) return 0; $count = 0; $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS) ); foreach ($iterator as $file) { if (!$file->isFile()) continue; // Skip hidden/dash-prefixed $relative = substr($file->getRealPath(), strlen(realpath($dir)) + 1); $skip = false; foreach (explode('/', str_replace('\\', '/', $relative)) as $seg) { if ($seg !== '' && ($seg[0] === '.' || $seg[0] === '-')) { $skip = true; break; } } if ($skip) continue; $ext = strtolower($file->getExtension()); if (empty($extensions) || in_array($ext, $extensions, true)) { $count++; } } return $count; } /** * Telt het aantal submappen in een map, recursief. * * Slaat verborgen en met '-' voorafgegane mappen over. * * @since 2.6.4 * @param string $dir Pad naar de map die doorzocht moet worden. * @return int Het aantal gevonden submappen. */ private function countDirs(string $dir): int { if (!is_dir($dir)) return 0; $count = 0; $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $file) { if ($file->isDir()) { $name = $file->getFilename(); if ($name[0] === '.' || $name[0] === '-') continue; $count++; } } return $count; } /** * Berekent de totale bestandsgrootte in bytes van alle bestanden in een map. * * @since 2.6.4 * @param string $dir Pad naar de map die doorzocht moet worden. * @return int De totale grootte in bytes. */ private function dirSize(string $dir): int { if (!is_dir($dir)) return 0; $size = 0; $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS) ); foreach ($iterator as $file) { if ($file->isFile()) { $size += $file->getSize(); } } return $size; } /** * Formateert een byte-grootte naar een leesbare string met eenheid. * * @since 2.6.4 * @param int $bytes Het aantal bytes. * @return string De geformatteerde grootte met eenheid (bijv. '1.5 MB'). */ private function formatSize(int $bytes): string { if ($bytes <= 0) return '0 B'; $units = ['B', 'KB', 'MB', 'GB']; $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = min($pow, count($units) - 1); $bytes /= pow(1024, $pow); return round($bytes, 2) . ' ' . $units[$pow]; } }