108 lines
3.0 KiB
PHP
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;
|
|
}
|
|
} |