diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ac315c..ff712e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [UNRELEASED] +## [1.0.0] - 2018-01-24 ### Added - Improved testing and added code coverage reporting - Added tests for PHP 7.2 +- Added support for `Closure` handlers ### Changed @@ -69,7 +70,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). First version -[UNRELEASED]: https://github.com/middlewares/request-handler/compare/v0.5.0...HEAD +[1.0.0]: https://github.com/middlewares/request-handler/compare/v0.5.0...v1.0.0 [0.5.0]: https://github.com/middlewares/request-handler/compare/v0.4.0...v0.5.0 [0.4.0]: https://github.com/middlewares/request-handler/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/middlewares/request-handler/compare/v0.2.0...v0.3.0 diff --git a/README.md b/README.md index 73ef89d..44f39ee 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ $dispatcher = new Dispatcher([ $response = $dispatcher->dispatch(new ServerRequest('/hello/world')); ``` -When the request handler is invoked, it expects a request attribute to be defined that contains a reference to the handler. The handler must be a string or an object implementing `MiddlewareInterface` or `RequestHandlerInterface`. If it's a string, a `ContainerInterface` will be used to resolve it and get the `MiddlewareInterface` or `RequestHandlerInterface` to use. +When the request handler is invoked, it expects a request attribute to be defined that contains a reference to the handler. The handler must be a string, a `Closure` or an object implementing `MiddlewareInterface` or `RequestHandlerInterface`. If it's a string, a `ContainerInterface` will be used to resolve it and get the `MiddlewareInterface` or `RequestHandlerInterface` to use. If it's a `Closure`, will be converted automatically to `MiddlewareInterface` using the [middlewares/utils CallableHandler](https://github.com/middlewares/utils#callablehandler) ```php // Use a PSR-11 container to create the intances of the request handlers diff --git a/src/RequestHandler.php b/src/RequestHandler.php index 454c725..0835983 100644 --- a/src/RequestHandler.php +++ b/src/RequestHandler.php @@ -3,6 +3,8 @@ namespace Middlewares; +use Closure; +use Middlewares\Utils\CallableHandler; use Middlewares\Utils\RequestHandlerContainer; use Psr\Container\ContainerInterface; use Psr\Http\Message\ResponseInterface; @@ -61,6 +63,10 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface return $requestHandler->handle($request); } + if ($requestHandler instanceof Closure) { + return (new CallableHandler($requestHandler))->process($request, $handler); + } + throw new RuntimeException(sprintf('Invalid request handler: %s', gettype($requestHandler))); } } diff --git a/tests/RequestHandlerTest.php b/tests/RequestHandlerTest.php index f788893..0017f7f 100644 --- a/tests/RequestHandlerTest.php +++ b/tests/RequestHandlerTest.php @@ -93,4 +93,20 @@ public function testRequestHandler() $this->assertSame(200, $response->getStatusCode()); $this->assertSame('Bar', $response->getHeaderLine('X-Foo')); } + + public function testClosure() + { + $response = Dispatcher::run( + [ + new RequestHandler(), + ], + $request = Factory::createServerRequest() + ->withAttribute('request-handler', function () { + return Factory::createResponse()->withHeader('X-Foo', 'Bar'); + }) + ); + + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('Bar', $response->getHeaderLine('X-Foo')); + } }