mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-07-11 23:42:15 +00:00
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:
@@ -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');
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ class SimpleRouter
|
||||
/**
|
||||
* Start routing
|
||||
*
|
||||
* @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException
|
||||
* @throws \Pecee\Http\Middleware\Exceptions\TokenMismatchException
|
||||
* @throws HttpException
|
||||
* @throws \Exception
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user