Skip to content

Commit

Permalink
Improve CurrentRoute, minor fixes (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustamwin committed Aug 20, 2021
1 parent 694aa09 commit a26af50
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 20 deletions.
7 changes: 6 additions & 1 deletion config/common.php
Expand Up @@ -8,5 +8,10 @@

return [
RouteCollectorInterface::class => RouteCollector::class,
CurrentRoute::class => CurrentRoute::class,
CurrentRoute::class => [
'reset' => function () {
$this->route = null;
$this->uri = null;
},
],
];
25 changes: 21 additions & 4 deletions src/CurrentRoute.php
Expand Up @@ -5,12 +5,18 @@
namespace Yiisoft\Router;

use Psr\Http\Message\UriInterface;
use RuntimeException;

/**
* Holds information about current route e.g. matched last.
*/
final class CurrentRoute
{
/**
* Current Route
*
* @var RouteParametersInterface|null
*/
private ?RouteParametersInterface $route = null;
/**
* Current URI
Expand Down Expand Up @@ -39,16 +45,27 @@ public function getUri(): ?UriInterface
return $this->uri;
}

/**
* @param RouteParametersInterface $route
*/
public function setRoute(RouteParametersInterface $route): void
{
$this->route = $route;
if ($this->route === null) {
$this->route = $route;
return;
}
throw new RuntimeException('Can not set route since it was already set.');
}

/**
* @param UriInterface|null $uri
* @param UriInterface $uri
*/
public function setUri(?UriInterface $uri): void
public function setUri(UriInterface $uri): void
{
$this->uri = $uri;
if ($this->uri === null) {
$this->uri = $uri;
return;
}
throw new RuntimeException('Can not set URI since it was already set.');
}
}
5 changes: 5 additions & 0 deletions src/MatchingResult.php
Expand Up @@ -67,6 +67,11 @@ public function methods(): array
return $this->methods;
}

public function route(): Route
{
return $this->route;
}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (!$this->isSuccess()) {
Expand Down
9 changes: 8 additions & 1 deletion src/Middleware/Router.php
Expand Up @@ -11,25 +11,30 @@
use Psr\Http\Server\RequestHandlerInterface;
use Yiisoft\Http\Status;
use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher;
use Yiisoft\Router\CurrentRoute;
use Yiisoft\Router\UrlMatcherInterface;

final class Router implements MiddlewareInterface
{
private UrlMatcherInterface $matcher;
private ResponseFactoryInterface $responseFactory;
private MiddlewareDispatcher $dispatcher;
private CurrentRoute $currentRoute;

public function __construct(UrlMatcherInterface $matcher, ResponseFactoryInterface $responseFactory, MiddlewareDispatcher $dispatcher)
public function __construct(UrlMatcherInterface $matcher, ResponseFactoryInterface $responseFactory, MiddlewareDispatcher $dispatcher, CurrentRoute $currentRoute)
{
$this->matcher = $matcher;
$this->responseFactory = $responseFactory;
$this->dispatcher = $dispatcher;
$this->currentRoute = $currentRoute;
}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$result = $this->matcher->match($request);

$this->currentRoute->setUri($request->getUri());

if ($result->isMethodFailure()) {
return $this->responseFactory->createResponse(Status::METHOD_NOT_ALLOWED)
->withHeader('Allow', implode(', ', $result->methods()));
Expand All @@ -39,6 +44,8 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
return $handler->handle($request);
}

$this->currentRoute->setRoute($result->route());

foreach ($result->parameters() as $parameter => $value) {
$request = $request->withAttribute($parameter, $value);
}
Expand Down
41 changes: 27 additions & 14 deletions tests/Middleware/RouterTest.php
Expand Up @@ -12,32 +12,32 @@
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Yiisoft\Http\Method;
use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher;
use Yiisoft\Middleware\Dispatcher\MiddlewareFactory;
use Yiisoft\Router\CurrentRoute;
use Yiisoft\Router\MatchingResult;
use Yiisoft\Router\Middleware\Router;
use Yiisoft\Router\Route;
use Yiisoft\Router\UrlMatcherInterface;

final class RouterTest extends TestCase
{
private function createRouterMiddleware(): Router
private function createRouterMiddleware(?CurrentRoute $currentRoute = null): Router
{
$container = $this->createMock(ContainerInterface::class);
$dispatcher = new MiddlewareDispatcher(
new MiddlewareFactory($container),
$this->createMock(EventDispatcherInterface::class)
);

return new Router($this->getMatcher(), new Psr17Factory(), $dispatcher);
return new Router($this->getMatcher(), new Psr17Factory(), $dispatcher, $currentRoute ?? new CurrentRoute());
}

private function processWithRouter(ServerRequestInterface $request): ResponseInterface
private function processWithRouter(ServerRequestInterface $request, ?CurrentRoute $currentRoute = null): ResponseInterface
{
return $this->createRouterMiddleware()->process($request, $this->createRequestHandler());
return $this->createRouterMiddleware($currentRoute)->process($request, $this->createRequestHandler());
}

public function testProcessSuccess(): void
Expand All @@ -62,6 +62,27 @@ public function testMethodMismatchRespondWith405(): void
$this->assertSame('GET, HEAD', $response->getHeaderLine('Allow'));
}

public function testGetCurrentRoute(): void
{
$currentRoute = new CurrentRoute();
$request = new ServerRequest('GET', '/');

$this->processWithRouter($request, $currentRoute);

$this->assertInstanceOf(Route::class, $currentRoute->getRoute());
$this->assertEquals('GET /', $currentRoute->getRoute()->getName());
}

public function testGetCurrentUri(): void
{
$currentRoute = new CurrentRoute();
$request = new ServerRequest('GET', '/');

$this->processWithRouter($request, $currentRoute);

$this->assertSame($request->getUri(), $currentRoute->getUri());
}

private function getMatcher(): UrlMatcherInterface
{
$middleware = $this->createRouteMiddleware();
Expand All @@ -74,14 +95,6 @@ public function __construct($middleware)
$this->middleware = $middleware;
}

public function getCurrentRoute(): ?Route
{
}

public function getCurrentUri(): ?UriInterface
{
}

/**
* Emulates router with a single `GET /` route
*
Expand All @@ -92,7 +105,7 @@ public function getCurrentUri(): ?UriInterface
public function match(ServerRequestInterface $request): MatchingResult
{
if ($request->getUri()->getPath() !== '/') {
return MatchingResult::fromFailure(Method::ANY);
return MatchingResult::fromFailure(Method::ALL);
}

if ($request->getMethod() === 'GET') {
Expand Down

0 comments on commit a26af50

Please sign in to comment.