| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Theme Helper | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Handles theme management and template/asset loading for the application. | 
					
						
							|  |  |  |  * Supports multiple themes with fallback to default theme when needed. | 
					
						
							|  |  |  |  * The default theme uses app/templates and public_html/static as fallbacks/ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace App\Helpers; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use Exception; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  | // Include Session class
 | 
					
						
							|  |  |  | require_once __DIR__ . '/../classes/session.php'; | 
					
						
							|  |  |  | use Session; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  | class Theme | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @var array Theme configuration | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private static $config; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the theme configuration | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getConfig() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-09-12 08:56:55 +00:00
										 |  |  |         $configFile = __DIR__ . '/../config/theme.php'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Create default config if it doesn't exist
 | 
					
						
							|  |  |  |         if (!file_exists($configFile)) { | 
					
						
							|  |  |  |             $configDir = dirname($configFile); | 
					
						
							|  |  |  |             if (!is_dir($configDir)) { | 
					
						
							|  |  |  |                 mkdir($configDir, 0755, true); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Generate the config file with proper formatting
 | 
					
						
							|  |  |  |             $configContent = <<<'EOT' | 
					
						
							|  |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Theme Configuration | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is auto-generated. Do not edit it manually. | 
					
						
							|  |  |  |  * Use the theme management interface to modify theme settings. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | return [ | 
					
						
							|  |  |  |     // Active theme (can be overridden by user preference)
 | 
					
						
							|  |  |  |     'active_theme' => 'modern', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Available themes with their display names
 | 
					
						
							|  |  |  |     'available_themes' => [ | 
					
						
							|  |  |  |         'default' => 'Default built-in theme', | 
					
						
							|  |  |  |         'modern' => 'Modern theme', | 
					
						
							|  |  |  |         'retro' => 'Alternative retro theme' | 
					
						
							|  |  |  |     ], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Path configurations
 | 
					
						
							|  |  |  |     'paths' => [ | 
					
						
							|  |  |  |         // Base directory for all external themes
 | 
					
						
							|  |  |  |         'themes' => __DIR__ . '/../../themes', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Default templates location (built-in fallback)
 | 
					
						
							|  |  |  |         'templates' => __DIR__ . '/../templates', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Public assets directory (built-in fallback)
 | 
					
						
							|  |  |  |         'public' => __DIR__ . '/../../public_html' | 
					
						
							|  |  |  |     ], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Theme configuration defaults
 | 
					
						
							|  |  |  |     'default_config' => [ | 
					
						
							|  |  |  |         'name' => 'Unnamed Theme', | 
					
						
							|  |  |  |         'description' => 'A Jilo Web theme', | 
					
						
							|  |  |  |         'version' => '1.0.0', | 
					
						
							|  |  |  |         'author' => 'Lindeas Inc.', | 
					
						
							|  |  |  |         'screenshot' => 'screenshot.png', | 
					
						
							|  |  |  |         'options' => [] | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EOT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             file_put_contents($configFile, $configContent); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Load the configuration
 | 
					
						
							|  |  |  |         self::$config = require $configFile; | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |         return self::$config; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @var string Current theme name | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private static $currentTheme; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Initialize the theme system | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function init() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-06-10 08:55:06 +00:00
										 |  |  |         // Only load config if not already loaded
 | 
					
						
							|  |  |  |         if (self::$config === null) { | 
					
						
							| 
									
										
										
										
											2025-09-12 08:56:55 +00:00
										 |  |  |             try { | 
					
						
							|  |  |  |                 self::getConfig(); // This will create default config if needed
 | 
					
						
							|  |  |  |             } catch (Exception $e) { | 
					
						
							|  |  |  |                 error_log('Failed to load theme configuration: ' . $e->getMessage()); | 
					
						
							|  |  |  |                 // Fallback to default configuration
 | 
					
						
							|  |  |  |                 self::$config = [ | 
					
						
							|  |  |  |                     'active_theme' => 'modern', | 
					
						
							|  |  |  |                     'available_themes' => [ | 
					
						
							|  |  |  |                         'modern' => ['name' => 'Modern'], | 
					
						
							|  |  |  |                         'retro' => ['name' => 'Retro'] | 
					
						
							|  |  |  |                     ] | 
					
						
							|  |  |  |                 ]; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-06-10 08:55:06 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-09-12 08:56:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         self::$currentTheme = self::getCurrentThemeName(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the current theme name | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getCurrentThemeName() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-06-10 08:55:06 +00:00
										 |  |  |         // Ensure session is started
 | 
					
						
							|  |  |  |         if (session_status() === PHP_SESSION_NONE) { | 
					
						
							|  |  |  |             Session::startSession(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         // Check if already determined
 | 
					
						
							|  |  |  |         if (self::$currentTheme !== null) { | 
					
						
							|  |  |  |             return self::$currentTheme; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  |         // Try to get from session first
 | 
					
						
							| 
									
										
										
										
											2025-06-23 11:08:11 +00:00
										 |  |  |         $sessionTheme = isset($_SESSION['theme']) ? $_SESSION['theme'] : null; | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  |         if ($sessionTheme && isset(self::$config['available_themes'][$sessionTheme])) { | 
					
						
							|  |  |  |             self::$currentTheme = $sessionTheme; | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2025-09-24 13:56:14 +00:00
										 |  |  |             // Attempt to load per-user theme from DB if user is logged in and userObject is available
 | 
					
						
							|  |  |  |             if (Session::isValidSession() && isset($_SESSION['user_id']) && isset($GLOBALS['userObject']) && is_object($GLOBALS['userObject']) && method_exists($GLOBALS['userObject'], 'getUserTheme')) { | 
					
						
							|  |  |  |                 try { | 
					
						
							|  |  |  |                     $dbTheme = $GLOBALS['userObject']->getUserTheme((int)$_SESSION['user_id']); | 
					
						
							|  |  |  |                     if ($dbTheme && isset(self::$config['available_themes'][$dbTheme]) && self::themeExists($dbTheme)) { | 
					
						
							|  |  |  |                         // Set session and current theme to the user's stored preference
 | 
					
						
							|  |  |  |                         $_SESSION['theme'] = $dbTheme; | 
					
						
							|  |  |  |                         self::$currentTheme = $dbTheme; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } catch (\Throwable $e) { | 
					
						
							|  |  |  |                     // Ignore and continue to default fallback
 | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Fall back to default theme if still not determined
 | 
					
						
							|  |  |  |             if (self::$currentTheme === null) { | 
					
						
							|  |  |  |                 self::$currentTheme = self::$config['active_theme']; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return self::$currentTheme; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the URL for a theme asset | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $themeId Theme ID | 
					
						
							|  |  |  |      * @param string $assetPath Path to the asset relative to theme directory (e.g., 'css/style.css') | 
					
						
							|  |  |  |      * @return string|null URL to the asset or null if not found | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getAssetUrl($themeId, $assetPath = '') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Clean and validate the asset path
 | 
					
						
							|  |  |  |         $assetPath = ltrim($assetPath, '/'); | 
					
						
							|  |  |  |         if (empty($assetPath)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Only allow alphanumeric, hyphen, underscore, dot, and forward slash
 | 
					
						
							|  |  |  |         if (!preg_match('/^[a-zA-Z0-9_\-\.\/]+$/', $assetPath)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Prevent directory traversal
 | 
					
						
							|  |  |  |         if (strpos($assetPath, '..') !== false) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $fullPath = __DIR__ . "/../../themes/$themeId/$assetPath"; | 
					
						
							|  |  |  |         if (!file_exists($fullPath) || !is_readable($fullPath)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-26 11:27:54 +00:00
										 |  |  |         // Generate URL that goes through index.php
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  |         global $app_root; | 
					
						
							| 
									
										
										
										
											2025-06-26 11:27:54 +00:00
										 |  |  |         // Remove any trailing slash from app_root to avoid double slashes
 | 
					
						
							|  |  |  |         $baseUrl = rtrim($app_root, '/'); | 
					
						
							|  |  |  |         return "$baseUrl/?page=theme-asset&theme=" . urlencode($themeId) . "&path=" . urlencode($assetPath); | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Set the current theme for the session | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $themeName | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-09-24 13:56:14 +00:00
										 |  |  |     public static function setCurrentTheme(string $themeName, bool $persist = true): bool | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (!self::themeExists($themeName)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-10 08:55:06 +00:00
										 |  |  |         // Update session
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         if (Session::isValidSession()) { | 
					
						
							| 
									
										
										
										
											2025-06-26 11:48:51 +00:00
										 |  |  |             $_SESSION['theme'] = $themeName; | 
					
						
							| 
									
										
										
										
											2025-06-10 08:55:06 +00:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-26 11:48:51 +00:00
										 |  |  |         // Clear the current theme cache
 | 
					
						
							|  |  |  |         self::$currentTheme = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-24 13:56:14 +00:00
										 |  |  |         // Persist per-user preference in DB when available and requested
 | 
					
						
							|  |  |  |         if ($persist && Session::isValidSession() && isset($_SESSION['user_id'])) { | 
					
						
							|  |  |  |             // Try to use existing user object if available
 | 
					
						
							|  |  |  |             if (isset($GLOBALS['userObject']) && is_object($GLOBALS['userObject']) && method_exists($GLOBALS['userObject'], 'setUserTheme')) { | 
					
						
							|  |  |  |                 try { | 
					
						
							|  |  |  |                     $GLOBALS['userObject']->setUserTheme((int)$_SESSION['user_id'], $themeName); | 
					
						
							|  |  |  |                 } catch (\Throwable $e) { | 
					
						
							|  |  |  |                     // Non-fatal: keep session theme even if DB save fails
 | 
					
						
							|  |  |  |                     error_log('Failed to persist user theme: ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2025-06-10 08:55:06 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-06-26 11:48:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-12 08:56:55 +00:00
										 |  |  |         self::$currentTheme = $themeName; | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Check if a theme exists | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $themeName | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function themeExists(string $themeName): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-06-10 08:55:06 +00:00
										 |  |  |         // Default theme always exists as it uses core templates
 | 
					
						
							|  |  |  |         if ($themeName === 'default') { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         $themePath = self::getThemePath($themeName); | 
					
						
							|  |  |  |         return is_dir($themePath) && file_exists("$themePath/config.php"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the path to a theme | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string|null $themeName | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getThemePath(?string $themeName = null): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $themeName = $themeName ?? self::getCurrentThemeName(); | 
					
						
							|  |  |  |         $config = self::getConfig(); | 
					
						
							|  |  |  |         return rtrim($config['paths']['themes'], '/') . "/$themeName"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the URL for a theme asset | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $path | 
					
						
							|  |  |  |      * @param bool $includeVersion | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function asset($path, $includeVersion = false) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $themeName = self::getCurrentThemeName(); | 
					
						
							|  |  |  |         $config = self::getConfig(); | 
					
						
							|  |  |  |         $baseUrl = rtrim($GLOBALS['app_root'] ?? '', '/'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // For non-default themes, use theme assets
 | 
					
						
							|  |  |  |         if ($themeName !== 'default') { | 
					
						
							|  |  |  |             $assetPath = "/themes/{$themeName}/assets/" . ltrim($path, '/'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Add version query string for cache busting
 | 
					
						
							|  |  |  |             if ($includeVersion) { | 
					
						
							|  |  |  |                 $version = self::getThemeVersion($themeName); | 
					
						
							|  |  |  |                 $assetPath .= (strpos($assetPath, '?') !== false ? '&' : '?') . 'v=' . $version; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             // For default theme, use public_html directly
 | 
					
						
							|  |  |  |             $assetPath = '/' . ltrim($path, '/'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $baseUrl . $assetPath; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |      * Include a theme template file | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |      * @param string $template Template name without .php extension | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |      * @return void | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |     public static function include($template) | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-06-16 09:22:26 +00:00
										 |  |  |         global $config; | 
					
						
							|  |  |  |         $config = $config ?? []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $themeConfig = self::getConfig(); | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         $themeName = self::getCurrentThemeName(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |         // We need this here, otherwise because this helper
 | 
					
						
							|  |  |  |         // between index and the views breaks the session vars
 | 
					
						
							|  |  |  |         extract($GLOBALS, EXTR_SKIP | EXTR_REFS); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-16 09:22:26 +00:00
										 |  |  |         // Ensure config is always available in templates
 | 
					
						
							|  |  |  |         $config = array_merge($config, $themeConfig); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |         // For non-default themes, look in the theme directory first
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         if ($themeName !== 'default') { | 
					
						
							|  |  |  |             $themePath = $config['paths']['themes'] . '/' . $themeName . '/views/' . $template . '.php'; | 
					
						
							|  |  |  |             if (file_exists($themePath)) { | 
					
						
							|  |  |  |                 include $themePath; | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-23 06:58:50 +00:00
										 |  |  |         // Fallback to default template location
 | 
					
						
							|  |  |  |         $defaultPath = $config['paths']['templates'] . '/' . $template . '.php'; | 
					
						
							|  |  |  |         if (file_exists($defaultPath)) { | 
					
						
							|  |  |  |             include $defaultPath; | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Log error if template not found
 | 
					
						
							|  |  |  |         error_log("Template not found: {$template} in theme: {$themeName}"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 10:55:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get all available themes | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getAvailableThemes(): array | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-06-01 07:39:39 +00:00
										 |  |  |         $config = self::getConfig(); | 
					
						
							|  |  |  |         $availableThemes = $config['available_themes'] ?? []; | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         $themes = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-01 07:39:39 +00:00
										 |  |  |         // Add default theme if not already present
 | 
					
						
							|  |  |  |         if (!isset($availableThemes['default'])) { | 
					
						
							|  |  |  |             $availableThemes['default'] = 'Default built-in theme'; | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-01 07:39:39 +00:00
										 |  |  |         // Verify each theme exists and has a config file
 | 
					
						
							|  |  |  |         $themesDir = $config['paths']['themes'] ?? (__DIR__ . '/../../themes'); | 
					
						
							|  |  |  |         foreach ($availableThemes as $id => $name) { | 
					
						
							| 
									
										
										
										
											2025-06-10 08:55:06 +00:00
										 |  |  |             if ($id === 'default' || (is_dir("$themesDir/$id") && file_exists("$themesDir/$id/config.php"))) { | 
					
						
							| 
									
										
										
										
											2025-06-01 07:39:39 +00:00
										 |  |  |                 $themes[$id] = $name; | 
					
						
							| 
									
										
										
										
											2025-05-15 11:54:21 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $themes; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Initialize the theme system
 | 
					
						
							|  |  |  | Theme::init(); |