| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-29 16:21:08 +00:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-11-29 16:38:49 +00:00
										 |  |  |  * class Router | 
					
						
							| 
									
										
										
										
											2024-11-29 16:21:08 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * A simple Router class to manage URL-to-callback mapping and dispatch requests to the appropriate controllers and methods. | 
					
						
							|  |  |  |  * The class supports defining routes, matching URLs against patterns, and invoking callbacks for matched routes. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  | class Router { | 
					
						
							| 
									
										
										
										
											2024-11-29 16:21:08 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @var array $routes Associative array of route patterns and their corresponding callbacks. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |     private $routes = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-29 16:21:08 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Adds a new route to the router. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $pattern  The URL pattern to match (regular expression). | 
					
						
							|  |  |  |      * @param string $callback The callback for the route in the format "Controller@Method". | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return void | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-11-29 16:25:09 +00:00
										 |  |  |     public function add($pattern, $callback) { | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |         $this->routes[$pattern] = $callback; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-29 16:21:08 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Dispatches a request to the appropriate route callback. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $url The URL to match against the defined routes. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return void Outputs the result of the invoked callback or a 404 error if no route matches. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |     public function dispatch($url) { | 
					
						
							| 
									
										
										
										
											2024-11-29 16:25:09 +00:00
										 |  |  |         // remove query string variables from url
 | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |         $url = strtok($url, '?'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach ($this->routes as $pattern => $callback) { | 
					
						
							| 
									
										
										
										
											2024-11-29 16:25:09 +00:00
										 |  |  |             // check if the URL matches the current route pattern
 | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |             if (preg_match('#^' . $pattern . '$#', $url, $matches)) { | 
					
						
							| 
									
										
										
										
											2024-11-29 16:25:09 +00:00
										 |  |  |                 // remove the exact match to extrat parameters
 | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |                 array_shift($matches); | 
					
						
							|  |  |  |                 return $this->invoke($callback, $matches); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // if there was no match at all, return 404
 | 
					
						
							|  |  |  |         http_response_code(404); | 
					
						
							|  |  |  |         echo '404 page not found'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-29 16:21:08 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Invokes the callback for a matched route. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $callback The callback for the route in the format "Controller@Method". | 
					
						
							|  |  |  |      * @param array  $params   Parameters extracted from the route pattern. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return void Executes the specified method on the specified controller with the provided parameters. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @throws Exception If the controller class or method does not exist. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |     private function invoke($callback, $params) { | 
					
						
							|  |  |  |         list($controllerName, $methodName) = explode('@', $callback); | 
					
						
							| 
									
										
										
										
											2024-11-29 16:25:09 +00:00
										 |  |  |         $controllerClass = "../pages/$controllerName"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // ensure the controller class exists
 | 
					
						
							|  |  |  |         if (!class_exists($controllerClass)) { | 
					
						
							|  |  |  |             throw new Exception("Controller '$controllerClass' not found."); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |         $controller = new $controllerClass(); | 
					
						
							| 
									
										
										
										
											2024-11-29 16:25:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // ensure the method exists on the controller
 | 
					
						
							|  |  |  |         if (!method_exists($controller, $methodName)) { | 
					
						
							|  |  |  |             throw new Exception("Method '$methodName' not found in controller '$controllerClass'."); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // call the controller's method with the parameters
 | 
					
						
							| 
									
										
										
										
											2024-08-14 07:11:36 +00:00
										 |  |  |         call_user_func_array([$controller, $methodName], $params); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ?>
 |