url = $_SERVER['REQUEST_URI'] ?? ($argv[1] ?? '/'); // Get the URL (Or the first argument if it's a CLI request) $this->method = $_SERVER['REQUEST_METHOD'] ?? ($argv[2] ?? 'GET'); // Get the method (Or the second argument if it's a CLI request) $this->routes = []; $this->routeClasses = []; } public function add($route, $method, $function, array $permissions = []): void { $this->routes[] = ['route' => $route, 'method' => $method, 'function' => $function, 'permissions' => $permissions]; } public function auto_load_routes(string $path): void { global $response; $files = scandir($path); foreach ( $files as $file ) { if ($file == '.' || $file == '..') { continue; } require_once $path . '/' . $file; } // Get all the classes in the files with the route_t trait $classes = get_declared_classes(); foreach ( $classes as $class ) { if (in_array('traits\route_t', class_uses($class))) { $this->routeClasses[] = $class; } } // Try to run the routes, if there is an error, catch it and send an internal server error response try { $this->run(); } catch (\Throwable $e) { $response->internal_server_error($e->getMessage()); } } public function run(): void { foreach ( $this->routeClasses as $class ) { $route = new $class(); // Add the routes to the router $route->run(); } $this->routeRequest(); } private function routeRequest(): void { global $response; $matching_route_found = false; foreach ( $this->routes as $route ) { if ($this->doesRouteMatchCurrent($route['route']) && $route['method'] == $this->method) { $route['function'](); $matching_route_found = true; } } if ($matching_route_found) { $response->matching_route_found(); } else { $response->not_found(); } } private function doesRouteMatchCurrent($route): bool { // Check if the route matches the current URL or if it matches the regex pattern // Remove the query string $this->url = explode('?', $this->url)[0]; // Exact match if ($route == $this->url) { return true; } // Regex $route = str_replace('/', '\/', $route); $route = preg_replace('/{[a-zA-Z0-9_]+}/', '([a-zA-Z0-9]+)', $route); if (preg_match('/^' . $route . '$/', $this->url)) { return true; } // None of the matches were found return false; } public function ERROR_HANDLER($callback): void { try { $callback(); } catch (\Exception $e) { global $response; $response->internal_server_error($e->getMessage()); } } public function countRoutes(): int { return count($this->routes); } public function getPermissions(): array { $permissions = []; foreach ( $this->routes as $route ) { $permissions = array_merge($permissions, $route['permissions']); } return $permissions; } public function getRoutes(): array { return $this->routes; } }