diff --git a/Slim/Routing/RouteCollector.php b/Slim/Routing/RouteCollector.php index a6947cdac..4a7428516 100644 --- a/Slim/Routing/RouteCollector.php +++ b/Slim/Routing/RouteCollector.php @@ -59,6 +59,13 @@ class RouteCollector implements RouteCollectorInterface */ protected array $routes = []; + /** + * Routes indexed by name + * + * @var RouteInterface[] + */ + protected array $routesByName = []; + /** * Route groups * @@ -172,7 +179,8 @@ public function getRoutes(): array public function removeNamedRoute(string $name): RouteCollectorInterface { $route = $this->getNamedRoute($name); - unset($this->routes[$route->getIdentifier()]); + + unset($this->routesByName[$route->getName()], $this->routes[$route->getIdentifier()]); return $this; } @@ -181,11 +189,22 @@ public function removeNamedRoute(string $name): RouteCollectorInterface */ public function getNamedRoute(string $name): RouteInterface { + if (isset($this->routesByName[$name])) { + $route = $this->routesByName[$name]; + if ($route->getName() === $name) { + return $route; + } + + unset($this->routesByName[$name]); + } + foreach ($this->routes as $route) { if ($name === $route->getName()) { + $this->routesByName[$name] = $route; return $route; } } + throw new RuntimeException('Named route does not exist for name: ' . $name); } @@ -229,6 +248,12 @@ public function map(array $methods, string $pattern, $handler): RouteInterface { $route = $this->createRoute($methods, $pattern, $handler); $this->routes[$route->getIdentifier()] = $route; + + $routeName = $route->getName(); + if ($routeName !== null && !isset($this->routesByName[$routeName])) { + $this->routesByName[$routeName] = $route; + } + $this->routeCounter++; return $route; diff --git a/tests/Handlers/ErrorHandlerTest.php b/tests/Handlers/ErrorHandlerTest.php index 0a97c0c7e..f23acd6b3 100644 --- a/tests/Handlers/ErrorHandlerTest.php +++ b/tests/Handlers/ErrorHandlerTest.php @@ -296,7 +296,7 @@ public function testOptions() $exception->setAllowedMethods(['POST', 'PUT']); /** @var ResponseInterface $res */ - $res = $handler->__invoke($request, $exception, true, true, true); + $res = $handler->__invoke($request, $exception, true, false, true); $this->assertSame(200, $res->getStatusCode()); $this->assertTrue($res->hasHeader('Allow')); @@ -367,7 +367,7 @@ public function testDefaultErrorRenderer() $exception = new RuntimeException(); /** @var ResponseInterface $res */ - $res = $handler->__invoke($request, $exception, true, true, true); + $res = $handler->__invoke($request, $exception, true, false, true); $this->assertTrue($res->hasHeader('Content-Type')); $this->assertSame('text/html', $res->getHeaderLine('Content-Type')); @@ -388,6 +388,10 @@ public function testLogErrorRenderer() $handler = new ErrorHandler($callableResolverProphecy->reveal(), $this->getResponseFactory()); $handler->setLogErrorRenderer('logErrorRenderer'); + $displayErrorDetailsProperty = new ReflectionProperty($handler, 'displayErrorDetails'); + $displayErrorDetailsProperty->setAccessible(true); + $displayErrorDetailsProperty->setValue($handler, true); + $exception = new RuntimeException(); $exceptionProperty = new ReflectionProperty($handler, 'exception'); $exceptionProperty->setAccessible(true);