Files
api/classes/router.php
T
2024-12-16 08:54:03 +01:00

108 lines
3.0 KiB
PHP

<?php
namespace classes;
class router
{
private string $url;
private string $method;
private array $routes;
private array $routeClasses; // Contains the classes that have the route_t trait
public function __construct()
{
$this->url = $_SERVER['REQUEST_URI'];
$this->method = $_SERVER['REQUEST_METHOD'];
$this->routes = [];
$this->routeClasses = [];
}
public function add($route, $method, $function): void
{
$this->routes[] = ['route' => $route, 'method' => $method, 'function' => $function];
}
public function run(): void
{
foreach ($this->routeClasses as $class) {
$route = new $class();
// Add the routes to the router
$route->run();
}
$this->routeRequest();
}
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 (\Exception $e) {
$response->internal_server_error($e->getMessage());
}
}
public function ERROR_HANDLER($callback): void
{
try {
$callback();
} catch (\Exception $e) {
global $response;
$response->internal_server_error($e->getMessage());
}
}
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;
}
}