Skip to content

Commit

Permalink
Merge pull request #93 from sunrise-php/release/v2.13.0
Browse files Browse the repository at this point in the history
v2.13.0
  • Loading branch information
fenric authored Mar 20, 2022
2 parents c3db73a + 097831a commit 9f07a5d
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## v2.13.0

* Supports for events using the `symfony/event-dispatcher`.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
## Installation

```bash
composer require 'sunrise/http-router:^2.11'
composer require 'sunrise/http-router:^2.13'
```

## Support for OpenAPI (Swagger) Specification (optional)
Expand Down Expand Up @@ -570,6 +570,32 @@ use Sunrise\Http\Router\Command\RouteListCommand;
new RouteListCommand($router);
```

### Events

> Available from version 2.13
```bash
composer require symfony/event-dispatcher
```

```php
use Sunrise\Http\Router\Event\RouteEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;

$eventDispatcher = new EventDispatcher();

$eventDispatcher->addListener(RouteEvent::NAME, function (RouteEvent $event) {
// gets the matched route:
$event->getRoute();
// gets the current request:
$event->getRequest();
// overrides the current request:
$event->setRequest(ServerRequestInterface $request);
});

$router->setEventDispatcher($eventDispatcher);
```

---

## Test run
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"sunrise/coding-standard": "1.0.0",
"sunrise/http-factory": "1.1.0",
"doctrine/annotations": "^1.6",
"symfony/console": "^4.4"
"symfony/console": "^4.4",
"symfony/event-dispatcher": "^4.4"
},
"autoload": {
"files": [
Expand Down
81 changes: 81 additions & 0 deletions src/Event/RouteEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php declare(strict_types=1);

/**
* It's free open-source software released under the MIT License.
*
* @author Anatoly Fenric <[email protected]>
* @copyright Copyright (c) 2018, Anatoly Fenric
* @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
* @link https://github.com/sunrise-php/http-router
*/

namespace Sunrise\Http\Router\Event;

/**
* Import classes
*/
use Psr\Http\Message\ServerRequestInterface;
use Sunrise\Http\Router\RouteInterface;
use Symfony\Contracts\EventDispatcher\Event;

/**
* RouteEvent
*
* @since 2.13.0
*/
final class RouteEvent extends Event
{

/**
* @var string
*/
public const NAME = 'router.route';

/**
* @var RouteInterface
*/
private $route;

/**
* @var ServerRequestInterface
*/
private $request;

/**
* Constructor of the class
*
* @param RouteInterface $route
* @param ServerRequestInterface $request
*/
public function __construct(RouteInterface $route, ServerRequestInterface $request)
{
$this->route = $route;
$this->request = $request;
}

/**
* @return RouteInterface
*/
public function getRoute() : RouteInterface
{
return $this->route;
}

/**
* @return ServerRequestInterface
*/
public function getRequest() : ServerRequestInterface
{
return $this->request;
}

/**
* @param ServerRequestInterface $request
*
* @return void
*/
public function setRequest(ServerRequestInterface $request) : void
{
$this->request = $request;
}
}
50 changes: 50 additions & 0 deletions src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Sunrise\Http\Router\Event\RouteEvent;
use Sunrise\Http\Router\Exception\InvalidArgumentException;
use Sunrise\Http\Router\Exception\MethodNotAllowedException;
use Sunrise\Http\Router\Exception\PageNotFoundException;
use Sunrise\Http\Router\Exception\RouteNotFoundException;
use Sunrise\Http\Router\Loader\LoaderInterface;
use Sunrise\Http\Router\RequestHandler\CallableRequestHandler;
use Sunrise\Http\Router\RequestHandler\QueueableRequestHandler;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
* Import functions
Expand Down Expand Up @@ -90,6 +92,15 @@ class Router implements MiddlewareInterface, RequestHandlerInterface, RequestMet
*/
private $matchedRoute = null;

/**
* The router's event dispatcher
*
* @var EventDispatcherInterface|null
*
* @since 2.13.0
*/
private $eventDispatcher = null;

/**
* Gets the router host table
*
Expand Down Expand Up @@ -132,6 +143,18 @@ public function getMatchedRoute() : ?RouteInterface
return $this->matchedRoute;
}

/**
* Gets the router's event dispatcher
*
* @return EventDispatcherInterface|null
*
* @since 2.13.0
*/
public function getEventDispatcher() : ?EventDispatcherInterface
{
return $this->eventDispatcher;
}

/**
* Adds the given patterns to the router
*
Expand Down Expand Up @@ -246,6 +269,20 @@ public function addMiddleware(MiddlewareInterface ...$middlewares) : void
}
}

/**
* Sets the given event dispatcher to the router
*
* @param EventDispatcherInterface|null $eventDispatcher
*
* @return void
*
* @since 2.13.0
*/
public function setEventDispatcher(?EventDispatcherInterface $eventDispatcher) : void
{
$this->eventDispatcher = $eventDispatcher;
}

/**
* Gets allowed methods
*
Expand Down Expand Up @@ -374,6 +411,13 @@ public function run(ServerRequestInterface $request) : ResponseInterface
$routing = new CallableRequestHandler(function (ServerRequestInterface $request) : ResponseInterface {
$route = $this->match($request);
$this->matchedRoute = $route;

if (isset($this->eventDispatcher)) {
$event = new RouteEvent($route, $request);
$this->eventDispatcher->dispatch($event, RouteEvent::NAME);
$request = $event->getRequest();
}

return $route->handle($request);
});

Expand All @@ -396,6 +440,12 @@ public function handle(ServerRequestInterface $request) : ResponseInterface
$route = $this->match($request);
$this->matchedRoute = $route;

if (isset($this->eventDispatcher)) {
$event = new RouteEvent($route, $request);
$this->eventDispatcher->dispatch($event, RouteEvent::NAME);
$request = $event->getRequest();
}

$middlewares = $this->getMiddlewares();
if (empty($middlewares)) {
return $route->handle($request);
Expand Down
72 changes: 72 additions & 0 deletions tests/RouterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPUnit\Framework\TestCase;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Sunrise\Http\Router\Event\RouteEvent;
use Sunrise\Http\Router\Exception\InvalidArgumentException;
use Sunrise\Http\Router\Exception\MethodNotAllowedException;
use Sunrise\Http\Router\Exception\PageNotFoundException;
Expand All @@ -19,6 +20,7 @@
use Sunrise\Http\Router\Router;
use Sunrise\Http\Message\ResponseFactory;
use Sunrise\Http\ServerRequest\ServerRequestFactory;
use Symfony\Component\EventDispatcher\EventDispatcher;

/**
* Import functions
Expand Down Expand Up @@ -819,4 +821,74 @@ public function testMatchWithHosts() : void
$router->match((new ServerRequestFactory)
->createServerRequest('GET', 'http://localhost/ping'));
}

/**
* @return void
*/
public function testEventDispatcher() : void
{
$router = new Router();
$this->assertNull($router->getEventDispatcher());

$eventDispatcher = new EventDispatcher();
$router->setEventDispatcher($eventDispatcher);
$this->assertSame($eventDispatcher, $router->getEventDispatcher());

$router->setEventDispatcher(null);
$this->assertNull($router->getEventDispatcher());
}

/**
* @return void
*/
public function testRouteEvent() : void
{
$routes = [
new Fixtures\Route(),
new Fixtures\Route(),
new Fixtures\Route(),
];

$request = (new ServerRequestFactory)
->createServerRequest(
$routes[1]->getMethods()[1],
$routes[1]->getPath()
);

$eventDispatcher = new EventDispatcher();
$eventDispatcher->addListener(RouteEvent::NAME, function (RouteEvent $event) use ($routes, $request) {
$this->assertSame($routes[1]->getName(), $event->getRoute()->getName());
$this->assertSame($request, $event->getRequest());
});

$router = new Router();
$router->addRoute(...$routes);
$router->setEventDispatcher($eventDispatcher);
$router->run($request);
}

/**
* @return void
*/
public function testRouteEventOverrideRequest() : void
{
$route = new Fixtures\Route();

$request = (new ServerRequestFactory)
->createServerRequest(
$route->getMethods()[0],
$route->getPath()
);

$eventDispatcher = new EventDispatcher();
$eventDispatcher->addListener(RouteEvent::NAME, function (RouteEvent $event) use ($request) {
$event->setRequest($request->withAttribute('foo', 'bar'));
$this->assertNotSame($request, $event->getRequest());
});

$router = new Router();
$router->addRoute($route);
$router->setEventDispatcher($eventDispatcher);
$router->handle($request);
}
}

0 comments on commit 9f07a5d

Please sign in to comment.