mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-06-21 18:51:26 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 032a2ae7e0 | |||
| c2e2d3bb5d | |||
| 5dd0690009 | |||
| ee61eda1e8 | |||
| 471bbe137f | |||
| b17ba06a8c | |||
| 69494265a5 | |||
| 0d8915b206 | |||
| b54a25804a | |||
| 4b8dbdc9e5 | |||
| 7fe66ac938 |
@@ -62,6 +62,7 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c
|
||||
- [ExceptionHandlers](#exceptionhandlers)
|
||||
- [Handling 404, 403 and other errors](#handling-404-403-and-other-errors)
|
||||
- [Using custom exception handlers](#using-custom-exception-handlers)
|
||||
- [Prevent merge of parent exception-handlers](#prevent-merge-of-parent-exception-handlers)
|
||||
- [Urls](#urls)
|
||||
- [Get the current url](#get-the-current-url)
|
||||
- [Get by name (single route)](#get-by-name-single-route)
|
||||
@@ -791,7 +792,7 @@ If you want to store the token elsewhere, please refer to the "Creating custom T
|
||||
When you've created your CSRF-verifier you need to tell simple-php-router that it should use it. You can do this by adding the following line in your `routes.php` file:
|
||||
|
||||
```php
|
||||
Router::csrfVerifier(new \Demo\Middlewares\CsrfVerifier());
|
||||
SimpleRouter::csrfVerifier(new \Demo\Middlewares\CsrfVerifier());
|
||||
```
|
||||
|
||||
## Getting CSRF-token
|
||||
@@ -807,7 +808,7 @@ csrf_token();
|
||||
You can also get the token directly:
|
||||
|
||||
```php
|
||||
return Router::router()->getCsrfVerifier()->getTokenProvider()->getToken();
|
||||
return SimpleRouter::router()->getCsrfVerifier()->getTokenProvider()->getToken();
|
||||
```
|
||||
|
||||
The default name/key for the input-field is `csrf_token` and is defined in the `POST_KEY` constant in the `BaseCsrfVerifier` class.
|
||||
@@ -893,10 +894,10 @@ class SessionTokenProvider implements ITokenProvider
|
||||
Next you need to set your custom `ITokenProvider` implementation on your `BaseCsrfVerifier` class in your routes file:
|
||||
|
||||
```php
|
||||
$verifier = new \dscuz\Middleware\CsrfVerifier();
|
||||
$verifier = new \Demo\Middlewares\CsrfVerifier();
|
||||
$verifier->setTokenProvider(new SessionTokenProvider());
|
||||
|
||||
Router::csrfVerifier($verifier);
|
||||
SimpleRouter::csrfVerifier($verifier);
|
||||
```
|
||||
|
||||
---
|
||||
@@ -938,7 +939,7 @@ ExceptionHandler are classes that handles all exceptions. ExceptionsHandlers mus
|
||||
|
||||
## Handling 404, 403 and other errors
|
||||
|
||||
If you simply want to catch a 404 (page not found) etc. you can use the `Router::error($callback)` static helper method.
|
||||
If you simply want to catch a 404 (page not found) etc. you can use the `SimpleRouter::error($callback)` static helper method.
|
||||
|
||||
This will add a callback method which is fired whenever an error occurs on all routes.
|
||||
|
||||
@@ -946,17 +947,31 @@ The basic example below simply redirect the page to `/not-found` if an `NotFound
|
||||
The code should be placed in the file that contains your routes.
|
||||
|
||||
```php
|
||||
Router::get('/not-found', 'PageController@notFound');
|
||||
SimpleRouter::get('/not-found', 'PageController@notFound');
|
||||
SimpleRouter::get('/forbidden', 'PageController@notFound');
|
||||
|
||||
Router::error(function(Request $request, \Exception $exception) {
|
||||
SimpleRouter::error(function(Request $request, \Exception $exception) {
|
||||
|
||||
if($exception instanceof NotFoundHttpException && $exception->getCode() === 404) {
|
||||
response()->redirect('/not-found');
|
||||
switch($exception->getCode()) {
|
||||
// Page not found
|
||||
case 404:
|
||||
response()->redirect('/not-found');
|
||||
// Forbidden
|
||||
case 403:
|
||||
response()->redirect('/forbidden');
|
||||
}
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
The example above will redirect all errors with http-code `404` (page not found) to `/not-found` and `403` (forbidden) to `/forbidden`.
|
||||
|
||||
If you do not want a redirect, but want the error-page rendered on the current-url, you can tell the router to execute a rewrite callback like so:
|
||||
|
||||
```php
|
||||
$request->setRewriteCallback('ErrorController@notFound');
|
||||
```
|
||||
|
||||
## Using custom exception handlers
|
||||
|
||||
This is a basic example of an ExceptionHandler implementation (please see "[Easily overwrite route about to be loaded](#easily-overwrite-route-about-to-be-loaded)" for examples on how to change callback).
|
||||
@@ -1000,6 +1015,41 @@ class CustomExceptionHandler implements IExceptionHandler
|
||||
}
|
||||
```
|
||||
|
||||
You can add your custom exception-handler class to your group by using the `exceptionHandler` settings-attribute.
|
||||
`exceptionHandler` can be either class-name or array of class-names.
|
||||
|
||||
```php
|
||||
SimpleRouter::group(['exceptionHandler' => \Demo\Handlers\CustomExceptionHandler::class], function() {
|
||||
|
||||
// Your routes here
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
### Prevent merge of parent exception-handlers
|
||||
|
||||
By default the router will merge exception-handlers to any handlers provided by parent groups, and will be executed in the order of newest to oldest.
|
||||
|
||||
If you want your groups exception handler to be executed independently, you can add the `mergeExceptionHandlers` attribute and set it to `false`.
|
||||
|
||||
```php
|
||||
SimpleRouter::group(['prefix' => '/', 'exceptionHandler' => \Demo\Handlers\FirstExceptionHandler::class, 'mergeExceptionHandlers' => false], function() {
|
||||
|
||||
SimpleRouter::group(['prefix' => '/admin', 'exceptionHandler' => \Demo\Handlers\SecondExceptionHandler::class], function() {
|
||||
|
||||
// Both SecondExceptionHandler and FirstExceptionHandler will trigger (in that order).
|
||||
|
||||
});
|
||||
|
||||
SimpleRouter::group(['prefix' => '/user', 'exceptionHandler' => \Demo\Handlers\SecondExceptionHandler::class, 'mergeExceptionHandlers' => false], function() {
|
||||
|
||||
// Only SecondExceptionHandler will trigger.
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Urls
|
||||
@@ -1297,7 +1347,7 @@ All event callbacks will retrieve a `EventArgument` object as parameter. This ob
|
||||
| `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_GET_URL` | `name`<br>`parameters`<br>`getParams` | Fires whenever the `SimpleRouter::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. |
|
||||
@@ -1480,7 +1530,7 @@ $eventHandler->register(EventHandler::EVENT_ADD_ROUTE, function(EventArgument $e
|
||||
|
||||
});
|
||||
|
||||
TestRouter::addEventHandler($eventHandler);
|
||||
SimpleRouter::addEventHandler($eventHandler);
|
||||
```
|
||||
|
||||
In the example shown above, we create a new `EVENT_ADD_ROUTE` event that triggers, when a new route is added.
|
||||
|
||||
@@ -31,6 +31,21 @@ interface IGroupRoute extends IRoute
|
||||
*/
|
||||
public function setExceptionHandlers(array $handlers): self;
|
||||
|
||||
/**
|
||||
* Returns true if group should overwrite existing exception-handlers.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getMergeExceptionHandlers(): bool;
|
||||
|
||||
/**
|
||||
* When enabled group will overwrite any existing exception-handlers.
|
||||
*
|
||||
* @param bool $merge
|
||||
* @return static
|
||||
*/
|
||||
public function setMergeExceptionHandlers(bool $merge): self;
|
||||
|
||||
/**
|
||||
* Get exception-handlers for group
|
||||
*
|
||||
|
||||
@@ -12,6 +12,7 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
protected $name;
|
||||
protected $domains = [];
|
||||
protected $exceptionHandlers = [];
|
||||
protected $mergeExceptionHandlers = true;
|
||||
|
||||
/**
|
||||
* Method called to check if a domain matches
|
||||
@@ -36,6 +37,7 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
|
||||
if ($parameters !== null && count($parameters) !== 0) {
|
||||
$this->parameters = $parameters;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +78,7 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
}
|
||||
|
||||
/* Skip if prefix doesn't match */
|
||||
if ($this->prefix !== null && stripos($url, $parsedPrefix) === false) {
|
||||
if ($this->prefix !== null && stripos($url, rtrim($parsedPrefix, '/') . '/') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -174,6 +176,29 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* When enabled group will overwrite any existing exception-handlers.
|
||||
*
|
||||
* @param bool $merge
|
||||
* @return static
|
||||
*/
|
||||
public function setMergeExceptionHandlers(bool $merge): IGroupRoute
|
||||
{
|
||||
$this->mergeExceptionHandlers = $merge;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if group should overwrite existing exception-handlers.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getMergeExceptionHandlers(): bool
|
||||
{
|
||||
return $this->mergeExceptionHandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge with information from another route.
|
||||
*
|
||||
@@ -187,6 +212,10 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
$this->setPrefix($settings['prefix'] . $this->prefix);
|
||||
}
|
||||
|
||||
if (isset($settings['mergeExceptionHandlers']) === true) {
|
||||
$this->setMergeExceptionHandlers($settings['mergeExceptionHandlers']);
|
||||
}
|
||||
|
||||
if ($merge === false && isset($settings['exceptionHandler']) === true) {
|
||||
$this->setExceptionHandlers((array)$settings['exceptionHandler']);
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ class Router
|
||||
public function addRoute(IRoute $route): IRoute
|
||||
{
|
||||
$this->fireEvents(EventHandler::EVENT_ADD_ROUTE, [
|
||||
'route' => $route,
|
||||
'route' => $route,
|
||||
'isSubRoute' => $this->isProcessingRoute,
|
||||
]);
|
||||
|
||||
@@ -203,7 +203,7 @@ class Router
|
||||
/**
|
||||
* Process added routes.
|
||||
*
|
||||
* @param array $routes
|
||||
* @param array|IRoute[] $routes
|
||||
* @param IGroupRoute|null $group
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
@@ -211,9 +211,6 @@ class Router
|
||||
{
|
||||
$this->debug('Processing routes');
|
||||
|
||||
// Loop through each route-request
|
||||
$exceptionHandlers = [];
|
||||
|
||||
// Stop processing routes if no valid route is found.
|
||||
if ($this->request->getRewriteRoute() === null && $this->request->getUrl()->getOriginalUrl() === '') {
|
||||
$this->debug('Halted route-processing as no valid route was found');
|
||||
@@ -223,7 +220,7 @@ class Router
|
||||
|
||||
$url = $this->request->getRewriteUrl() ?? $this->request->getUrl()->getPath();
|
||||
|
||||
/* @var $route IRoute */
|
||||
// Loop through each route-request
|
||||
foreach ($routes as $route) {
|
||||
|
||||
$this->debug('Processing route "%s"', get_class($route));
|
||||
@@ -240,13 +237,22 @@ class Router
|
||||
|
||||
/* Add exception handlers */
|
||||
if (count($route->getExceptionHandlers()) !== 0) {
|
||||
/** @noinspection AdditionOperationOnArraysInspection */
|
||||
$exceptionHandlers += $route->getExceptionHandlers();
|
||||
|
||||
if ($route->getMergeExceptionHandlers() === true) {
|
||||
|
||||
foreach ($route->getExceptionHandlers() as $handler) {
|
||||
$this->exceptionHandlers[] = $handler;
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->exceptionHandlers = $route->getExceptionHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
/* Only render partial group if it matches */
|
||||
if ($route instanceof IPartialGroupRoute === true) {
|
||||
$this->renderAndProcess($route);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -264,8 +270,6 @@ class Router
|
||||
$this->processedRoutes[] = $route;
|
||||
}
|
||||
}
|
||||
|
||||
$this->exceptionHandlers = array_merge($exceptionHandlers, $this->exceptionHandlers);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -679,7 +683,7 @@ class Router
|
||||
->setParams($getParams);
|
||||
}
|
||||
|
||||
if($name !== null) {
|
||||
if ($name !== null) {
|
||||
/* We try to find a match on the given name */
|
||||
$route = $this->findRoute($name);
|
||||
|
||||
@@ -942,6 +946,7 @@ class Router
|
||||
public function addExceptionHandler(IExceptionHandler $handler): self
|
||||
{
|
||||
$this->exceptionHandlers[] = $handler;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ class RouterRewriteTest extends \PHPUnit\Framework\TestCase
|
||||
global $stack;
|
||||
$stack = [];
|
||||
|
||||
TestRouter::group(['exceptionHandler' => [ExceptionHandlerFirst::class, ExceptionHandlerSecond::class]], function () use ($stack) {
|
||||
TestRouter::group(['exceptionHandler' => [ExceptionHandlerFirst::class, ExceptionHandlerSecond::class]], function () {
|
||||
|
||||
TestRouter::group(['exceptionHandler' => ExceptionHandlerThird::class], function () use ($stack) {
|
||||
TestRouter::group(['prefix' => '/test', 'exceptionHandler' => ExceptionHandlerThird::class], function () {
|
||||
|
||||
TestRouter::get('/my-path', 'DummyController@method1');
|
||||
|
||||
@@ -43,7 +43,7 @@ class RouterRewriteTest extends \PHPUnit\Framework\TestCase
|
||||
});
|
||||
|
||||
try {
|
||||
TestRouter::debug('/my-non-existing-path', 'get');
|
||||
TestRouter::debug('/test/non-existing', 'get');
|
||||
} catch (\ResponseException $e) {
|
||||
|
||||
}
|
||||
@@ -58,6 +58,33 @@ class RouterRewriteTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testStopMergeExceptionHandlers()
|
||||
{
|
||||
global $stack;
|
||||
$stack = [];
|
||||
|
||||
TestRouter::group(['prefix' => '/', 'exceptionHandler' => ExceptionHandlerFirst::class], function () {
|
||||
|
||||
TestRouter::group(['prefix' => '/admin', 'exceptionHandler' => ExceptionHandlerSecond::class, 'mergeExceptionHandlers' => false], function () {
|
||||
|
||||
TestRouter::get('/my-path', 'DummyController@method1');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
TestRouter::debug('/admin/my-path-test', 'get');
|
||||
} catch (\Pecee\SimpleRouter\Exceptions\NotFoundHttpException $e) {
|
||||
|
||||
}
|
||||
|
||||
$expectedStack = [
|
||||
ExceptionHandlerSecond::class,
|
||||
];
|
||||
|
||||
$this->assertEquals($expectedStack, $stack);
|
||||
}
|
||||
|
||||
public function testRewriteExceptionMessage()
|
||||
{
|
||||
$this->expectException(\Pecee\SimpleRouter\Exceptions\NotFoundHttpException::class);
|
||||
|
||||
Reference in New Issue
Block a user