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:
@@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user