diff --git a/Slim/App.php b/Slim/App.php index a2ed1c671..616fffab0 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -19,6 +19,8 @@ use Slim\Interfaces\CallableResolverInterface; use Slim\Interfaces\RouteCollectorInterface; use Slim\Interfaces\RouteResolverInterface; +use Slim\Middleware\ErrorMiddleware; +use Slim\Middleware\RoutingMiddleware; use Slim\Routing\RouteCollectorProxy; use Slim\Routing\RouteResolver; use Slim\Routing\RouteRunner; @@ -101,6 +103,46 @@ public function addMiddleware(MiddlewareInterface $middleware): self return $this; } + /** + * Add the slim built-in routing middleware to the app middleware stack + * + * @return RoutingMiddleware + */ + public function addRoutingMiddleware(): RoutingMiddleware + { + $routingMiddleware = new RoutingMiddleware( + $this->getRouteResolver(), + $this->getRouteCollector()->getRouteParser() + ); + $this->add($routingMiddleware); + return $routingMiddleware; + } + + /** + * Add the slim built-in error middleware to the app middleware stack + * + * @param bool $displayErrorDetails + * @param bool $logErrors + * @param bool $logErrorDetails + * + * @return ErrorMiddleware + */ + public function addErrorMiddleware( + bool $displayErrorDetails, + bool $logErrors, + bool $logErrorDetails + ): ErrorMiddleware { + $errorMiddleware = new ErrorMiddleware( + $this->getCallableResolver(), + $this->getResponseFactory(), + $displayErrorDetails, + $logErrors, + $logErrorDetails + ); + $this->add($errorMiddleware); + return $errorMiddleware; + } + /** * Run application * diff --git a/tests/AppTest.php b/tests/AppTest.php index 099509717..c36b53cef 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -28,6 +28,9 @@ use Slim\Interfaces\RouteCollectorInterface; use Slim\Interfaces\RouteCollectorProxyInterface; use Slim\Interfaces\RouteParserInterface; +use Slim\Middleware\ErrorMiddleware; +use Slim\Middleware\RoutingMiddleware; +use Slim\MiddlewareDispatcher; use Slim\Routing\RouteCollector; use Slim\Routing\RouteCollectorProxy; use Slim\Tests\Mocks\MockAction; @@ -651,6 +654,66 @@ public function testAddMiddlewareUsingDeferredResolution() $this->assertSame('Hello World', (string) $response->getBody()); } + public function testAddRoutingMiddleware() + { + /** @var ResponseFactoryInterface $responseFactory */ + $responseFactory = $this->prophesize(ResponseFactoryInterface::class)->reveal(); + + // Create the app. + $app = new App($responseFactory); + + // Add the routing middleware. + $routingMiddleware = $app->addRoutingMiddleware(); + + // Check that the routing middleware really has been added to the tip of the app middleware stack. + $middlewareDispatcherProperty = new \ReflectionProperty(App::class, 'middlewareDispatcher'); + $middlewareDispatcherProperty->setAccessible(true); + /** @var MiddlewareDispatcher $middlewareDispatcher */ + $middlewareDispatcher = $middlewareDispatcherProperty->getValue($app); + + $tipProperty = new \ReflectionProperty(MiddlewareDispatcher::class, 'tip'); + $tipProperty->setAccessible(true); + /** @var RequestHandlerInterface $tip */ + $tip = $tipProperty->getValue($middlewareDispatcher); + + $reflection = new \ReflectionClass($tip); + $middlewareProperty = $reflection->getProperty('middleware'); + $middlewareProperty->setAccessible(true); + + $this->assertSame($routingMiddleware, $middlewareProperty->getValue($tip)); + $this->assertInstanceOf(RoutingMiddleware::class, $routingMiddleware); + } + + public function testAddErrorMiddleware() + { + /** @var ResponseFactoryInterface $responseFactory */ + $responseFactory = $this->prophesize(ResponseFactoryInterface::class)->reveal(); + + // Create the app. + $app = new App($responseFactory); + + // Add the error middleware. + $errorMiddleware = $app->addErrorMiddleware(true, true, true); + + // Check that the error middleware really has been added to the tip of the app middleware stack. + $middlewareDispatcherProperty = new \ReflectionProperty(App::class, 'middlewareDispatcher'); + $middlewareDispatcherProperty->setAccessible(true); + /** @var MiddlewareDispatcher $middlewareDispatcher */ + $middlewareDispatcher = $middlewareDispatcherProperty->getValue($app); + + $tipProperty = new \ReflectionProperty(MiddlewareDispatcher::class, 'tip'); + $tipProperty->setAccessible(true); + /** @var RequestHandlerInterface $tip */ + $tip = $tipProperty->getValue($middlewareDispatcher); + + $reflection = new \ReflectionClass($tip); + $middlewareProperty = $reflection->getProperty('middleware'); + $middlewareProperty->setAccessible(true); + + $this->assertSame($errorMiddleware, $middlewareProperty->getValue($tip)); + $this->assertInstanceOf(ErrorMiddleware::class, $errorMiddleware); + } + public function testAddMiddlewareOnRoute() { $output = '';