diff --git a/CHANGELOG.md b/CHANGELOG.md index c538c3e..194adf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ details. ### Added +- [#146](https://github.com/zendframework/zend-stratigility/pull/146) adds a new + interface, `Zend\Stratigility\MiddlewarePipeInterface`. It extends the PSR-15 + `MiddlewareInterface` and `RequestHandlerInterface`, and defines one + additional method, `pipe(MiddlewareInterface $middleware) : void`. + - [#142](https://github.com/zendframework/zend-stratigility/pull/142) adds a new class, `Zend\Stratigility\Middleware\HostMiddlewareDecorator`, which provides host segregation functionality for middleware, allowing conditional execution @@ -75,13 +80,17 @@ details. supported (though Stratigility provides decorators for the latter in order to cast them to PSR-15 implementations). -- [#134](https://github.com/zendframework/zend-stratigility/pull/134) marks the - `MiddlewarePipe` class as `final`, disallowing direct extension. Either - compose an instance, or create a custom PSR-15 `MiddlewareInterface` - implementation. - - [#134](https://github.com/zendframework/zend-stratigility/pull/134) and - [#145](https://github.com/zendframework/zend-stratigility/pull/145) update + [#146](https://github.com/zendframework/zend-stratigility/pull/146) modify + `MiddlewarePipe` in two ways: it now implements the new + `MiddlewarePipeInterface`, and is marked as `final`, disallowing direct + extension. Either decorate an instance in a custom `MiddlewarePipeInterface` + implementation, or create a custom PSR-15 `MiddlewareInterface` + implementation if piping is not necessary or will allow additional types. + +- [#134](https://github.com/zendframework/zend-stratigility/pull/134), + [#145](https://github.com/zendframework/zend-stratigility/pull/145), and + [#146](https://github.com/zendframework/zend-stratigility/pull/146) update `MiddlewarePipe` to implement `Psr\Http\Server\RequestHandlerInterface`. Calling it will cause it to pull the first middleware off the queue and create a `Next` implementation that uses the remaining queue as the request handler; diff --git a/docs/book/v3/migration.md b/docs/book/v3/migration.md index d2f129b..d513529 100644 --- a/docs/book/v3/migration.md +++ b/docs/book/v3/migration.md @@ -75,6 +75,9 @@ internal logic. - `Next::handle()`: the method now provides a return typehint of `Psr\Http\Message\ResponseInterface`. +- `MiddlewarePipe` class is marked now as `final` and implements the new + interface `MiddlewarePipeInterface.` + - `MiddlewarePipe::pipe()`: reduces the number of arguments to one, which now typehints against `Psr\Http\Server\MiddlewareInterface`. This means the method can no longer be used to segregate middleware by path. If you want to do that, @@ -88,6 +91,11 @@ internal logic. ### Class additions +- `Zend\Stratigility\MiddlewarePipeInterface` extends + `Psr\Http\Server\MiddlewareInterface` and `Psr\Http\Server\RequestHandlerInterface`, + and defines the method `pipe(Psr\Http\Server\MiddlewareInterface $middleware) : void`. + It is implemented by `MiddlewarePipe`. + - `Zend\Stratigility\Middleware\HostMiddlewareDecorator` allows you to segregate middleware by a static host name. This allows executing middleware only if a particular host matches. diff --git a/src/MiddlewarePipe.php b/src/MiddlewarePipe.php index 2bf519b..e8f276b 100644 --- a/src/MiddlewarePipe.php +++ b/src/MiddlewarePipe.php @@ -28,7 +28,7 @@ * * @see https://github.com/sencha/connect */ -final class MiddlewarePipe implements MiddlewareInterface, RequestHandlerInterface +final class MiddlewarePipe implements MiddlewarePipeInterface { /** * @var SplQueue diff --git a/src/MiddlewarePipeInterface.php b/src/MiddlewarePipeInterface.php new file mode 100644 index 0000000..202e7ba --- /dev/null +++ b/src/MiddlewarePipeInterface.php @@ -0,0 +1,17 @@ +assertSame($response, $pipeline->handle($this->request)); } + + public function testMiddlewarePipeOnlyImplementsMiddlewarePipeInterfaceApi() + { + $pipeline = new MiddlewarePipe(); + + $r = new ReflectionObject($pipeline); + $methods = $r->getMethods(ReflectionMethod::IS_PUBLIC); + $actual = []; + foreach ($methods as $method) { + if (strpos($method->getName(), '__') !== 0) { + $actual[] = $method->getName(); + } + } + sort($actual); + + $interfaceReflection = new ReflectionClass(MiddlewarePipeInterface::class); + $interfaceMethods = $interfaceReflection->getMethods(ReflectionMethod::IS_PUBLIC); + $expected = []; + foreach ($interfaceMethods as $method) { + $expected[] = $method->getName(); + } + sort($expected); + + self::assertTrue($r->isFinal()); + self::assertEquals($expected, $actual); + self::assertInstanceOf(MiddlewarePipeInterface::class, $pipeline); + } }