From 24cc28cb07ca10eaf8d76aaecca4514505ce1576 Mon Sep 17 00:00:00 2001 From: Petr Hejna Date: Tue, 20 Mar 2018 14:00:20 +0100 Subject: [PATCH] Revert "Revert "Global app middlewares and multiple action methods"" --- README.md | 9 +++-- src/SlimApplicationFactory.php | 52 ++++++++++++++++++++++++---- tests/Dummy/AllRouteMiddleware.php | 24 +++++++++++++ tests/Dummy/AppMiddleware.php | 24 +++++++++++++ tests/SlimApplicationFactoryTest.php | 22 +++++++++++- tests/config.neon | 9 +++++ 6 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 tests/Dummy/AllRouteMiddleware.php create mode 100644 tests/Dummy/AppMiddleware.php diff --git a/README.md b/README.md index 9207c25..50e00fd 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ slimApi: # Configure it ``` -### First API enpoint +### First API endpoint Now let's say you want to make a REST endpoint creating channels, `[POST] /new-api/2.0/channels` You need to define in `parameters.api` section in `config.neon`. @@ -71,7 +71,12 @@ parameters: - App\SomeOtherMiddleware # last in row - App\UsuallyRequestDataValidationMiddleware # second in row - App\SomeAuthMiddleware # this one is called first - + + globalMiddlewares: + - App\SomeGlobalMiddleware # this is called for each route, before route middlewares + + appMiddlewares: + - App\SomeAppMiddleware # this is called for each request ``` You can also reference the named service by it's name. diff --git a/src/SlimApplicationFactory.php b/src/SlimApplicationFactory.php index b669e29..61b17b8 100644 --- a/src/SlimApplicationFactory.php +++ b/src/SlimApplicationFactory.php @@ -22,6 +22,11 @@ final class SlimApplicationFactory */ private $container; + /** + * @var Middleware[] + */ + private $globalMiddlewares; + /** * @param array $configuration * @param Container $container @@ -30,6 +35,7 @@ public function __construct(array $configuration, Container $container) { $this->configuration = $configuration; $this->container = $container; + $this->globalMiddlewares = []; } /** @@ -41,6 +47,8 @@ public function create() $configuration = $this->getConfiguration($this->configuration['apiDefinitionKey']); + $this->registerGlobalMiddlewares($app, $configuration); + foreach ($configuration['routes'] as $apiName => $api) { $this->registerApis($app, $api, $apiName); } @@ -55,6 +63,12 @@ public function create() $this->registerHandlers($app, $configuration['handlers']); } + if (isset($configuration['appMiddlewares'])) { + foreach ($configuration['appMiddlewares'] as $globalMiddleware) { + $this->registerAppMiddleware($app, $globalMiddleware); + } + } + return $app; } @@ -146,7 +160,9 @@ private function registerHandlers(SlimApp $app, array $handlers) */ private function registerServiceIntoContainer(SlimApp $app, $serviceName) { - $app->getContainer()[$serviceName] = $this->getServiceProvider($serviceName); + if (!$app->getContainer()->has($serviceName)) { + $app->getContainer()[$serviceName] = $this->getServiceProvider($serviceName); + } } /** @@ -212,15 +228,15 @@ private function registerInvokableActionRoutes(SlimApp $app, array $routeData, $ if (isset($config['middleware']) && count($config['middleware']) > 0) { foreach ($config['middleware'] as $middleware) { - $container = $app->getContainer(); - - if (!$container->has($middleware)) { - $this->registerServiceIntoContainer($app, $middleware); - } + $this->registerServiceIntoContainer($app, $middleware); $routeToAdd->add($middleware); } } + + foreach ($this->globalMiddlewares as $globalMiddleware) { + $routeToAdd->add($globalMiddleware); + } } } @@ -235,4 +251,28 @@ private function createUrlPattern($apiName, $version, $routeName) return sprintf('/%s/%s%s', $apiName, $version, $routeName); } + /** + * @param SlimApp $app + * @param string $middleware + */ + private function registerAppMiddleware(SlimApp $app, $middleware) + { + $this->registerServiceIntoContainer($app, $middleware); + + $app->add($middleware); + } + + /** + * @param SlimApp $app + * @param array $configuration + */ + private function registerGlobalMiddlewares(SlimApp $app, $configuration) + { + if (isset($configuration['globalMiddlewares']) && count($configuration['globalMiddlewares']) > 0) { + foreach ($configuration['globalMiddlewares'] as $globalMiddleware) { + $this->registerServiceIntoContainer($app, $globalMiddleware); + $this->globalMiddlewares[] = $app->getContainer()->get($globalMiddleware); + } + } + } } diff --git a/tests/Dummy/AllRouteMiddleware.php b/tests/Dummy/AllRouteMiddleware.php new file mode 100644 index 0000000..1bbbdd5 --- /dev/null +++ b/tests/Dummy/AllRouteMiddleware.php @@ -0,0 +1,24 @@ +withAddedHeader('processed-by-all-route-middleware', 'correct'); + + return $next($request, $response); + } +} diff --git a/tests/Dummy/AppMiddleware.php b/tests/Dummy/AppMiddleware.php new file mode 100644 index 0000000..ddcd24c --- /dev/null +++ b/tests/Dummy/AppMiddleware.php @@ -0,0 +1,24 @@ +withAddedHeader('processed-by-app-middleware', 'correct'); + + return $next($request, $response); + } +} diff --git a/tests/SlimApplicationFactoryTest.php b/tests/SlimApplicationFactoryTest.php index c502abb..c47a497 100644 --- a/tests/SlimApplicationFactoryTest.php +++ b/tests/SlimApplicationFactoryTest.php @@ -7,7 +7,6 @@ use BrandEmbassy\Slim\SlimApplicationFactory; use BrandEmbassy\Slim\Request\Request; use BrandEmbassy\Slim\Response\Response; -use LogicException; use Nette\DI\Compiler; use Nette\DI\Container; use Nette\DI\ContainerLoader; @@ -87,6 +86,27 @@ public function testShouldAllowRequestByAccessMiddleware() $this->assertEquals('{"channelId":"fb_1234"}', $this->getContents($response)); } + public function testShouldHaveHeaderByGlobalMiddleware() + { + $request = $this->createRequest('POST', '/new-api/2.0/channels'); + + /** @var ResponseInterface $response */ + $response = $this->createSlimApp()->process($request, new Response(new \Slim\Http\Response())); + + $this->assertEquals(['correct'], $response->getHeader('processed-by-all-route-middleware')); + $this->assertEquals(['correct'], $response->getHeader('processed-by-app-middleware')); + } + + public function testShouldProcessedByAppMiddleware() + { + $request = $this->createRequest('POST', '/non-existing/path'); + + /** @var ResponseInterface $response */ + $response = $this->createSlimApp()->process($request, new Response(new \Slim\Http\Response())); + + $this->assertEquals(['correct'], $response->getHeader('processed-by-app-middleware')); + } + /** * @param string $configPath * @return Container diff --git a/tests/config.neon b/tests/config.neon index 66ae14a..2fcfc5d 100644 --- a/tests/config.neon +++ b/tests/config.neon @@ -9,6 +9,8 @@ services: - BrandEmbassyTest\Slim\Dummy\GoldenKeyAuthMiddleware - BrandEmbassyTest\Slim\Dummy\CreateChannelAction - BrandEmbassyTest\Slim\Dummy\ErroringAction + - BrandEmbassyTest\Slim\Dummy\AllRouteMiddleware + - BrandEmbassyTest\Slim\Dummy\AppMiddleware parameters: api: @@ -30,6 +32,13 @@ parameters: post: service: BrandEmbassyTest\Slim\Dummy\ErroringAction + globalMiddlewares: + - BrandEmbassyTest\Slim\Dummy\AllRouteMiddleware + + appMiddlewares: + - BrandEmbassyTest\Slim\Dummy\AppMiddleware + + slimApi: slimConfiguration: settings: