mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-07-11 15:52:14 +00:00
Merge pull request #577 from skipperbent/v4-prevent-merge-attribute
Added group attribute to stop router from merging exception-handlers (issue: #573)
This commit is contained in:
@@ -62,6 +62,7 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c
|
|||||||
- [ExceptionHandlers](#exceptionhandlers)
|
- [ExceptionHandlers](#exceptionhandlers)
|
||||||
- [Handling 404, 403 and other errors](#handling-404-403-and-other-errors)
|
- [Handling 404, 403 and other errors](#handling-404-403-and-other-errors)
|
||||||
- [Using custom exception handlers](#using-custom-exception-handlers)
|
- [Using custom exception handlers](#using-custom-exception-handlers)
|
||||||
|
- [Stop merge of parent exception-handlers](#stop-merge-of-parent-exception-handlers)
|
||||||
- [Urls](#urls)
|
- [Urls](#urls)
|
||||||
- [Get the current url](#get-the-current-url)
|
- [Get the current url](#get-the-current-url)
|
||||||
- [Get by name (single route)](#get-by-name-single-route)
|
- [Get by name (single route)](#get-by-name-single-route)
|
||||||
@@ -1014,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
|
||||||
|
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stop 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
|
# Urls
|
||||||
|
|||||||
@@ -31,6 +31,21 @@ interface IGroupRoute extends IRoute
|
|||||||
*/
|
*/
|
||||||
public function setExceptionHandlers(array $handlers): self;
|
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
|
* Get exception-handlers for group
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class RouteGroup extends Route implements IGroupRoute
|
|||||||
protected $name;
|
protected $name;
|
||||||
protected $domains = [];
|
protected $domains = [];
|
||||||
protected $exceptionHandlers = [];
|
protected $exceptionHandlers = [];
|
||||||
|
protected $mergeExceptionHandlers = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to check if a domain matches
|
* Method called to check if a domain matches
|
||||||
@@ -36,6 +37,7 @@ class RouteGroup extends Route implements IGroupRoute
|
|||||||
|
|
||||||
if ($parameters !== null && count($parameters) !== 0) {
|
if ($parameters !== null && count($parameters) !== 0) {
|
||||||
$this->parameters = $parameters;
|
$this->parameters = $parameters;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,6 +176,29 @@ class RouteGroup extends Route implements IGroupRoute
|
|||||||
return $this->prefix;
|
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.
|
* Merge with information from another route.
|
||||||
*
|
*
|
||||||
@@ -187,6 +212,10 @@ class RouteGroup extends Route implements IGroupRoute
|
|||||||
$this->setPrefix($settings['prefix'] . $this->prefix);
|
$this->setPrefix($settings['prefix'] . $this->prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($settings['mergeExceptionHandlers']) === true) {
|
||||||
|
$this->setMergeExceptionHandlers($settings['mergeExceptionHandlers']);
|
||||||
|
}
|
||||||
|
|
||||||
if ($merge === false && isset($settings['exceptionHandler']) === true) {
|
if ($merge === false && isset($settings['exceptionHandler']) === true) {
|
||||||
$this->setExceptionHandlers((array)$settings['exceptionHandler']);
|
$this->setExceptionHandlers((array)$settings['exceptionHandler']);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ class Router
|
|||||||
public function addRoute(IRoute $route): IRoute
|
public function addRoute(IRoute $route): IRoute
|
||||||
{
|
{
|
||||||
$this->fireEvents(EventHandler::EVENT_ADD_ROUTE, [
|
$this->fireEvents(EventHandler::EVENT_ADD_ROUTE, [
|
||||||
'route' => $route,
|
'route' => $route,
|
||||||
'isSubRoute' => $this->isProcessingRoute,
|
'isSubRoute' => $this->isProcessingRoute,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ class Router
|
|||||||
/**
|
/**
|
||||||
* Process added routes.
|
* Process added routes.
|
||||||
*
|
*
|
||||||
* @param array $routes
|
* @param array|IRoute[] $routes
|
||||||
* @param IGroupRoute|null $group
|
* @param IGroupRoute|null $group
|
||||||
* @throws NotFoundHttpException
|
* @throws NotFoundHttpException
|
||||||
*/
|
*/
|
||||||
@@ -211,9 +211,6 @@ class Router
|
|||||||
{
|
{
|
||||||
$this->debug('Processing routes');
|
$this->debug('Processing routes');
|
||||||
|
|
||||||
// Loop through each route-request
|
|
||||||
$exceptionHandlers = [];
|
|
||||||
|
|
||||||
// Stop processing routes if no valid route is found.
|
// Stop processing routes if no valid route is found.
|
||||||
if ($this->request->getRewriteRoute() === null && $this->request->getUrl()->getOriginalUrl() === '') {
|
if ($this->request->getRewriteRoute() === null && $this->request->getUrl()->getOriginalUrl() === '') {
|
||||||
$this->debug('Halted route-processing as no valid route was found');
|
$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();
|
$url = $this->request->getRewriteUrl() ?? $this->request->getUrl()->getPath();
|
||||||
|
|
||||||
/* @var $route IRoute */
|
// Loop through each route-request
|
||||||
foreach ($routes as $route) {
|
foreach ($routes as $route) {
|
||||||
|
|
||||||
$this->debug('Processing route "%s"', get_class($route));
|
$this->debug('Processing route "%s"', get_class($route));
|
||||||
@@ -240,13 +237,22 @@ class Router
|
|||||||
|
|
||||||
/* Add exception handlers */
|
/* Add exception handlers */
|
||||||
if (count($route->getExceptionHandlers()) !== 0) {
|
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 */
|
/* Only render partial group if it matches */
|
||||||
if ($route instanceof IPartialGroupRoute === true) {
|
if ($route instanceof IPartialGroupRoute === true) {
|
||||||
$this->renderAndProcess($route);
|
$this->renderAndProcess($route);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -264,8 +270,6 @@ class Router
|
|||||||
$this->processedRoutes[] = $route;
|
$this->processedRoutes[] = $route;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->exceptionHandlers = array_merge($exceptionHandlers, $this->exceptionHandlers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -679,7 +683,7 @@ class Router
|
|||||||
->setParams($getParams);
|
->setParams($getParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($name !== null) {
|
if ($name !== null) {
|
||||||
/* We try to find a match on the given name */
|
/* We try to find a match on the given name */
|
||||||
$route = $this->findRoute($name);
|
$route = $this->findRoute($name);
|
||||||
|
|
||||||
@@ -942,6 +946,7 @@ class Router
|
|||||||
public function addExceptionHandler(IExceptionHandler $handler): self
|
public function addExceptionHandler(IExceptionHandler $handler): self
|
||||||
{
|
{
|
||||||
$this->exceptionHandlers[] = $handler;
|
$this->exceptionHandlers[] = $handler;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ class RouterRewriteTest extends \PHPUnit\Framework\TestCase
|
|||||||
global $stack;
|
global $stack;
|
||||||
$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');
|
TestRouter::get('/my-path', 'DummyController@method1');
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ class RouterRewriteTest extends \PHPUnit\Framework\TestCase
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TestRouter::debug('/my-non-existing-path', 'get');
|
TestRouter::debug('/test/non-existing', 'get');
|
||||||
} catch (\ResponseException $e) {
|
} 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()
|
public function testRewriteExceptionMessage()
|
||||||
{
|
{
|
||||||
$this->expectException(\Pecee\SimpleRouter\Exceptions\NotFoundHttpException::class);
|
$this->expectException(\Pecee\SimpleRouter\Exceptions\NotFoundHttpException::class);
|
||||||
|
|||||||
Reference in New Issue
Block a user