Router stores path variables directly as attributes by default.
This commit is contained in:
parent
0387255676
commit
dedec4ec4e
|
|
@ -13,7 +13,7 @@ use WellRESTed\Routing\Route\RouteInterface;
|
|||
class Router implements RouterInterface
|
||||
{
|
||||
/** @var string Key to ServerRequestInterface attribute for matched path variables */
|
||||
public $pathVariablesAttributeKey = "pathVariables";
|
||||
private $pathVariablesAttributeName;
|
||||
/** @var DispatcherInterface */
|
||||
private $dispatcher;
|
||||
/** @var RouteFactoryInterface */
|
||||
|
|
@ -27,12 +27,25 @@ class Router implements RouterInterface
|
|||
/** @var RouteInterface[] Hash array mapping path prefixes to routes */
|
||||
private $patternRoutes;
|
||||
|
||||
public function __construct(DispatcherInterface $dispatcher = null)
|
||||
/**
|
||||
* Create a new Router.
|
||||
*
|
||||
* When the router matches a route with path variables, it will add each
|
||||
* variable as an attribute on the ServerRequestInterface by default.
|
||||
*
|
||||
* When $pathVariablesAttributeName is set, the router will set one
|
||||
* attribute with the passed name to an array containing all of the path
|
||||
* variables.
|
||||
*
|
||||
* @param DispatcherInterface $dispatcher Instance to use for dispatching
|
||||
* middleware.
|
||||
* @param string $pathVariablesAttributeName Optionally provide all path
|
||||
* variables as an array stored with this attribute name
|
||||
*/
|
||||
public function __construct(DispatcherInterface $dispatcher = null, $pathVariablesAttributeName = null)
|
||||
{
|
||||
if ($dispatcher === null) {
|
||||
$dispatcher = new Dispatcher();
|
||||
}
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->pathVariablesAttributeName = $pathVariablesAttributeName;
|
||||
$this->factory = $this->getRouteFactory($this->dispatcher);
|
||||
$this->routes = [];
|
||||
$this->staticRoutes = [];
|
||||
|
|
@ -40,6 +53,41 @@ class Router implements RouterInterface
|
|||
$this->patternRoutes = [];
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next)
|
||||
{
|
||||
// Use only the path for routing.
|
||||
$requestTarget = parse_url($request->getRequestTarget(), PHP_URL_PATH);
|
||||
|
||||
$route = $this->getStaticRoute($requestTarget);
|
||||
if ($route) {
|
||||
return $route($request, $response, $next);
|
||||
}
|
||||
|
||||
$route = $this->getPrefixRoute($requestTarget);
|
||||
if ($route) {
|
||||
return $route($request, $response, $next);
|
||||
}
|
||||
|
||||
// Try each of the routes.
|
||||
foreach ($this->patternRoutes as $route) {
|
||||
if ($route->matchesRequestTarget($requestTarget)) {
|
||||
$pathVariables = $route->getPathVariables();
|
||||
if ($this->pathVariablesAttributeName) {
|
||||
$request = $request->withAttribute($this->pathVariablesAttributeName, $pathVariables);
|
||||
} else {
|
||||
foreach ($pathVariables as $name => $value) {
|
||||
$request = $request->withAttribute($name, $value);
|
||||
}
|
||||
}
|
||||
return $route($request, $response, $next);
|
||||
}
|
||||
}
|
||||
|
||||
// If no route exists, set the status code of the response to 404 and
|
||||
// return the response without propagating.
|
||||
return $response->withStatus(404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register middleware with the router for a given path and method.
|
||||
*
|
||||
|
|
@ -75,35 +123,6 @@ class Router implements RouterInterface
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next)
|
||||
{
|
||||
// Use only the path for routing.
|
||||
$requestTarget = parse_url($request->getRequestTarget(), PHP_URL_PATH);
|
||||
|
||||
$route = $this->getStaticRoute($requestTarget);
|
||||
if ($route) {
|
||||
return $route($request, $response, $next);
|
||||
}
|
||||
|
||||
$route = $this->getPrefixRoute($requestTarget);
|
||||
if ($route) {
|
||||
return $route($request, $response, $next);
|
||||
}
|
||||
|
||||
// Try each of the routes.
|
||||
foreach ($this->patternRoutes as $route) {
|
||||
if ($route->matchesRequestTarget($requestTarget)) {
|
||||
$pathVariables = $route->getPathVariables();
|
||||
$request = $request->withAttribute($this->pathVariablesAttributeKey, $pathVariables);
|
||||
return $route($request, $response, $next);
|
||||
}
|
||||
}
|
||||
|
||||
// If no route exists, set the status code of the response to 404 and
|
||||
// return the response without propagating.
|
||||
return $response->withStatus(404);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DispatcherInterface
|
||||
* @return RouteFactoryInterface
|
||||
|
|
|
|||
|
|
@ -75,20 +75,8 @@ class RouterTest extends \PHPUnit_Framework_TestCase
|
|||
*/
|
||||
public function testCreatesInstance()
|
||||
{
|
||||
$routeMap = new Router($this->dispatcher->reveal());
|
||||
$this->assertNotNull($routeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::__construct
|
||||
* @covers ::getRouteFactory
|
||||
* @uses WellRESTed\Routing\Route\RouteFactory
|
||||
* @uses WellRESTed\Dispatching\Dispatcher
|
||||
*/
|
||||
public function testCreatesInstanceWithDispatcherByDefault()
|
||||
{
|
||||
$routeMap = new Router();
|
||||
$this->assertNotNull($routeMap);
|
||||
$router = new Router($this->dispatcher->reveal());
|
||||
$this->assertNotNull($router);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -339,30 +327,6 @@ class RouterTest extends \PHPUnit_Framework_TestCase
|
|||
$patternRoute2->matchesRequestTarget(Argument::any())->shouldNotHaveBeenCalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::__invoke
|
||||
* @group current
|
||||
*/
|
||||
public function testSetPathVariablesAttributeBeforeDispatchingPatternRoute()
|
||||
{
|
||||
$target = "/";
|
||||
$variables = [
|
||||
"id" => "1024",
|
||||
"name" => "Molly"
|
||||
];
|
||||
|
||||
$this->request->getRequestTarget()->willReturn($target);
|
||||
$this->route->getTarget()->willReturn($target);
|
||||
$this->route->getType()->willReturn(RouteInterface::TYPE_PATTERN);
|
||||
$this->route->matchesRequestTarget(Argument::cetera())->willReturn(true);
|
||||
$this->route->getPathVariables()->willReturn($variables);
|
||||
|
||||
$this->router->register("GET", $target, "middleware");
|
||||
$this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next);
|
||||
|
||||
$this->request->withAttribute("pathVariables", $variables)->shouldHaveBeenCalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::__invoke
|
||||
* @covers ::registerRouteForTarget
|
||||
|
|
@ -382,6 +346,70 @@ class RouterTest extends \PHPUnit_Framework_TestCase
|
|||
$this->route->matchesRequestTarget("/my/path")->shouldHaveBeenCalled();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Path Variables
|
||||
|
||||
/**
|
||||
* @covers ::__invoke
|
||||
* @dataProvider pathVariableProvider
|
||||
*/
|
||||
public function testSetPathVariablesAttributeIndividually($name, $value)
|
||||
{
|
||||
$attributeName = "pathVariables";
|
||||
|
||||
$target = "/";
|
||||
$variables = [
|
||||
"id" => "1024",
|
||||
"name" => "Molly"
|
||||
];
|
||||
|
||||
$this->request->getRequestTarget()->willReturn($target);
|
||||
$this->route->getTarget()->willReturn($target);
|
||||
$this->route->getType()->willReturn(RouteInterface::TYPE_PATTERN);
|
||||
$this->route->matchesRequestTarget(Argument::cetera())->willReturn(true);
|
||||
$this->route->getPathVariables()->willReturn($variables);
|
||||
|
||||
$this->router->__construct($this->dispatcher->reveal());
|
||||
$this->router->register("GET", $target, "middleware");
|
||||
$this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next);
|
||||
|
||||
$this->request->withAttribute($name, $value)->shouldHaveBeenCalled();
|
||||
}
|
||||
|
||||
public function pathVariableProvider()
|
||||
{
|
||||
return [
|
||||
["id", "1024"],
|
||||
["name", "Molly"]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::__invoke
|
||||
*/
|
||||
public function testSetPathVariablesAttributeAsArray()
|
||||
{
|
||||
$attributeName = "pathVariables";
|
||||
|
||||
$target = "/";
|
||||
$variables = [
|
||||
"id" => "1024",
|
||||
"name" => "Molly"
|
||||
];
|
||||
|
||||
$this->request->getRequestTarget()->willReturn($target);
|
||||
$this->route->getTarget()->willReturn($target);
|
||||
$this->route->getType()->willReturn(RouteInterface::TYPE_PATTERN);
|
||||
$this->route->matchesRequestTarget(Argument::cetera())->willReturn(true);
|
||||
$this->route->getPathVariables()->willReturn($variables);
|
||||
|
||||
$this->router->__construct($this->dispatcher->reveal(), $attributeName);
|
||||
$this->router->register("GET", $target, "middleware");
|
||||
$this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next);
|
||||
|
||||
$this->request->withAttribute("pathVariables", $variables)->shouldHaveBeenCalled();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// No Matching Routes
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue