mirror of
				https://github.com/billz/raspap-webgui.git
				synced 2025-03-01 10:31:47 +00:00 
			
		
		
		
	Initial commit
This commit is contained in:
		
							
								
								
									
										31
									
								
								src/RaspAP/Plugins/PluginInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/RaspAP/Plugins/PluginInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Plugin Interface | ||||
|  * | ||||
|  * @description Basic plugin interface for RaspAP | ||||
|  * @author      Bill Zimmerman <billzimmerman@gmail.com> | ||||
|  * @license     https://github.com/raspap/raspap-webgui/blob/master/LICENSE | ||||
|  * @see          | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace RaspAP\Plugins; | ||||
|  | ||||
| use RaspAP\UI\Sidebar; | ||||
|  | ||||
| interface PluginInterface { | ||||
|     /** | ||||
|      * Initialize the plugin | ||||
|      * @param Sidebar $sidebar Sidebar instance for adding items | ||||
|      */ | ||||
|     public function initialize(Sidebar $sidebar): void; | ||||
|  | ||||
|     /** | ||||
|      * Provide template data for rendering | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getTemplateData(): array; | ||||
| } | ||||
|  | ||||
							
								
								
									
										120
									
								
								src/RaspAP/Plugins/PluginManager.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/RaspAP/Plugins/PluginManager.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Plugin Manager class | ||||
|  * | ||||
|  * @description Architecture to support user plugins for RaspAP | ||||
|  * @author      Bill Zimmerman <billzimmerman@gmail.com> | ||||
|  * @license     https://github.com/raspap/raspap-webgui/blob/master/LICENSE | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace RaspAP\Plugins; | ||||
|  | ||||
| use RaspAP\UI\Sidebar; | ||||
|  | ||||
| class PluginManager { | ||||
|     private static $instance = null; | ||||
|     private $plugins = []; | ||||
|     private $sidebar; | ||||
|  | ||||
|     private function __construct() { | ||||
|         $this->pluginPath = 'plugins'; | ||||
|         $this->sidebar = new Sidebar(); | ||||
|         $this->autoloadPlugins(); // autoload plugins on instantiation | ||||
|     } | ||||
|  | ||||
|     // Get the single instance of PluginManager | ||||
|     public static function getInstance(): PluginManager { | ||||
|         if (self::$instance === null) { | ||||
|             self::$instance = new PluginManager(); | ||||
|         } | ||||
|         return self::$instance; | ||||
|     } | ||||
|  | ||||
|     // Autoload plugins found in pluginPath | ||||
|     private function autoloadPlugins(): void { | ||||
|         if (!is_dir($this->pluginPath)) { | ||||
|             return; | ||||
|         } | ||||
|         $directories = array_filter(glob($this->pluginPath . '/*'), 'is_dir'); | ||||
|         foreach ($directories as $dir) { | ||||
|             $pluginName = basename($dir); | ||||
|             $pluginFile = "$dir/$pluginName.php"; | ||||
|  | ||||
|             if (file_exists($pluginFile)) { | ||||
|                 require_once $pluginFile; | ||||
|                 $className = "RaspAP\\Plugins\\$pluginName\\$pluginName"; // Fully qualified class name | ||||
|                 if (class_exists($className)) { | ||||
|                     $plugin = new $className(); | ||||
|                     $this->registerPlugin($plugin); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Registers a plugin by its interface implementation  | ||||
|     private function registerPlugin(PluginInterface $plugin) { | ||||
|         $plugin->initialize($this->sidebar); // pass sidebar to initialize method  | ||||
|         $this->plugins[] = $plugin; // store the plugin instance | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renders a template from inside a plugin directory | ||||
|      * @param string $pluginName | ||||
|      * @param string $templateName | ||||
|      * @param array $__data | ||||
|      */ | ||||
|     public function renderTemplate(string $pluginName, string $templateName, array $__data = []): string { | ||||
|         // Construct the file path for the template | ||||
|         $templateFile = "{$this->pluginPath}/{$pluginName}/templates/{$templateName}.php"; | ||||
|  | ||||
|         if (!file_exists($templateFile)) { | ||||
|             return "Template file {$templateFile} not found."; | ||||
|         } | ||||
|  | ||||
|         // Extract the data for use in the template | ||||
|         if (!empty($__data)) { | ||||
|             extract($__data); | ||||
|         } | ||||
|  | ||||
|         // Start output buffering to capture the template output | ||||
|         ob_start(); | ||||
|         include $templateFile; | ||||
|         return ob_get_clean(); // return the output | ||||
|     } | ||||
|  | ||||
|     // Returns the sidebar | ||||
|     public function getSidebar(): Sidebar { | ||||
|         return $this->sidebar; | ||||
|     } | ||||
|  | ||||
|     // Forwards the page to the responsible plugin | ||||
|     public function handlePageAction(string $page): void { | ||||
|         foreach ($this->getInstalledPlugins() as $plugin) { | ||||
|             if (str_starts_with($page, "/plugin__" . $plugin . "__")) { | ||||
|                 require_once($this->pluginPath . "/" . $plugin . "/functions.php"); | ||||
|                 $function = '\\' . $plugin . '\\pluginHandlePageAction'; | ||||
|                 $function($page); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Returns all installed plugins | ||||
|     public function getInstalledPlugins(): array { | ||||
|         $plugins = []; | ||||
|         if (file_exists($this->pluginPath)) { | ||||
|             $files = scandir($this->pluginPath); | ||||
|             foreach ($files as $file) { | ||||
|                 if ($file === "." || $file === "..") continue; | ||||
|                 $filePath = $this->pluginPath . '/' . $file; | ||||
|                 if (is_dir($filePath)) { | ||||
|                     $plugins[] = $file; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return $plugins; | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										98
									
								
								src/RaspAP/UI/Sidebar.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/RaspAP/UI/Sidebar.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Sidebar UI class | ||||
|  * | ||||
|  * @description A sidebar class for the RaspAP UI, extendable by user plugins | ||||
|  * @author      Bill Zimmerman <billzimmerman@gmail.com> | ||||
|  * @license     https://github.com/raspap/raspap-webgui/blob/master/LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace RaspAP\UI; | ||||
|  | ||||
| class Sidebar { | ||||
|     private $items = []; | ||||
|  | ||||
|     public function __construct() { | ||||
|         // Load default sidebar items | ||||
|         $this->addItem(_('Dashboard'), 'fa-solid fa-gauge-high', 'wlan0_info', 10); | ||||
|         $this->addItem(_('Hotspot'), 'far fa-dot-circle', 'hostapd_conf', 20, | ||||
|             fn() => defined('RASPI_HOTSPOT_ENABLED') && RASPI_HOTSPOT_ENABLED  | ||||
|         ); | ||||
|         $this->addItem(_('DHCP Server'), 'fas fa-exchange-alt', 'dhcpd_conf', 30, | ||||
|             fn() => defined('RASPI_DHCP_ENABLED') && RASPI_DHCP_ENABLED && !$_SESSION["bridgedEnabled"]  | ||||
|         ); | ||||
|         $this->addItem(_('Ad Blocking'), 'far fa-hand-paper', 'adblock_conf', 40, | ||||
|             fn() => defined('RASPI_ADBLOCK_ENABLED') && RASPI_HOTSPOT_ENABLED && !$_SESSION["bridgedEnabled"]  | ||||
|         ); | ||||
|         $this->addItem(_('Networking'), 'fas fa-network-wired', 'network_conf', 50, | ||||
|             fn() => defined('RASPI_NETWORK_ENABLED') && RASPI_NETWORK_ENABLED  | ||||
|         ); | ||||
|         $this->addItem(_('WiFi client'), 'fas fa-wifi', 'wpa_conf', 60, | ||||
|             fn() => defined('RASPI_WIFICLIENT_ENABLED') && RASPI_WIFICLIENT_ENABLED && !$_SESSION["bridgedEnabled"] | ||||
|         ); | ||||
|         $this->addItem(_('OpenVPN'), 'fas fa-key', 'openvpn_conf', 70, | ||||
|             fn() => defined('RASPI_OPENVPN_ENABLED') && RASPI_OPENVPN_ENABLED | ||||
|         ); | ||||
|         $this->addItem(_('WireGuard'), 'ra-wireguard', 'wg_conf', 80, | ||||
|             fn() => defined('RASPI_WIREGUARD_ENABLED') && RASPI_WIREGUARD_ENABLED | ||||
|         ); | ||||
|         $this->addItem(_(getProviderValue($_SESSION["providerID"], "name")), 'fas fa-shield-alt', 'provider_conf', 90, | ||||
|             fn() => defined('RASPI_VPN_PROVIDER_ENABLED') && RASPI_VPN_PROVIDER_ENABLED | ||||
|         ); | ||||
|          $this->addItem(_('Authentication'), 'fas fa-user-lock', 'auth_conf', 100, | ||||
|             fn() => defined('RASPI_CONFAUTH_ENABLED') && RASPI_CONFAUTH_ENABLED  | ||||
|         ); | ||||
|         $this->addItem(_('Data usage'), 'fas fa-chart-area', 'data_use', 110, | ||||
|             fn() => defined('RASPI_VNSTAT_ENABLED') && RASPI_VNSTAT_ENABLED | ||||
|         ); | ||||
|         $this->addItem(_('RestAPI'), 'fas fa-puzzle-piece', 'restapi_conf', 120, | ||||
|             fn() => defined('RASPI_VNSTAT_ENABLED') && RASPI_VNSTAT_ENABLED | ||||
|         ); | ||||
|         $this->addItem(_('System'), 'fas fa-cube', 'data_use', 130, | ||||
|             fn() => defined('RASPI_SYSTEM_ENABLED') && RASPI_SYSTEM_ENABLED | ||||
|         ); | ||||
|         $this->addItem(_('About RaspAP'), 'fas fa-info-circle', 'about', 140); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an item to the sidebar | ||||
|      * @param string $label | ||||
|      * @param string $iconClass | ||||
|      * @param string $link | ||||
|      * @param int $priority | ||||
|      * @param callable $condition | ||||
|      */ | ||||
|     public function addItem(string $label, string $iconClass, string $link, int $priority, callable $condition = null) { | ||||
|         $this->items[] = [ | ||||
|             'label' => $label, | ||||
|             'icon' => $iconClass, | ||||
|             'link' => $link, | ||||
|             'priority' => $priority, | ||||
|             'condition' => $condition | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getItems(): array { | ||||
|         // Sort items by priority and filter by enabled condition | ||||
|         $filteredItems = array_filter($this->items, function ($item) { | ||||
|             return $item['condition'] === null || call_user_func($item['condition']); | ||||
|         }); | ||||
|         usort($filteredItems, function ($a, $b) { | ||||
|             return $a['priority'] <=> $b['priority']; | ||||
|         }); | ||||
|         return $filteredItems; | ||||
|     } | ||||
|  | ||||
|     public function render() { | ||||
|         foreach ($this->getItems() as $item) { | ||||
|             echo "<div class=\"sb-nav-link-icon px-2\"> | ||||
|                   <a class=\"nav-link\" href=\"{$item['link']}\"> | ||||
|                     <i class=\"sb-nav-link-icon {$item['icon']} fa-fw mr-2\"></i> | ||||
|                     <span class=\"nav-label\">{$item['label']}</span> | ||||
|                   </a> | ||||
|                   </div>"; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user