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.
128 lines
3.6 KiB
PHP
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;
|
|
}
|
|
} |