mirror of
https://github.com/flarum/core.git
synced 2025-10-17 17:56:14 +02:00
Refactor Route Resolving and Dispatch (#2425)
- Split DispatchRoute. This allows us to run middleware after we figure out which route we're on, but before we actually execute the controller for that route. - By making the route name explicitly available to middlewares, applications like CSRF and floodgate can set patterns based on route names instead of the path, which is an implementation detail. - Support using route name match for CSRF extender, deprecate path match
This commit is contained in:
committed by
GitHub
parent
67741c7a6f
commit
0c95774333
79
src/Http/Middleware/ResolveRoute.php
Normal file
79
src/Http/Middleware/ResolveRoute.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Http\Middleware;
|
||||
|
||||
use FastRoute\Dispatcher;
|
||||
use Flarum\Http\Exception\MethodNotAllowedException;
|
||||
use Flarum\Http\Exception\RouteNotFoundException;
|
||||
use Flarum\Http\RouteCollection;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||
use Psr\Http\Server\RequestHandlerInterface as Handler;
|
||||
|
||||
class ResolveRoute implements Middleware
|
||||
{
|
||||
/**
|
||||
* @var RouteCollection
|
||||
*/
|
||||
protected $routes;
|
||||
|
||||
/**
|
||||
* @var Dispatcher
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
/**
|
||||
* Create the middleware instance.
|
||||
*
|
||||
* @param RouteCollection $routes
|
||||
*/
|
||||
public function __construct(RouteCollection $routes)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given request from our route collection.
|
||||
*
|
||||
* @throws MethodNotAllowedException
|
||||
* @throws RouteNotFoundException
|
||||
*/
|
||||
public function process(Request $request, Handler $handler): Response
|
||||
{
|
||||
$method = $request->getMethod();
|
||||
$uri = $request->getUri()->getPath() ?: '/';
|
||||
|
||||
$routeInfo = $this->getDispatcher()->dispatch($method, $uri);
|
||||
|
||||
switch ($routeInfo[0]) {
|
||||
case Dispatcher::NOT_FOUND:
|
||||
throw new RouteNotFoundException($uri);
|
||||
case Dispatcher::METHOD_NOT_ALLOWED:
|
||||
throw new MethodNotAllowedException($method);
|
||||
case Dispatcher::FOUND:
|
||||
$request = $request
|
||||
->withAttribute('routeName', $routeInfo[1]['name'])
|
||||
->withAttribute('routeHandler', $routeInfo[1]['handler'])
|
||||
->withAttribute('routeParameters', $routeInfo[2]);
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDispatcher()
|
||||
{
|
||||
if (! isset($this->dispatcher)) {
|
||||
$this->dispatcher = new Dispatcher\GroupCountBased($this->routes->getRouteData());
|
||||
}
|
||||
|
||||
return $this->dispatcher;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user