| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Messages { | 
					
						
							|  |  |  |     // Message types
 | 
					
						
							|  |  |  |     const TYPE_SUCCESS = 'success'; | 
					
						
							|  |  |  |     const TYPE_ERROR = 'danger'; | 
					
						
							|  |  |  |     const TYPE_INFO = 'info'; | 
					
						
							|  |  |  |     const TYPE_WARNING = 'warning'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |     // Default message configurations
 | 
					
						
							|  |  |  |     const NOTICE = [ | 
					
						
							|  |  |  |         'DEFAULT' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_INFO, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const ERROR = [ | 
					
						
							|  |  |  |         'DEFAULT' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => false | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const LOGIN = [ | 
					
						
							|  |  |  |         'LOGIN_SUCCESS' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_SUCCESS, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'LOGIN_FAILED' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => false | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'LOGOUT_SUCCESS' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_SUCCESS, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'IP_BLACKLISTED' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => false | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'IP_NOT_WHITELISTED' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => false | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'TOO_MANY_ATTEMPTS' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => false | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |     const SECURITY = [ | 
					
						
							|  |  |  |         'WHITELIST_ADD_SUCCESS' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_SUCCESS, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'WHITELIST_ADD_ERROR' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'WHITELIST_REMOVE_SUCCESS' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_SUCCESS, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'WHITELIST_REMOVE_ERROR' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'BLACKLIST_ADD_SUCCESS' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_SUCCESS, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'BLACKLIST_ADD_ERROR' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'BLACKLIST_REMOVE_SUCCESS' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_SUCCESS, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'BLACKLIST_REMOVE_ERROR' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => true | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'RATE_LIMIT_INFO' => [ | 
					
						
							|  |  |  |             'type' => self::TYPE_INFO, | 
					
						
							|  |  |  |             'dismissible' => false | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |         'PERMISSION_DENIED' => [ | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => false | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |         'IP_REQUIRED' => [ | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |             'type' => self::TYPE_ERROR, | 
					
						
							|  |  |  |             'dismissible' => false | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |     private static $strings = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get message strings | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private static function getStrings() { | 
					
						
							|  |  |  |         if (self::$strings === null) { | 
					
						
							|  |  |  |             self::$strings = require __DIR__ . '/../includes/messages-strings.php'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return self::$strings; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get message configuration by key | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function get($category, $key) { | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |         $config = constant("self::$category")[$key] ?? null; | 
					
						
							|  |  |  |         if (!$config) return null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $strings = self::getStrings(); | 
					
						
							|  |  |  |         $message = $strings[$category][$key] ?? ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return array_merge($config, ['message' => $message]); | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Render message HTML | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-01-07 11:02:57 +00:00
										 |  |  |     // Usage: echo Messages::render('LOGIN', 'LOGIN_SUCCESS', 'custom message [or null]', true [for dismissible; or null], true [for small; or omit]);
 | 
					
						
							| 
									
										
										
										
											2025-01-15 16:22:49 +00:00
										 |  |  |     public static function render($category, $key, $customMessage = null, $dismissible = null, $small = false, $sanitize = true) { | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |         $config = self::get($category, $key); | 
					
						
							|  |  |  |         if (!$config) return ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $message = $customMessage ?? $config['message']; | 
					
						
							| 
									
										
										
										
											2025-01-07 11:02:57 +00:00
										 |  |  |         $isDismissible = $dismissible ?? $config['dismissible'] ?? false; | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |         $dismissClass = $isDismissible ? ' alert-dismissible fade show' : ''; | 
					
						
							| 
									
										
										
										
											2025-01-06 09:43:20 +00:00
										 |  |  |         $dismissButton = $isDismissible ? '<button type="button" class="btn-close' . ($small ? ' btn-close-sm' : '') . '" data-bs-dismiss="alert" aria-label="Close"></button>' : ''; | 
					
						
							|  |  |  |         $smallClass = $small ? ' alert-sm' : ''; | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return sprintf( | 
					
						
							| 
									
										
										
										
											2025-01-06 09:43:20 +00:00
										 |  |  |             '<div class="alert alert-%s%s%s" role="alert">%s%s</div>', | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |             $config['type'], | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |             $dismissClass, | 
					
						
							| 
									
										
										
										
											2025-01-06 09:43:20 +00:00
										 |  |  |             $smallClass, | 
					
						
							| 
									
										
										
										
											2025-01-15 16:22:49 +00:00
										 |  |  |             $sanitize ? htmlspecialchars($message) : $message, | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |             $dismissButton | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-23 10:37:10 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get message data for JavaScript | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getMessageData($category, $key, $customMessage = null, $dismissible = null, $small = false) { | 
					
						
							|  |  |  |         $config = self::get($category, $key); | 
					
						
							|  |  |  |         if (!$config) return null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return [ | 
					
						
							|  |  |  |             'type' => $config['type'], | 
					
						
							|  |  |  |             'message' => $customMessage ?? $config['message'], | 
					
						
							|  |  |  |             'dismissible' => $dismissible ?? $config['dismissible'] ?? false, | 
					
						
							|  |  |  |             'small' => $small | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Store message in session for display after redirect | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-01-07 11:02:57 +00:00
										 |  |  |     // Usage: Messages::flash('LOGIN', 'LOGIN_SUCCESS', 'custom message [or null]', true [for dismissible; or null], true [for small; or omit]);
 | 
					
						
							|  |  |  |     public static function flash($category, $key, $customMessage = null, $dismissible = null, $small = false) { | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |         if (!isset($_SESSION['flash_messages'])) { | 
					
						
							|  |  |  |             $_SESSION['flash_messages'] = []; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-01-07 11:02:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Get the message configuration
 | 
					
						
							|  |  |  |         $config = self::get($category, $key); | 
					
						
							|  |  |  |         $isDismissible = $dismissible ?? $config['dismissible'] ?? false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |         $_SESSION['flash_messages'][] = [ | 
					
						
							|  |  |  |             'category' => $category, | 
					
						
							|  |  |  |             'key' => $key, | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |             'custom_message' => $customMessage, | 
					
						
							| 
									
										
										
										
											2025-01-07 11:02:57 +00:00
										 |  |  |             'dismissible' => $isDismissible, | 
					
						
							| 
									
										
										
										
											2025-01-06 09:43:20 +00:00
										 |  |  |             'small' => $small | 
					
						
							| 
									
										
										
										
											2025-01-04 12:22:53 +00:00
										 |  |  |         ]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get and clear all flash messages | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getFlash() { | 
					
						
							|  |  |  |         $messages = $_SESSION['flash_messages'] ?? []; | 
					
						
							|  |  |  |         unset($_SESSION['flash_messages']); | 
					
						
							|  |  |  |         return $messages; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |