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 6ed29e2c6c
commit a9e3b023de
11 changed files with 219 additions and 5 deletions
+78
View File
@@ -227,4 +227,82 @@ class PluginManager
}
return $urls;
}
/**
* Get admin menu items from system plugins.
* Each system plugin can register admin menu items via getAdminMenu().
* Returns an array of [label, route, icon] tuples.
*
* @return array Admin menu items
*/
public function getAdminMenuItems(): array
{
$items = [];
foreach ($this->plugins as $pluginName => $plugin) {
// Only system plugins provide admin menu items
if (method_exists($plugin, 'getConfig')) {
$config = $plugin->getConfig();
if (($config['type'] ?? 'content') !== 'system') {
continue;
}
}
if (method_exists($plugin, 'getAdminMenu')) {
$menuItems = $plugin->getAdminMenu();
if (is_array($menuItems)) {
foreach ($menuItems as $item) {
$items[] = $item;
}
}
}
}
return $items;
}
/**
* Handle an admin route for a system plugin.
* Called when a route matches a plugin's registered admin route.
* Returns the rendered content string, or null if no plugin handled it.
*
* @param string $route The admin route
* @return string|null Rendered content or null if not handled
*/
public function handleAdminRoute(string $route): ?string
{
foreach ($this->plugins as $pluginName => $plugin) {
if (method_exists($plugin, 'getConfig')) {
$config = $plugin->getConfig();
if (($config['type'] ?? 'content') !== 'system') {
continue;
}
}
if (method_exists($plugin, 'getAdminRoutes')) {
$routes = $plugin->getAdminRoutes();
if (is_array($routes) && in_array($route, $routes, true)) {
ob_start();
$plugin->handleAdminRoute($route);
return ob_get_clean();
}
}
}
return null;
}
/**
* Get a plugin's type (content or system).
*
* @param string $pluginName Plugin name
* @return string 'content', 'system', or 'content' if unknown
*/
public function getPluginType(string $pluginName): string
{
$pluginDir = $this->pluginsPath . '/' . $pluginName;
$jsonFile = $pluginDir . '/plugin.json';
if (file_exists($jsonFile)) {
$data = json_decode(file_get_contents($jsonFile), true);
return $data['type'] ?? 'content';
}
return 'content';
}
}