Development

- Added event-arguments data.
- Added event-arguments to the event list in documentation.
- Fixed missing exceptions thrown in phpDocs.
- Added unit-tests for new event functionality.
This commit is contained in:
Simon Sessingø
2018-03-29 18:51:28 +02:00
parent a9c03f9271
commit f5a023117a
11 changed files with 162 additions and 70 deletions
+25 -18
View File
@@ -1238,23 +1238,25 @@ It will also cover the basics of event-handlers; how to use the handlers provide
This section contains all available events that can be registered using the `EventHandler`.
| Name | Description |
| ------------- |------------- |
| `EventHandler::EVENT_ALL` | Fires when a event is triggered. |
| `EventHandler::EVENT_INIT` | Fires when router is initializing and before routes are loaded. |
| `EventHandler::EVENT_LOAD` | Fires when all routes has been loaded and rendered, just before the output is returned. |
| `EventHandler::EVENT_REWRITE` | Fires when a url-rewrite is and just before the routes are re-initialized. |
| `EventHandler::EVENT_BOOT` | Fires when the router is booting. This happens just before boot-managers are rendered and before any routes has been loaded. |
| `EventHandler::EVENT_RENDER_BOOTMANAGER` | Fires before a boot-manager is rendered. |
| `EventHandler::EVENT_LOAD_ROUTES` | Fires when the router is about to load all routes. |
| `EventHandler::EVENT_FIND_ROUTE` | Fires whenever the `findRoute` method is called within the `Router`. This usually happens when the router tries to find routes that contains a certain url, usually after the `EventHandler::EVENT_GET_URL` event. |
| `EventHandler::EVENT_GET_URL` | Fires whenever the `Router::getUrl` method or `url`-helper function is called and the router tries to find the route. |
| `EventHandler::EVENT_MATCH_ROUTE` | Fires when a route is matched and valid (correct request-type etc). and before the route is rendered. |
| `EventHandler::EVENT_RENDER_ROUTE` | Fires before a route is rendered. |
| `EventHandler::EVENT_LOAD_EXCEPTIONS` | Fires when the router is loading exception-handlers. |
| `EventHandler::EVENT_RENDER_EXCEPTION` | Fires before the router is rendering a exception-handler. |
| `EventHandler::EVENT_RENDER_MIDDLEWARE` | Fires before a middleware is rendered. |
| `EventHandler::EVENT_RENDER_CSRF` | Fires before the CSRF-verifier is rendered. |
All event callbacks will retrieve a `EventArgument` object as parameter. This object contains easy access to event-name, router- and request instance and any special event-arguments related to the given event. You can see what special event arguments each event returns in the list below.
| Name | Special arguments | Description |
| ------------- |----------- | ---- |
| `EVENT_ALL` | - | Fires when a event is triggered. |
| `EVENT_INIT` | - | Fires when router is initializing and before routes are loaded. |
| `EVENT_LOAD` | `loadedRoutes` | Fires when all routes has been loaded and rendered, just before the output is returned. |
| `EVENT_REWRITE` | `rewriteUrl`<br>`rewriteRoute` | Fires when a url-rewrite is and just before the routes are re-initialized. |
| `EVENT_BOOT` | `bootmanagers` | Fires when the router is booting. This happens just before boot-managers are rendered and before any routes has been loaded. |
| `EVENT_RENDER_BOOTMANAGER` | `bootmanagers`<br>`bootmanager` | Fires before a boot-manager is rendered. |
| `EVENT_LOAD_ROUTES` | `routes` | Fires when the router is about to load all routes. |
| `EVENT_FIND_ROUTE` | `name` | Fires whenever the `findRoute` method is called within the `Router`. This usually happens when the router tries to find routes that contains a certain url, usually after the `EventHandler::EVENT_GET_URL` event. |
| `EVENT_GET_URL` | `name`<br>`parameters`<br>`getParams` | Fires whenever the `Router::getUrl` method or `url`-helper function is called and the router tries to find the route. |
| `EVENT_MATCH_ROUTE` | `route` | Fires when a route is matched and valid (correct request-type etc). and before the route is rendered. |
| `EVENT_RENDER_ROUTE` | `route` | Fires before a route is rendered. |
| `EVENT_LOAD_EXCEPTIONS` | `exception`<br>`exceptionHandlers` | Fires when the router is loading exception-handlers. |
| `EVENT_RENDER_EXCEPTION` | `exception`<br>`exceptionHandler`<br>`exceptionHandlers` | Fires before the router is rendering a exception-handler. |
| `EVENT_RENDER_MIDDLEWARES` | `route`<br>`middlewares` | Fires before middlewares for a route is rendered. |
| `EVENT_RENDER_CSRF` | `csrfVerifier` | Fires before the CSRF-verifier is rendered. |
## Registering new event
@@ -1272,9 +1274,14 @@ use Pecee\SimpleRouter\Event\EventArgument;
// --- your routes goes here ---
$eventHandler = new EventHandler();
// Add event that fires when a route is rendered
$eventHandler->register(EventHandler::EVENT_RENDER_ROUTE, function(EventArgument $argument) {
// Fires when route is rendered ...
// Get the route by using the special argument for this event.
$route = $argument->route;
// DO STUFF...
});
@@ -70,6 +70,34 @@ class EventArgument implements IEventArgument
return $this->getRouter()->getRequest();
}
/**
* @param string $name
* @return mixed
*/
public function __get($name)
{
return $this->arguments[$name] ?? null;
}
/**
* @param string $name
* @return bool
*/
public function __isset($name)
{
return array_key_exists($name, $this->arguments);
}
/**
* @param string $name
* @param mixed $value
* @throws \InvalidArgumentException
*/
public function __set($name, $value)
{
throw new \InvalidArgumentException('Not supported');
}
/**
* Get arguments
*
@@ -41,9 +41,9 @@ class DebugEventHandler implements IEventHandler
*
* @param Router $router Router instance
* @param string $name Event name
* @param array ...$eventArgs Event arguments
* @param array $eventArgs Event arguments
*/
public function fireEvents(Router $router, string $name, ...$eventArgs): void
public function fireEvents(Router $router, string $name, array $eventArgs = []): void
{
$callback = $this->callback;
$callback(new EventArgument($router, $eventArgs));
@@ -80,7 +80,7 @@ class EventHandler implements IEventHandler
/**
* Fires before a middleware is rendered.
*/
public const EVENT_RENDER_MIDDLEWARE = 'onRenderMiddleware';
public const EVENT_RENDER_MIDDLEWARES = 'onRenderMiddlewares';
/**
* Fires before the CSRF-verifier is rendered.
@@ -105,7 +105,7 @@ class EventHandler implements IEventHandler
self::EVENT_RENDER_ROUTE,
self::EVENT_LOAD_EXCEPTIONS,
self::EVENT_RENDER_EXCEPTION,
self::EVENT_RENDER_MIDDLEWARE,
self::EVENT_RENDER_MIDDLEWARES,
self::EVENT_RENDER_CSRF,
];
@@ -163,9 +163,9 @@ class EventHandler implements IEventHandler
*
* @param Router $router Router instance
* @param string $name Event name
* @param array ...$eventArgs Event arguments
* @param array $eventArgs Event arguments
*/
public function fireEvents(Router $router, string $name, ...$eventArgs): void
public function fireEvents(Router $router, string $name, array $eventArgs = []): void
{
$events = $this->getEvents(static::EVENT_ALL, $name);
@@ -19,8 +19,8 @@ interface IEventHandler {
*
* @param Router $router Router instance
* @param string $name Event name
* @param array ...$eventArgs Event arguments
* @param array $eventArgs Event arguments
*/
public function fireEvents(Router $router, string $name, ...$eventArgs) : void;
public function fireEvents(Router $router, string $name, array $eventArgs = []) : void;
}
@@ -42,9 +42,11 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
throw new HttpException($middleware . ' must be inherit the IMiddleware interface');
}
$router->debug('Loading middleware "%s"', \get_class($middleware));
$className = \get_class($middleware);
$router->debug('Loading middleware "%s"', $className);
$middleware->handle($request);
$router->debug('Finished loading middleware');
$router->debug('Finished loading middleware "%s"', $className);
}
$router->debug('Finished loading middlewares');
+1 -1
View File
@@ -82,7 +82,7 @@ abstract class Route implements IRoute
*/
public function renderRoute(Request $request, Router $router): ?string
{
$router->debug('Starting rendering route');
$router->debug('Starting rendering route "%s"', \get_class($this));
$callback = $this->getCallback();
+61 -19
View File
@@ -258,23 +258,31 @@ class Router
{
$this->debug('Loading routes');
$this->fireEvents(EventHandler::EVENT_BOOT);
$this->fireEvents(EventHandler::EVENT_BOOT, [
'bootmanagers' => $this->bootManagers,
]);
/* Initialize boot-managers */
/* @var $manager IRouterBootManager */
foreach ($this->bootManagers as $manager) {
$this->debug('Rendering bootmanager %s', \get_class($manager));
$this->fireEvents(EventHandler::EVENT_RENDER_BOOTMANAGER, $manager);
$className = \get_class($manager);
$this->debug('Rendering bootmanager "%s"', $className);
$this->fireEvents(EventHandler::EVENT_RENDER_BOOTMANAGER, [
'bootmanagers' => $this->bootManagers,
'bootmanager' => $manager,
]);
/* Render bootmanager */
$manager->boot($this, $this->request);
$this->debug('Finished rendering bootmanager');
$this->debug('Finished rendering bootmanager "%s"', $className);
}
$this->fireEvents(EventHandler::EVENT_LOAD_ROUTES);
$this->fireEvents(EventHandler::EVENT_LOAD_ROUTES, [
'routes' => $this->routes,
]);
/* Loop through each route-request */
$this->processRoutes($this->routes);
@@ -301,7 +309,9 @@ class Router
if ($this->csrfVerifier !== null) {
$this->fireEvents(EventHandler::EVENT_RENDER_CSRF);
$this->fireEvents(EventHandler::EVENT_RENDER_CSRF, [
'csrfVerifier' => $this->csrfVerifier,
]);
/* Verify csrf token for request */
$this->csrfVerifier->handle($this->request);
@@ -309,7 +319,9 @@ class Router
$output = $this->routeRequest();
$this->fireEvents(EventHandler::EVENT_LOAD);
$this->fireEvents(EventHandler::EVENT_LOAD, [
'loadedRoutes' => $this->getRequest()->getLoadedRoutes(),
]);
$this->debug('Routing complete');
@@ -340,7 +352,9 @@ class Router
/* If the route matches */
if ($route->matchRoute($url, $this->request) === true) {
$this->fireEvents(EventHandler::EVENT_MATCH_ROUTE);
$this->fireEvents(EventHandler::EVENT_MATCH_ROUTE, [
'route' => $route,
]);
/* Check if request method matches */
if (\count($route->getRequestMethods()) !== 0 && \in_array($this->request->getMethod(), $route->getRequestMethods(), true) === false) {
@@ -349,7 +363,10 @@ class Router
continue;
}
$this->fireEvents(EventHandler::EVENT_RENDER_MIDDLEWARE);
$this->fireEvents(EventHandler::EVENT_RENDER_MIDDLEWARES, [
'route' => $route,
'middlewares' => $route->getMiddlewares(),
]);
$route->loadMiddleware($this->request, $this);
@@ -361,6 +378,11 @@ class Router
$methodNotAllowed = false;
$this->request->addLoadedRoute($route);
$this->fireEvents(EventHandler::EVENT_RENDER_ROUTE, [
'route' => $route,
]);
$output = $route->renderRoute($this->request, $this);
if ($output !== null) {
return $output;
@@ -427,7 +449,10 @@ class Router
unset($this->processedRoutes[$key]);
$this->request->setHasPendingRewrite(false);
$this->fireEvents(EventHandler::EVENT_REWRITE);
$this->fireEvents(EventHandler::EVENT_REWRITE, [
'rewriteUrl' => $this->request->getRewriteUrl(),
'rewriteRoute' => $this->request->getRewriteRoute(),
]);
return $this->routeRequest();
}
@@ -445,7 +470,10 @@ class Router
{
$this->debug('Starting exception handling for "%s"', \get_class($e));
$this->fireEvents(EventHandler::EVENT_LOAD_EXCEPTIONS);
$this->fireEvents(EventHandler::EVENT_LOAD_EXCEPTIONS, [
'exception' => $e,
'exceptionHandlers' => $this->exceptionHandlers,
]);
/* @var $handler IExceptionHandler */
foreach ($this->exceptionHandlers as $key => $handler) {
@@ -454,7 +482,11 @@ class Router
$handler = new $handler();
}
$this->fireEvents(EventHandler::EVENT_RENDER_EXCEPTION);
$this->fireEvents(EventHandler::EVENT_RENDER_EXCEPTION, [
'exception' => $e,
'exceptionHandler' => $handler,
'exceptionHandlers' => $this->exceptionHandlers,
]);
$this->debug('Processing exception-handler "%s"', \get_class($handler));
@@ -473,7 +505,10 @@ class Router
$this->debug('Exception handler contains rewrite, reloading routes');
$this->fireEvents(EventHandler::EVENT_REWRITE);
$this->fireEvents(EventHandler::EVENT_REWRITE, [
'rewriteUrl' => $this->request->getRewriteUrl(),
'rewriteRoute' => $this->request->getRewriteRoute(),
]);
return $this->routeRequest();
}
@@ -498,7 +533,10 @@ class Router
public function findRoute(string $name): ?ILoadableRoute
{
$this->debug('Finding route by name "%s"', $name);
$this->fireEvents(EventHandler::EVENT_FIND_ROUTE);
$this->fireEvents(EventHandler::EVENT_FIND_ROUTE, [
'name' => $name,
]);
/* @var $route ILoadableRoute */
foreach ($this->processedRoutes as $route) {
@@ -576,7 +614,11 @@ class Router
{
$this->debug('Finding url', \func_get_args());
$this->fireEvents(EventHandler::EVENT_GET_URL);
$this->fireEvents(EventHandler::EVENT_GET_URL, [
'name' => $name,
'parameters' => $parameters,
'getParams' => $getParams,
]);
if ($getParams !== null && \is_array($getParams) === false) {
throw new InvalidArgumentException('Invalid type for getParams. Must be array or null');
@@ -772,12 +814,12 @@ class Router
}
/**
* Fire event
* Fire event in event-handler.
*
* @param string $name
* @param array ...$args
* @param array $arguments
*/
protected function fireEvents($name, ...$args): void
protected function fireEvents($name, array $arguments = []): void
{
if (\count($this->eventHandlers) === 0) {
return;
@@ -785,7 +827,7 @@ class Router
/* @var IEventHandler $eventHandler */
foreach ($this->eventHandlers as $eventHandler) {
$eventHandler->fireEvents($this, $name, $args);
$eventHandler->fireEvents($this, $name, $arguments);
}
}
+2
View File
@@ -51,6 +51,8 @@ class SimpleRouter
/**
* Start routing
*
* @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException
* @throws \Pecee\Http\Middleware\Exceptions\TokenMismatchException
* @throws HttpException
* @throws \Exception
*/
+23 -17
View File
@@ -4,6 +4,7 @@ require_once 'Dummy/DummyMiddleware.php';
require_once 'Dummy/DummyController.php';
require_once 'Dummy/Handler/ExceptionHandler.php';
require_once 'Dummy/Security/SilentTokenProvider.php';
require_once 'Dummy/Managers/TestBootManager.php';
use \Pecee\SimpleRouter\Handlers\EventHandler;
use \Pecee\SimpleRouter\Event\EventArgument;
@@ -11,21 +12,22 @@ use \Pecee\SimpleRouter\Event\EventArgument;
class EventHandlerTest extends \PHPUnit\Framework\TestCase
{
public function testMissingEvents() {
public function testAllEventTriggered()
{
$events = EventHandler::$events;
// Remove the all event
unset($events[\array_search(EventHandler::EVENT_ALL, $events, true)], $events[\array_search(EventHandler::EVENT_REWRITE, $events, true)]);
unset($events[\array_search(EventHandler::EVENT_ALL, $events, true)]);
$eventHandler = new EventHandler();
$eventHandler->register(EventHandler::EVENT_ALL, function(EventArgument $arg) use(&$events) {
$eventHandler->register(EventHandler::EVENT_ALL, function (EventArgument $arg) use (&$events) {
$key = \array_search($arg->getEventName(), $events, true);
unset($events[$key]);
});
TestRouter::addEventHandler($eventHandler);
// Add rewrite
TestRouter::error(function (\Pecee\Http\Request $request, \Exception $error) {
// Trigger rewrite
@@ -35,28 +37,36 @@ class EventHandlerTest extends \PHPUnit\Framework\TestCase
TestRouter::get('/', 'DummyController@method1')->name('home');
// Trigger findRoute
TestRouter::router()->findRoute('home');
// Trigger getUrl
TestRouter::router()->getUrl('home');
// Add csrf-verifier
$csrfVerifier = new \Pecee\Http\Middleware\BaseCsrfVerifier();
$csrfVerifier->setTokenProvider(new SilentTokenProvider());
TestRouter::csrfVerifier($csrfVerifier);
TestRouter::debug('/not-existing');
// Add boot-manager
TestRouter::addBootManager(new TestBootManager([
'/test',
], '/'));
// Start router
TestRouter::debug('/non-existing');
$this->assertEquals($events, []);
TestRouter::router()->reset();
}
public function testAllEvent() {
public function testAllEvent()
{
$status = 0;
$status = false;
$eventHandler = new EventHandler();
$eventHandler->register(EventHandler::EVENT_ALL, function(EventArgument $arg) use(&$status) {
$status++;
$eventHandler->register(EventHandler::EVENT_ALL, function (EventArgument $arg) use (&$status) {
$status = true;
});
TestRouter::addEventHandler($eventHandler);
@@ -65,11 +75,7 @@ class EventHandlerTest extends \PHPUnit\Framework\TestCase
TestRouter::debug('/');
// All event should fire for each other event
$this->assertEquals(\count(EventHandler::$events), $status);
}
public function testEvents() {
$this->assertEquals(true, true);
$this->assertEquals(true, $status);
}
}
+10 -5
View File
@@ -7,23 +7,28 @@ require_once 'Dummy/Handler/ExceptionHandler.php';
class InputHandlerTest extends \PHPUnit\Framework\TestCase
{
public function testGet() {
public function testGet()
{
$this->assertEquals(true, true);
}
public function testPost() {
public function testPost()
{
$this->assertEquals(true, true);
}
public function testFile() {
public function testFile()
{
$this->assertEquals(true, true);
}
public function testFiles() {
public function testFiles()
{
$this->assertEquals(true, true);
}
public function testAll() {
public function testAll()
{
$this->assertEquals(true, true);
}