System plugin support: admin menu items, admin routes, API integration

- PluginManager: getAdminMenuItems(), handleAdminRoute(), getPluginType()
- admin.php: load PluginManager, pass plugin_admin_menu to Twig
- admin.php: route to plugin admin pages via handleAdminRoute()
- admin.twig: show 'Plugins' sidebar section for system plugins
- plugins-new.twig: choose content or system plugin type
- handlePluginsNew: generate proper template based on type (content/system)
- plugin-admin.twig: renders plugin output in admin layout
- GeoIPInfo: example system plugin (admin page with GeoIP info)
- System plugins: getAdminMenu(), getAdminRoutes(), handleAdminRoute()
- Content plugins: getSidebarContent() (unchanged)
This commit is contained in:
2026-08-11 18:06:17 +02:00
parent 6daa0a6f49
commit c2bcd7be22
11 changed files with 219 additions and 5 deletions
+41 -3
View File
@@ -27,6 +27,8 @@ require_once __DIR__ . '/../cms/core/class/Cache.php';
require_once __DIR__ . '/../cms/core/class/GeoIP.php';
require_once __DIR__ . '/../cms/core/class/Analytics.php';
require_once __DIR__ . '/../cms/core/class/LogManager.php';
require_once __DIR__ . '/../cms/core/plugin/CMSAPI.php';
require_once __DIR__ . '/../cms/core/plugin/PluginManager.php';
// Initialize dynamic logging from site config
$siteConfigForLogging = file_exists($appConfig['config_json'])
@@ -62,6 +64,15 @@ $twig->addFunction(new \Twig\TwigFunction('role_label', function($role) {
return AdminAuth::getRoleLabel($role);
}));
// Initialize PluginManager for admin (system plugins provide admin menu items)
$siteConfigForPlugins = file_exists($appConfig['config_json'])
? (json_decode(file_get_contents($appConfig['config_json']), true) ?? [])
: [];
$enabledPluginsList = $siteConfigForPlugins['plugins']['enabled'] ?? $siteConfigForPlugins['enabled_plugins'] ?? [];
$adminPluginManager = new PluginManager(__DIR__ . '/../plugins', $enabledPluginsList);
$pluginAdminMenuItems = $adminPluginManager->getAdminMenuItems();
$twig->addGlobal('plugin_admin_menu', $pluginAdminMenuItems);
// Routing
$route = $_GET['route'] ?? '';
@@ -247,7 +258,22 @@ switch ($route) {
break;
default:
handleDashboard($auth, $appConfig, $twig, $user, $csrf, $siteConfig);
// Check if a system plugin handles this route
$pluginContent = $adminPluginManager->handleAdminRoute($route);
if ($pluginContent !== null) {
echo $twig->render('pages/plugin-admin.twig', [
'user' => $user,
'route' => $route,
'csrf_token' => $csrf,
'sidebar_color' => getSidebarColor($appConfig),
'needs_editor' => false,
'message' => '',
'message_type' => 'info',
'plugin_content' => $pluginContent,
]);
} else {
handleDashboard($auth, $appConfig, $twig, $user, $csrf, $siteConfig);
}
}
// ============================================================================
@@ -1109,6 +1135,10 @@ function handlePluginsNew($auth, $config, $twig, $user, $csrf): void
$messageType = 'danger';
} else {
$pluginName = trim($_POST['name'] ?? '');
$pluginType = $_POST['type'] ?? 'content';
if (!in_array($pluginType, ['content', 'system'], true)) {
$pluginType = 'content';
}
if (!empty($pluginName)) {
$pluginName = preg_replace('/[^a-zA-Z0-9_-]/', '-', $pluginName);
$pluginsDir = $config['plugins_dir'];
@@ -1121,11 +1151,19 @@ function handlePluginsNew($auth, $config, $twig, $user, $csrf): void
'name' => ucfirst($pluginName),
'version' => '1.0.0',
'author' => $user['username'],
'type' => $pluginType,
];
file_put_contents($newPluginDir . '/plugin.json', json_encode($pluginJson, JSON_PRETTY_PRINT));
file_put_contents($newPluginDir . '/' . $pluginName . '.php', "<?php\n// Plugin: " . ucfirst($pluginName) . "\n\necho 'Hello from " . $pluginName . "';\n");
adminLog($config, 'info', $user['username'] . ' creëerde plugin ' . $pluginName);
// Generate plugin template based on type
if ($pluginType === 'system') {
$template = "<?php\n\nclass $pluginName\n{\n private ?CMSAPI \$api = null;\n\n public function setAPI(CMSAPI \$api): void\n {\n \$this->api = \$api;\n }\n\n public function getConfig(): array\n {\n return ['title' => ucfirst('$pluginName'), 'type' => 'system'];\n }\n\n // Register admin menu items\n public function getAdminMenu(): array\n {\n return [\n ['label' => ucfirst('$pluginName'), 'route' => '" . strtolower($pluginName) . "', 'icon' => 'bi-gear'],\n ];\n }\n\n // Register admin routes this plugin handles\n public function getAdminRoutes(): array\n {\n return ['" . strtolower($pluginName) . "'];\n }\n\n // Handle admin route\n public function handleAdminRoute(string \$route): void\n {\n // Render your admin page here\n echo '<h1>" . ucfirst($pluginName) . "</h1><p>Systeem plugin admin pagina.</p>';\n }\n}\n";
} else {
$template = "<?php\n\nclass $pluginName\n{\n private ?CMSAPI \$api = null;\n\n public function setAPI(CMSAPI \$api): void\n {\n \$this->api = \$api;\n }\n\n public function getConfig(): array\n {\n return ['title' => ucfirst('$pluginName'), 'type' => 'content'];\n }\n\n public function getSidebarContent(): string\n {\n return '<p>" . ucfirst($pluginName) . " sidebar content.</p>';\n }\n}\n";
}
file_put_contents($newPluginDir . '/' . $pluginName . '.php', $template);
adminLog($config, 'info', $user['username'] . ' creëerde ' . $pluginType . ' plugin ' . $pluginName);
header('Location: /admin/plugins-edit?plugin=' . urlencode($pluginName));
exit;
} else {