Add pre- and post-route hooks to Router
This commit is contained in:
parent
b0a0f5262e
commit
963e1acd58
|
|
@ -13,6 +13,12 @@ use WellRESTed\Stream\Stream;
|
||||||
|
|
||||||
class Router implements MiddlewareInterface
|
class Router implements MiddlewareInterface
|
||||||
{
|
{
|
||||||
|
/** @var DispatcherInterface */
|
||||||
|
protected $dispatcher;
|
||||||
|
/** @var array Middleware to dispatch before the router evaluates the route. */
|
||||||
|
private $preRouteHooks;
|
||||||
|
/** @var array Middleware to dispatch after the router dispatches all other middleware */
|
||||||
|
private $postRouteHooks;
|
||||||
/** @var array Hash array of status code => error handler */
|
/** @var array Hash array of status code => error handler */
|
||||||
private $statusHandlers;
|
private $statusHandlers;
|
||||||
/** @var RouteTable Collection of routes */
|
/** @var RouteTable Collection of routes */
|
||||||
|
|
@ -20,6 +26,8 @@ class Router implements MiddlewareInterface
|
||||||
/** @var RouteFactoryInterface */
|
/** @var RouteFactoryInterface */
|
||||||
private $routeFactory;
|
private $routeFactory;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->routeFactory = $this->getRouteFactory();
|
$this->routeFactory = $this->getRouteFactory();
|
||||||
|
|
@ -27,6 +35,8 @@ class Router implements MiddlewareInterface
|
||||||
$this->statusHandlers = [];
|
$this->statusHandlers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return a route given a string path, a handler, and optional
|
* Create and return a route given a string path, a handler, and optional
|
||||||
* extra arguments.
|
* extra arguments.
|
||||||
|
|
@ -53,6 +63,22 @@ class Router implements MiddlewareInterface
|
||||||
$this->routeFactory->registerRoute($this->routeTable, $target, $middleware, $extra);
|
$this->routeFactory->registerRoute($this->routeTable, $target, $middleware, $extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addPreRouteHook($middleware)
|
||||||
|
{
|
||||||
|
if (!isset($this->preRouteHooks)) {
|
||||||
|
$this->preRouteHooks = [];
|
||||||
|
}
|
||||||
|
$this->preRouteHooks[] = $middleware;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addPostRouteHook($middleware)
|
||||||
|
{
|
||||||
|
if (!isset($this->postRouteHooks)) {
|
||||||
|
$this->postRouteHooks = [];
|
||||||
|
}
|
||||||
|
$this->postRouteHooks[] = $middleware;
|
||||||
|
}
|
||||||
|
|
||||||
public function setStatusHandler($statusCode, $middleware)
|
public function setStatusHandler($statusCode, $middleware)
|
||||||
{
|
{
|
||||||
$this->statusHandlers[$statusCode] = $middleware;
|
$this->statusHandlers[$statusCode] = $middleware;
|
||||||
|
|
@ -60,6 +86,7 @@ class Router implements MiddlewareInterface
|
||||||
|
|
||||||
public function dispatch(ServerRequestInterface $request, ResponseInterface &$response)
|
public function dispatch(ServerRequestInterface $request, ResponseInterface &$response)
|
||||||
{
|
{
|
||||||
|
$this->disptachPreRouteHooks($request, $response);
|
||||||
try {
|
try {
|
||||||
$this->routeTable->dispatch($request, $response);
|
$this->routeTable->dispatch($request, $response);
|
||||||
} catch (HttpException $e) {
|
} catch (HttpException $e) {
|
||||||
|
|
@ -72,6 +99,7 @@ class Router implements MiddlewareInterface
|
||||||
$dispatcher = $this->getDispatcher();
|
$dispatcher = $this->getDispatcher();
|
||||||
$dispatcher->dispatch($middleware, $request, $response);
|
$dispatcher->dispatch($middleware, $request, $response);
|
||||||
}
|
}
|
||||||
|
$this->disptachPostRouteHooks($request, $response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function respond()
|
public function respond()
|
||||||
|
|
@ -97,7 +125,10 @@ class Router implements MiddlewareInterface
|
||||||
*/
|
*/
|
||||||
protected function getDispatcher()
|
protected function getDispatcher()
|
||||||
{
|
{
|
||||||
return new Dispatcher();
|
if (!isset($this->dispatcher)) {
|
||||||
|
$this->dispatcher = new Dispatcher();
|
||||||
|
}
|
||||||
|
return $this->dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -149,4 +180,26 @@ class Router implements MiddlewareInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private function disptachPreRouteHooks(ServerRequestInterface $request, ResponseInterface &$response)
|
||||||
|
{
|
||||||
|
if ($this->preRouteHooks) {
|
||||||
|
$dispatcher = $this->getDispatcher();
|
||||||
|
foreach ($this->preRouteHooks as $hook) {
|
||||||
|
$dispatcher->dispatch($hook, $request, $response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function disptachPostRouteHooks(ServerRequestInterface $request, ResponseInterface &$response)
|
||||||
|
{
|
||||||
|
if ($this->postRouteHooks) {
|
||||||
|
$dispatcher = $this->getDispatcher();
|
||||||
|
foreach ($this->postRouteHooks as $hook) {
|
||||||
|
$dispatcher->dispatch($hook, $request, $response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ use WellRESTed\Routing\Router;
|
||||||
*/
|
*/
|
||||||
class RouterTest extends \PHPUnit_Framework_TestCase
|
class RouterTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
private $dispatcher;
|
||||||
private $middleware;
|
private $middleware;
|
||||||
private $request;
|
private $request;
|
||||||
private $responder;
|
private $responder;
|
||||||
|
|
@ -28,6 +29,8 @@ class RouterTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
|
$this->dispatcher = $this->prophesize('\WellRESTed\Routing\DispatcherInterface');
|
||||||
|
$this->dispatcher->dispatch(Argument::any())->willReturn();
|
||||||
$this->request = $this->prophesize("\\Psr\\Http\\Message\\ServerRequestInterface");
|
$this->request = $this->prophesize("\\Psr\\Http\\Message\\ServerRequestInterface");
|
||||||
$this->response = $this->prophesize("\\Psr\\Http\\Message\\ResponseInterface");
|
$this->response = $this->prophesize("\\Psr\\Http\\Message\\ResponseInterface");
|
||||||
$this->response->withStatus(Argument::any())->willReturn($this->response->reveal());
|
$this->response->withStatus(Argument::any())->willReturn($this->response->reveal());
|
||||||
|
|
@ -50,6 +53,36 @@ class RouterTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->middleware->dispatch(Argument::cetera())->shouldHaveBeenCalled();
|
$this->middleware->dispatch(Argument::cetera())->shouldHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDispatchesPreRouteHooks()
|
||||||
|
{
|
||||||
|
$hook = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface');
|
||||||
|
$hook->dispatch(Argument::cetera())->willReturn();
|
||||||
|
|
||||||
|
$this->request->getRequestTarget()->willReturn("/cats/");
|
||||||
|
|
||||||
|
$router = new Router();
|
||||||
|
$router->addPreRouteHook($hook->reveal());
|
||||||
|
$router->add("/cats/", $this->middleware->reveal());
|
||||||
|
$router->dispatch($this->request->reveal(), $this->response->reveal());
|
||||||
|
|
||||||
|
$hook->dispatch(Argument::cetera())->shouldHaveBeenCalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDispatchesPostRouteHooks()
|
||||||
|
{
|
||||||
|
$hook = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface');
|
||||||
|
$hook->dispatch(Argument::cetera())->willReturn();
|
||||||
|
|
||||||
|
$this->request->getRequestTarget()->willReturn("/cats/");
|
||||||
|
|
||||||
|
$router = new Router();
|
||||||
|
$router->addPostRouteHook($hook->reveal());
|
||||||
|
$router->add("/cats/", $this->middleware->reveal());
|
||||||
|
$router->dispatch($this->request->reveal(), $this->response->reveal());
|
||||||
|
|
||||||
|
$hook->dispatch(Argument::cetera())->shouldHaveBeenCalled();
|
||||||
|
}
|
||||||
|
|
||||||
public function testRespondsWithErrorResponseForHttpException()
|
public function testRespondsWithErrorResponseForHttpException()
|
||||||
{
|
{
|
||||||
$this->request->getRequestTarget()->willReturn("/cats/");
|
$this->request->getRequestTarget()->willReturn("/cats/");
|
||||||
|
|
@ -110,11 +143,17 @@ class RouterTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
class SettableRouter extends Router
|
class SettableRouter extends Router
|
||||||
{
|
{
|
||||||
|
public $dispatcher;
|
||||||
public $methodMap;
|
public $methodMap;
|
||||||
public $request;
|
public $request;
|
||||||
public $response;
|
public $response;
|
||||||
public $responder;
|
public $responder;
|
||||||
|
|
||||||
|
public function getDispatcher()
|
||||||
|
{
|
||||||
|
return $this->dispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
public function getMethodMap()
|
public function getMethodMap()
|
||||||
{
|
{
|
||||||
return $this->methodMap ?: parent::getMethodMap();
|
return $this->methodMap ?: parent::getMethodMap();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue