diff --git a/src/MiddlewareListener.php b/src/MiddlewareListener.php index 5ea4efe15..f93e360e6 100644 --- a/src/MiddlewareListener.php +++ b/src/MiddlewareListener.php @@ -14,6 +14,7 @@ use Zend\EventManager\EventManagerInterface; use Zend\Psr7Bridge\Psr7ServerRequest as Psr7Request; use Zend\Psr7Bridge\Psr7Response; +use Zend\Router\RouteMatch; class MiddlewareListener extends AbstractListenerAggregate { @@ -59,7 +60,11 @@ public function onDispatch(MvcEvent $event) $caughtException = null; try { - $return = $middleware(Psr7Request::fromZend($request), Psr7Response::fromZend($response)); + $psr7Request = Psr7Request::fromZend($request)->withAttribute(RouteMatch::class, $routeMatch); + foreach ($routeMatch->getParams() as $key => $value) { + $psr7Request = $psr7Request->withAttribute($key, $value); + } + $return = $middleware($psr7Request, Psr7Response::fromZend($response)); } catch (\Throwable $ex) { $caughtException = $ex; } catch (\Exception $ex) { // @TODO clean up once PHP 7 requirement is enforced diff --git a/test/MiddlewareListenerTest.php b/test/MiddlewareListenerTest.php index 8e32e1c3b..20bbe5330 100644 --- a/test/MiddlewareListenerTest.php +++ b/test/MiddlewareListenerTest.php @@ -24,6 +24,11 @@ class MiddlewareListenerTest extends TestCase { + /** + * @var \Prophecy\Prophecy\ObjectProphecy + */ + private $routeMatch; + /** * Create an MvcEvent, populated with everything it needs. * @@ -34,8 +39,9 @@ class MiddlewareListenerTest extends TestCase public function createMvcEvent($middlewareMatched, $middleware = null) { $response = new Response(); - $routeMatch = $this->prophesize(RouteMatch::class); - $routeMatch->getParam('middleware', false)->willReturn($middlewareMatched); + $this->routeMatch = $this->prophesize(RouteMatch::class); + $this->routeMatch->getParam('middleware', false)->willReturn($middlewareMatched); + $this->routeMatch->getParams()->willReturn([]); $eventManager = new EventManager(); @@ -54,7 +60,7 @@ public function createMvcEvent($middlewareMatched, $middleware = null) $event->setRequest(new Request()); $event->setResponse($response); $event->setApplication($application->reveal()); - $event->setRouteMatch($routeMatch->reveal()); + $event->setRouteMatch($this->routeMatch->reveal()); return $event; } @@ -82,6 +88,31 @@ public function testSuccessfullyDispatchesMiddleware() $this->assertEquals('Test!', $return->getBody()); } + public function testMatchedRouteParamsAreInjectedToRequestAsAttributes() + { + $matchedRouteParam = uniqid('matched param', true); + $routeAttribute = null; + + $event = $this->createMvcEvent( + 'foo', + function (ServerRequestInterface $request, ResponseInterface $response) use (&$routeAttribute) { + $routeAttribute = $request->getAttribute(RouteMatch::class); + $response->getBody()->write($request->getAttribute('myParam', 'param did not exist')); + return $response; + } + ); + + $this->routeMatch->getParams()->willReturn([ + 'myParam' => $matchedRouteParam, + ]); + + $listener = new MiddlewareListener(); + $return = $listener->onDispatch($event); + $this->assertInstanceOf(Response::class, $return); + $this->assertSame($matchedRouteParam, $return->getBody()); + $this->assertSame($this->routeMatch->reveal(), $routeAttribute); + } + public function testTriggersErrorForUncallableMiddleware() { $event = $this->createMvcEvent('path'); @@ -125,6 +156,7 @@ public function testCanLoadFromAbstractFactory() $response = new Response(); $routeMatch = $this->prophesize(RouteMatch::class); $routeMatch->getParam('middleware', false)->willReturn('test'); + $routeMatch->getParams()->willReturn([]); $eventManager = new EventManager();