|
1 | 1 | <?php
|
2 | 2 | /**
|
3 |
| - * @link http://github.com/zendframework/zend-mvc for the canonical source repository |
4 |
| - * @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (http://www.zend.com) |
| 3 | + * @see https://github.com/zendframework/zend-mvc for the canonical source repository |
| 4 | + * @copyright Copyright (c) 2018 Zend Technologies USA Inc. (http://www.zend.com) |
5 | 5 | * @license https://github.com/zendframework/zend-mvc/blob/master/LICENSE.md New BSD License
|
6 | 6 | */
|
7 | 7 |
|
8 | 8 | namespace Zend\Mvc;
|
9 | 9 |
|
| 10 | +use Closure; |
10 | 11 | use Interop\Container\ContainerInterface;
|
| 12 | +use Interop\Http\ServerMiddleware\DelegateInterface; |
11 | 13 | use Interop\Http\ServerMiddleware\MiddlewareInterface;
|
12 |
| -use Psr\Http\Message\ResponseInterface as PsrResponseInterface; |
13 | 14 | use Psr\Http\Message\ResponseInterface;
|
14 |
| -use Psr\Http\Message\ServerRequestInterface as PsrServerRequestInterface; |
| 15 | +use Psr\Http\Message\ResponseInterface as PsrResponseInterface; |
| 16 | +use ReflectionFunction; |
| 17 | +use ReflectionMethod; |
15 | 18 | use Zend\EventManager\AbstractListenerAggregate;
|
16 | 19 | use Zend\EventManager\EventManagerInterface;
|
17 |
| -use Zend\Mvc\Exception\InvalidMiddlewareException; |
18 |
| -use Zend\Mvc\Exception\ReachedFinalHandlerException; |
19 | 20 | use Zend\Mvc\Controller\MiddlewareController;
|
| 21 | +use Zend\Mvc\Exception\InvalidMiddlewareException; |
20 | 22 | use Zend\Psr7Bridge\Psr7Response;
|
21 |
| -use Zend\Router\RouteMatch; |
22 |
| -use Zend\Stratigility\Delegate\CallableDelegateDecorator; |
| 23 | +use Zend\Stratigility\Middleware\DoublePassMiddlewareDecorator; |
23 | 24 | use Zend\Stratigility\MiddlewarePipe;
|
24 | 25 |
|
25 | 26 | class MiddlewareListener extends AbstractListenerAggregate
|
@@ -146,6 +147,19 @@ private function createPipeFromSpec(
|
146 | 147 | throw InvalidMiddlewareException::fromMiddlewareName($middlewareName);
|
147 | 148 | }
|
148 | 149 |
|
| 150 | + // Decorate double-pass middleware |
| 151 | + if (is_callable($middlewareToBePiped)) { |
| 152 | + $r = $this->getReflectionFunction($middlewareToBePiped); |
| 153 | + $paramsCount = $r->getNumberOfParameters(); |
| 154 | + |
| 155 | + $params = $r->getParameters(); |
| 156 | + $type = isset($params[1]) ? $params[1]->getClass() : null; |
| 157 | + |
| 158 | + if ($paramsCount !== 2 || ! $type || ! is_a($type->getName(), DelegateInterface::class, true)) { |
| 159 | + $middlewareToBePiped = new DoublePassMiddlewareDecorator($middlewareToBePiped); |
| 160 | + } |
| 161 | + } |
| 162 | + |
149 | 163 | $pipe->pipe($middlewareToBePiped);
|
150 | 164 | }
|
151 | 165 | return $pipe;
|
@@ -184,4 +198,23 @@ protected function marshalInvalidMiddleware(
|
184 | 198 | }
|
185 | 199 | return $return;
|
186 | 200 | }
|
| 201 | + |
| 202 | + /** |
| 203 | + * @param callable $middleware |
| 204 | + * @return \ReflectionFunctionAbstract |
| 205 | + */ |
| 206 | + private function getReflectionFunction(callable $middleware) |
| 207 | + { |
| 208 | + if (is_array($middleware)) { |
| 209 | + $class = array_shift($middleware); |
| 210 | + $method = array_shift($middleware); |
| 211 | + return new ReflectionMethod($class, $method); |
| 212 | + } |
| 213 | + |
| 214 | + if ($middleware instanceof Closure || ! is_object($middleware)) { |
| 215 | + return new ReflectionFunction($middleware); |
| 216 | + } |
| 217 | + |
| 218 | + return new ReflectionMethod($middleware, '__invoke'); |
| 219 | + } |
187 | 220 | }
|
0 commit comments