Route collection

This commit is contained in:
Maarten 2024-11-26 13:44:53 +01:00
parent e8d8e0e95b
commit d0760ed95c
4 changed files with 128 additions and 61 deletions

View file

@ -3,9 +3,9 @@
use App\Controllers\Api\SubnetController;
use App\Controllers\HomeController;
use App\Controllers\TestController;
use Core\Routing\Router;
use Core\Routing\Route;
Router::get('/', HomeController::class, 'index');
Router::post('/api/subnet', SubnetController::class, 'data');
Router::get('/test/{id}', TestController::class, 'test');
Router::get('/test/{id}/update', TestController::class, 'test');
Route::get('/', HomeController::class, 'index');
Route::post('/api/subnet', SubnetController::class, 'data');
Route::get('/test/{id}', TestController::class, 'test');
Route::get('/test/{id}/update', TestController::class, 'test');

32
src/Routing/Route.php Normal file
View file

@ -0,0 +1,32 @@
<?php
namespace Core\Routing;
class Route
{
/**
* Add GET route
*
* @param string $route
* @param string $controller
* @param string $action
* @return void
*/
public static function get(string $route, string $controller, string $action): void
{
RouteCollection::register($route, $controller, $action, 'GET');
}
/**
* Add POST route
*
* @param string $route
* @param string $controller
* @param string $action
* @return void
*/
public static function post(string $route, string $controller, string $action): void
{
RouteCollection::register($route, $controller, $action, 'POST');
}
}

View file

@ -0,0 +1,90 @@
<?php
namespace Core\Routing;
class RouteCollection
{
/**
* A majestic vault of all defined routes.
*
* @var array
*/
protected static array $routes = [];
/**
* Add a route to the sacred collection.
*
* @param string $route
* @param string $controller
* @param string $action
* @param string $method
* @return void
*/
public static function register(string $route, string $controller, string $action, string $method): void
{
// Transform human-readable route syntax into regex.
$routeRegex = self::convertToRegex($route);
// Store the route in the sacred collection
self::$routes[$method][$routeRegex] = [
'controller' => $controller,
'action' => $action,
'original' => $route,
];
}
/**
* Reveal the treasure trove of routes.
*
* @return array
*/
public static function retrieve(): array
{
return self::$routes;
}
/**
* Convert a route pattern into a regex for matching requests.
*
* @param string $route
* @return string
*/
protected static function convertToRegex(string $route): string
{
$regex = preg_replace('/\{([a-zA-Z0-9_]+)\}/', '(?P<\1>[a-zA-Z0-9_-]+)', $route);
return '#^' . $regex . '$#';
}
/**
* Retrieve a specific route by method and URL.
*
* @param string $method
* @param string $url
* @return array|null
*/
public static function find(string $method, string $url): ?array
{
foreach (self::$routes[$method] ?? [] as $routeRegex => $route) {
if (preg_match($routeRegex, $url, $matches)) {
$route['params'] = array_filter(
$matches,
fn($key) => !is_numeric($key),
ARRAY_FILTER_USE_KEY
);
return $route;
}
}
return null;
}
/**
* Purge all routes from the collection.
*
* @return void
*/
public static function clear(): void
{
self::$routes = [];
}
}

View file

@ -6,61 +6,6 @@ use Core\Http\Request;
class Router
{
/**
* List of routes
*
* @var array
*/
protected static array $routes = [];
/**
* Add GET route
*
* @param string $route
* @param string $controller
* @param string $action
* @return void
*/
public static function get(string $route, string $controller, string $action): void
{
self::register($route, $controller, $action, "GET");
}
/**
* Add POST route
*
* @param string $route
* @param string $controller
* @param string $action
* @return void
*/
public static function post(string $route, string $controller, string $action): void
{
self::register($route, $controller, $action, "POST");
}
/**
* Register route
*
* @param string $route
* @param string $controller
* @param string $action
* @param string $method
* @return void
*/
public static function register(string $route, string $controller, string $action, string $method): void
{
// Convert route with parameters into regex
$routeRegex = preg_replace('/\{([a-zA-Z0-9_]+)\}/', '(?P<\1>[a-zA-Z0-9_-]+)', $route);
$routeRegex = '#^' . $routeRegex . '$#';
self::$routes[$method][$routeRegex] = [
'controller' => $controller,
'action' => $action,
'original' => $route,
];
}
/**
* Dispatch router and run application
*
@ -72,6 +17,6 @@ class Router
$request = new Request($_POST + $_FILES);
// Dispatch router
RouteDispatcher::dispatch($request, self::$routes);
RouteDispatcher::dispatch($request, RouteCollection::retrieve());
}
}