diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ba470eb0..5c52cdd8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,37 @@ All notable changes to this project will be documented in this file, in reverse ### Added -- Nothing. +- [#163](https://github.com/zendframework/zend-mvc/pull/163) adds support to the + `AcceptableViewModelSelector` plugin for controller maps in the `view_manager` + configuration in the format: + + ```php + [ + 'ControllerClassName' => 'view/name', + ] + ``` + + This fixes an issue observed when running with Apigility. + +- [#163](https://github.com/zendframework/zend-mvc/pull/163) adds support to the + `InjectTemplateListener` for specifying whether or not to prefer the + controller matched during routing via routing configuration: + + ```php + 'route-name' => [ + /* ... */ + 'options' => [ + /* ... */ + 'defaults' => [ + /* ... */ + 'prefer_route_match_controller' => true, + ], + ], + ], + ``` + + This allows actions that might otherwise skip injection of the template + to force the injection. ### Deprecated diff --git a/src/Controller/Plugin/AcceptableViewModelSelector.php b/src/Controller/Plugin/AcceptableViewModelSelector.php index 2049d8f07..2fb4f2dc0 100644 --- a/src/Controller/Plugin/AcceptableViewModelSelector.php +++ b/src/Controller/Plugin/AcceptableViewModelSelector.php @@ -209,6 +209,9 @@ public function getDefaultMatchAgainst() protected function injectViewModelName($modelAcceptString, $modelName) { $modelName = str_replace('\\', '|', $modelName); + $modelAcceptString = (is_array($modelAcceptString)) + ? $modelAcceptString[key($modelAcceptString)] + : $modelAcceptString; return $modelAcceptString . '; ' . self::INJECT_VIEWMODEL_NAME . '="' . $modelName . '", '; } diff --git a/src/View/Http/InjectTemplateListener.php b/src/View/Http/InjectTemplateListener.php index 4f7c79566..b8fb16309 100644 --- a/src/View/Http/InjectTemplateListener.php +++ b/src/View/Http/InjectTemplateListener.php @@ -61,6 +61,10 @@ public function injectTemplate(MvcEvent $e) } $routeMatch = $e->getRouteMatch(); + if ($preferRouteMatchController = $routeMatch->getParam('prefer_route_match_controller', false)) { + $this->setPreferRouteMatchController($preferRouteMatchController); + } + $controller = $e->getTarget(); if (is_object($controller)) { $controller = get_class($controller); diff --git a/test/View/InjectTemplateListenerTest.php b/test/View/InjectTemplateListenerTest.php index 34466567d..fb5e11ae6 100644 --- a/test/View/InjectTemplateListenerTest.php +++ b/test/View/InjectTemplateListenerTest.php @@ -17,6 +17,7 @@ use Zend\Router\RouteMatch; use Zend\Mvc\View\Http\InjectTemplateListener; use Zend\View\Model\ViewModel; +use ZendTest\Mvc\Controller\TestAsset\SampleController; class InjectTemplateListenerTest extends TestCase { @@ -108,7 +109,7 @@ public function testBypassesTemplateInjectionIfResultViewModelAlreadyHasATemplat public function testMapsSubNamespaceToSubDirectory() { $myViewModel = new ViewModel(); - $myController = new \ZendTest\Mvc\Controller\TestAsset\SampleController(); + $myController = new SampleController(); $this->event->setTarget($myController); $this->event->setResult($myViewModel); @@ -158,7 +159,7 @@ public function testMapsSubNamespaceToSubDirectoryWithControllerFromEventTarget( $moduleRouteListener->onRoute($this->event); $myViewModel = new ViewModel(); - $myController = new \ZendTest\Mvc\Controller\TestAsset\SampleController(); + $myController = new SampleController(); $this->event->setTarget($myController); $this->event->setResult($myViewModel); @@ -183,7 +184,7 @@ public function testMapsSubNamespaceToSubDirectoryWithControllerFromEventTargetS $template1 = $myViewModel->getTemplate(); $myViewModel = new ViewModel(); - $myController = new \ZendTest\Mvc\Controller\TestAsset\SampleController(); + $myController = new SampleController(); $this->event->setTarget($myController); $this->event->setResult($myViewModel); @@ -204,7 +205,7 @@ public function testControllerMatchedByMapIsInflected() $this->listener->setControllerMap(['ZendTest' => true]); $myViewModel = new ViewModel(); - $myController = new \ZendTest\Mvc\Controller\TestAsset\SampleController(); + $myController = new SampleController(); $this->event->setTarget($myController); $this->event->setResult($myViewModel); @@ -332,7 +333,7 @@ public function testPrefersRouteMatchController() $this->listener->setPreferRouteMatchController(true); $this->routeMatch->setParam('controller', 'Some\Other\Service\Namespace\Controller\Sample'); $myViewModel = new ViewModel(); - $myController = new \ZendTest\Mvc\Controller\TestAsset\SampleController(); + $myController = new SampleController(); $this->event->setTarget($myController); $this->event->setResult($myViewModel); @@ -340,4 +341,28 @@ public function testPrefersRouteMatchController() $this->assertEquals('some/other/service/namespace/sample', $myViewModel->getTemplate()); } + + public function testPrefersRouteMatchControllerWithRouteMatchAndControllerMap() + { + $this->assertFalse($this->listener->isPreferRouteMatchController()); + $controllerMap = [ + 'Some\Other\Service\Namespace\Controller\Sample' => 'another/sample' + ]; + + $this->routeMatch->setParam('prefer_route_match_controller', true); + $this->routeMatch->setParam('controller', 'Some\Other\Service\Namespace\Controller\Sample'); + + $preferRouteMatchControllerRouteMatchConfig = $this->routeMatch->getParam('prefer_route_match_controller', false); + $this->listener->setPreferRouteMatchController($preferRouteMatchControllerRouteMatchConfig); + $this->listener->setControllerMap($controllerMap); + + $myViewModel = new ViewModel(); + $myController = new SampleController(); + + $this->event->setTarget($myController); + $this->event->setResult($myViewModel); + $this->listener->injectTemplate($this->event); + + $this->assertEquals('another/sample', $myViewModel->getTemplate()); + } }