Files
api/services/nginx/app/classes/router.php
T
Jepp9350 d9638406d3 Implement route-level permission handling.
Added support for defining and registering permissions for API routes. Updated methods across the router and route traits to accommodate permission details, enabling better access control. Enhanced department license plate lookup with session validation and additional endpoints.
2025-02-20 14:12:21 +01:00

128 lines
3.6 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'] ?? ($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 (\Exception $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;
}
}