Add type hints to Router
This commit is contained in:
parent
967b6ac2a4
commit
ca204a07e7
|
|
@ -48,8 +48,10 @@ class Router
|
|||
* Attribute name for matched path variables. A null value sets
|
||||
* attributes directly.
|
||||
*/
|
||||
public function __construct($dispatcher = null, $pathVariablesAttributeName = null)
|
||||
{
|
||||
public function __construct(
|
||||
?DispatcherInterface $dispatcher = null,
|
||||
?string $pathVariablesAttributeName = null
|
||||
) {
|
||||
$this->dispatcher = $dispatcher ?: $this->getDefaultDispatcher();
|
||||
$this->pathVariablesAttributeName = $pathVariablesAttributeName;
|
||||
$this->factory = $this->getRouteFactory($this->dispatcher);
|
||||
|
|
@ -63,8 +65,8 @@ class Router
|
|||
public function __invoke(
|
||||
ServerRequestInterface $request,
|
||||
ResponseInterface $response,
|
||||
$next
|
||||
) {
|
||||
callable $next
|
||||
): ResponseInterface {
|
||||
// Use only the path for routing.
|
||||
$requestTarget = parse_url($request->getRequestTarget(), PHP_URL_PATH);
|
||||
|
||||
|
|
@ -101,11 +103,11 @@ class Router
|
|||
}
|
||||
|
||||
private function dispatch(
|
||||
$route,
|
||||
callable $route,
|
||||
ServerRequestInterface $request,
|
||||
ResponseInterface $response,
|
||||
$next
|
||||
) {
|
||||
callable $next
|
||||
): ResponseInterface {
|
||||
if (!$this->stack) {
|
||||
return $route($request, $response, $next);
|
||||
}
|
||||
|
|
@ -145,12 +147,12 @@ class Router
|
|||
* - An array containing any of the items in this list.
|
||||
* @see DispatchedInterface::dispatch
|
||||
*
|
||||
* @param string $target Request target or pattern to match
|
||||
* @param string $method HTTP method(s) to match
|
||||
* @param string $target Request target or pattern to match
|
||||
* @param mixed $dispatchable Handler or middleware to dispatch
|
||||
* @return static
|
||||
*/
|
||||
public function register($method, $target, $dispatchable)
|
||||
public function register(string $method, string $target, $dispatchable): Router
|
||||
{
|
||||
$route = $this->getRouteForTarget($target);
|
||||
$route->register($method, $dispatchable);
|
||||
|
|
@ -174,7 +176,7 @@ class Router
|
|||
* @param mixed $middleware Middleware to dispatch in sequence
|
||||
* @return static
|
||||
*/
|
||||
public function add($middleware)
|
||||
public function add($middleware): Router
|
||||
{
|
||||
$this->stack[] = $middleware;
|
||||
return $this;
|
||||
|
|
@ -186,38 +188,23 @@ class Router
|
|||
*
|
||||
* @return static
|
||||
*/
|
||||
public function continueOnNotFound()
|
||||
public function continueOnNotFound(): Router
|
||||
{
|
||||
$this->continueOnNotFound = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance to dispatch middleware.
|
||||
*
|
||||
* @return DispatcherInterface
|
||||
*/
|
||||
protected function getDefaultDispatcher()
|
||||
protected function getDefaultDispatcher(): DispatcherInterface
|
||||
{
|
||||
return new Dispatcher();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DispatcherInterface $dispatcher
|
||||
* @return RouteFactoryInterface
|
||||
*/
|
||||
protected function getRouteFactory($dispatcher)
|
||||
protected function getRouteFactory(DispatcherInterface $dispatcher): RouteFactoryInterface
|
||||
{
|
||||
return new RouteFactory($dispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the route for a given target.
|
||||
*
|
||||
* @param $target
|
||||
* @return RouteInterface
|
||||
*/
|
||||
private function getRouteForTarget($target)
|
||||
private function getRouteForTarget(string $target): RouteInterface
|
||||
{
|
||||
if (isset($this->routes[$target])) {
|
||||
$route = $this->routes[$target];
|
||||
|
|
@ -228,7 +215,7 @@ class Router
|
|||
return $route;
|
||||
}
|
||||
|
||||
private function registerRouteForTarget($route, $target)
|
||||
private function registerRouteForTarget(RouteInterface $route, string $target): void
|
||||
{
|
||||
// Store the route to the hash indexed by original target.
|
||||
$this->routes[$target] = $route;
|
||||
|
|
@ -247,7 +234,7 @@ class Router
|
|||
}
|
||||
}
|
||||
|
||||
private function getStaticRoute($requestTarget)
|
||||
private function getStaticRoute(string $requestTarget): ?RouteInterface
|
||||
{
|
||||
if (isset($this->staticRoutes[$requestTarget])) {
|
||||
return $this->staticRoutes[$requestTarget];
|
||||
|
|
@ -255,7 +242,7 @@ class Router
|
|||
return null;
|
||||
}
|
||||
|
||||
private function getPrefixRoute($requestTarget)
|
||||
private function getPrefixRoute(string $requestTarget): ?RouteInterface
|
||||
{
|
||||
// Find all prefixes that match the start of this path.
|
||||
$prefixes = array_keys($this->prefixRoutes);
|
||||
|
|
@ -273,7 +260,7 @@ class Router
|
|||
// If there are multiple matches, sort them to find the one with the
|
||||
// longest string length.
|
||||
if (count($matches) > 1) {
|
||||
$compareByLength = function ($a, $b) {
|
||||
$compareByLength = function (string $a, string $b): int {
|
||||
return strlen($b) - strlen($a);
|
||||
};
|
||||
usort($matches, $compareByLength);
|
||||
|
|
@ -283,7 +270,7 @@ class Router
|
|||
return $this->prefixRoutes[$bestMatch];
|
||||
}
|
||||
|
||||
private function startsWith($haystack, $needle)
|
||||
private function startsWith(string $haystack, string $needle): bool
|
||||
{
|
||||
$length = strlen($needle);
|
||||
return (substr($haystack, 0, $length) === $needle);
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ namespace WellRESTed\Test\Unit\Routing;
|
|||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use WellRESTed\Dispatching\Dispatcher;
|
||||
use WellRESTed\Dispatching\DispatcherInterface;
|
||||
use WellRESTed\Message\Response;
|
||||
use WellRESTed\Message\ServerRequest;
|
||||
use WellRESTed\Routing\Route\RouteFactory;
|
||||
use WellRESTed\Routing\Route\RouteFactoryInterface;
|
||||
use WellRESTed\Routing\Route\RouteInterface;
|
||||
use WellRESTed\Routing\Router;
|
||||
use WellRESTed\Test\Doubles\NextMock;
|
||||
|
|
@ -30,7 +32,7 @@ class RouterTest extends TestCase
|
|||
|
||||
$this->route = $this->prophesize(RouteInterface::class);
|
||||
$this->route->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
$this->route->register(Argument::cetera())->willReturn();
|
||||
$this->route->register(Argument::cetera());
|
||||
$this->route->getType()->willReturn(RouteInterface::TYPE_STATIC);
|
||||
$this->route->getTarget()->willReturn("/");
|
||||
$this->route->getPathVariables()->willReturn([]);
|
||||
|
|
@ -134,13 +136,13 @@ class RouterTest extends TestCase
|
|||
public function testDispatchesStaticRouteBeforePrefixRoute()
|
||||
{
|
||||
$staticRoute = $this->prophesize(RouteInterface::class);
|
||||
$staticRoute->register(Argument::cetera())->willReturn();
|
||||
$staticRoute->register(Argument::cetera());
|
||||
$staticRoute->getTarget()->willReturn("/cats/");
|
||||
$staticRoute->getType()->willReturn(RouteInterface::TYPE_STATIC);
|
||||
$staticRoute->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
|
||||
$prefixRoute = $this->prophesize(RouteInterface::class);
|
||||
$prefixRoute->register(Argument::cetera())->willReturn();
|
||||
$prefixRoute->register(Argument::cetera());
|
||||
$prefixRoute->getTarget()->willReturn("/cats/*");
|
||||
$prefixRoute->getType()->willReturn(RouteInterface::TYPE_PREFIX);
|
||||
$prefixRoute->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
|
|
@ -163,13 +165,13 @@ class RouterTest extends TestCase
|
|||
// Note: The longest route is also good for 2 points in Settlers of Catan.
|
||||
|
||||
$shortRoute = $this->prophesize(RouteInterface::class);
|
||||
$shortRoute->register(Argument::cetera())->willReturn();
|
||||
$shortRoute->register(Argument::cetera());
|
||||
$shortRoute->getTarget()->willReturn("/animals/*");
|
||||
$shortRoute->getType()->willReturn(RouteInterface::TYPE_PREFIX);
|
||||
$shortRoute->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
|
||||
$longRoute = $this->prophesize(RouteInterface::class);
|
||||
$longRoute->register(Argument::cetera())->willReturn();
|
||||
$longRoute->register(Argument::cetera());
|
||||
$longRoute->getTarget()->willReturn("/animals/cats/*");
|
||||
$longRoute->getType()->willReturn(RouteInterface::TYPE_PREFIX);
|
||||
$longRoute->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
|
|
@ -191,13 +193,13 @@ class RouterTest extends TestCase
|
|||
public function testDispatchesPrefixRouteBeforePatternRoute()
|
||||
{
|
||||
$prefixRoute = $this->prophesize(RouteInterface::class);
|
||||
$prefixRoute->register(Argument::cetera())->willReturn();
|
||||
$prefixRoute->register(Argument::cetera());
|
||||
$prefixRoute->getTarget()->willReturn("/cats/*");
|
||||
$prefixRoute->getType()->willReturn(RouteInterface::TYPE_PREFIX);
|
||||
$prefixRoute->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
|
||||
$patternRoute = $this->prophesize(RouteInterface::class);
|
||||
$patternRoute->register(Argument::cetera())->willReturn();
|
||||
$patternRoute->register(Argument::cetera());
|
||||
$patternRoute->getTarget()->willReturn("/cats/{id}");
|
||||
$patternRoute->getType()->willReturn(RouteInterface::TYPE_PATTERN);
|
||||
$patternRoute->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
|
|
@ -218,7 +220,7 @@ class RouterTest extends TestCase
|
|||
public function testDispatchesFirstMatchingPatternRoute()
|
||||
{
|
||||
$patternRoute1 = $this->prophesize(RouteInterface::class);
|
||||
$patternRoute1->register(Argument::cetera())->willReturn();
|
||||
$patternRoute1->register(Argument::cetera());
|
||||
$patternRoute1->getTarget()->willReturn("/cats/{id}");
|
||||
$patternRoute1->getType()->willReturn(RouteInterface::TYPE_PATTERN);
|
||||
$patternRoute1->getPathVariables()->willReturn([]);
|
||||
|
|
@ -226,7 +228,7 @@ class RouterTest extends TestCase
|
|||
$patternRoute1->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
|
||||
$patternRoute2 = $this->prophesize(RouteInterface::class);
|
||||
$patternRoute2->register(Argument::cetera())->willReturn();
|
||||
$patternRoute2->register(Argument::cetera());
|
||||
$patternRoute2->getTarget()->willReturn("/cats/{name}");
|
||||
$patternRoute2->getType()->willReturn(RouteInterface::TYPE_PATTERN);
|
||||
$patternRoute2->getPathVariables()->willReturn([]);
|
||||
|
|
@ -249,7 +251,7 @@ class RouterTest extends TestCase
|
|||
public function testStopsTestingPatternsAfterFirstSuccessfulMatch()
|
||||
{
|
||||
$patternRoute1 = $this->prophesize(RouteInterface::class);
|
||||
$patternRoute1->register(Argument::cetera())->willReturn();
|
||||
$patternRoute1->register(Argument::cetera());
|
||||
$patternRoute1->getTarget()->willReturn("/cats/{id}");
|
||||
$patternRoute1->getType()->willReturn(RouteInterface::TYPE_PATTERN);
|
||||
$patternRoute1->getPathVariables()->willReturn([]);
|
||||
|
|
@ -257,7 +259,7 @@ class RouterTest extends TestCase
|
|||
$patternRoute1->__invoke(Argument::cetera())->willReturn(new Response());
|
||||
|
||||
$patternRoute2 = $this->prophesize(RouteInterface::class);
|
||||
$patternRoute2->register(Argument::cetera())->willReturn();
|
||||
$patternRoute2->register(Argument::cetera());
|
||||
$patternRoute2->getTarget()->willReturn("/cats/{name}");
|
||||
$patternRoute2->getType()->willReturn(RouteInterface::TYPE_PATTERN);
|
||||
$patternRoute2->getPathVariables()->willReturn([]);
|
||||
|
|
@ -447,7 +449,7 @@ class RouterWithFactory extends Router
|
|||
{
|
||||
static $routeFactory;
|
||||
|
||||
protected function getRouteFactory($dispatcher)
|
||||
protected function getRouteFactory(DispatcherInterface $dispatcher): RouteFactoryInterface
|
||||
{
|
||||
return self::$routeFactory;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue