From 026824d574a8e941b5e5f1779147b6b8bb6022ac Mon Sep 17 00:00:00 2001 From: oxcom Date: Wed, 4 Dec 2019 16:31:36 +0100 Subject: [PATCH] issue #13 - fix render flow --- src/Renderer/TwigRenderer.php | 34 +++++------ src/View/TwigStrategy.php | 11 ++++ tests/ZendTwig/Renderer/TwigRendererTest.php | 50 ++++++++-------- tests/ZendTwig/View/TwigStrategyTest.php | 62 +++++++++++++++++++- 4 files changed, 113 insertions(+), 44 deletions(-) diff --git a/src/Renderer/TwigRenderer.php b/src/Renderer/TwigRenderer.php index 84d0028..edd6c81 100755 --- a/src/Renderer/TwigRenderer.php +++ b/src/Renderer/TwigRenderer.php @@ -19,14 +19,10 @@ use Zend\View\Renderer\TreeRendererInterface; use Zend\View\Resolver\ResolverInterface; use Zend\View\View; +use ZendTwig\View\TwigModel; class TwigRenderer implements RendererInterface, TreeRendererInterface { - /** - * @var bool - */ - protected $canRenderTrees = true; - /** * @var Environment */ @@ -189,7 +185,7 @@ public function render($nameOrModel, $values = null) : string )); } - if ($model instanceof ModelInterface && $model->hasChildren() && $this->canRenderTrees()) { + if ($model instanceof ModelInterface && $model->hasChildren() && $this->canRenderTrees($model)) { if (!isset($values[$model->captureTo()])) { $values[$model->captureTo()] = ''; } @@ -199,7 +195,11 @@ public function render($nameOrModel, $values = null) : string * @var \Zend\View\Model\ViewModel $child * @var \Twig_Template $template */ - $result = $this->render($child, $values); + try { + $result = $this->render($child, $values); + } catch (RuntimeException $e) { + continue; + } if ($this->isForceStandalone() || $child->terminate()) { return $result; @@ -237,23 +237,17 @@ public function canRender($name) /** * Indicate whether the renderer is capable of rendering trees of view models * - * @return bool - */ - public function canRenderTrees() - { - return $this->canRenderTrees; - } - - /** - * @param boolean $canRenderTrees + * @param mixed $model * - * @return TwigRenderer + * @return bool */ - public function setCanRenderTrees($canRenderTrees) + public function canRenderTrees($model = null) { - $this->canRenderTrees = !!$canRenderTrees; + if (!empty($model) && $model instanceof TwigModel) { + return true; + } - return $this; + return false; } /** diff --git a/src/View/TwigStrategy.php b/src/View/TwigStrategy.php index 050d457..2096921 100755 --- a/src/View/TwigStrategy.php +++ b/src/View/TwigStrategy.php @@ -7,6 +7,7 @@ use Zend\EventManager\ListenerAggregateTrait; use Zend\View\Renderer\RendererInterface; use Zend\View\ViewEvent; +use ZendTwig\Renderer\TwigRenderer; class TwigStrategy implements ListenerAggregateInterface { @@ -65,6 +66,16 @@ public function selectRender(ViewEvent $e) return $this->renderer; } + if ($this->renderer instanceof TwigRenderer) { + try { + $tpl = $this->renderer->getResolver()->resolve($model->getTemplate()); + if ($tpl instanceof \Twig\Template) { + return $this->renderer; + } + } catch (\Throwable $e) { + } + } + return null; } diff --git a/tests/ZendTwig/Renderer/TwigRendererTest.php b/tests/ZendTwig/Renderer/TwigRendererTest.php index 6f8d26e..5e5d68a 100755 --- a/tests/ZendTwig/Renderer/TwigRendererTest.php +++ b/tests/ZendTwig/Renderer/TwigRendererTest.php @@ -4,8 +4,12 @@ use PHPUnit\Framework\TestCase; use Twig\Environment; +use Zend\Mvc\MvcEvent; +use Zend\Mvc\View\Http\DefaultRenderingStrategy; +use Zend\View\Model\ViewModel; use ZendTwig\Test\Bootstrap; use ZendTwig\Renderer\TwigRenderer; +use ZendTwig\View\TwigModel; class TwigRendererTest extends TestCase { @@ -111,13 +115,13 @@ public function testSetGetCanRenderTrees() */ $sm = Bootstrap::getInstance()->getServiceManager(); $render = $sm->get(TwigRenderer::class); - $canRenderOld = $render->canRenderTrees(); - $render->setCanRenderTrees(!$canRenderOld); - $this->assertNotEquals($canRenderOld, $render->canRenderTrees()); + $model = new ViewModel(); + $twigModel = new TwigModel(); - $render->setCanRenderTrees($canRenderOld); - $this->assertEquals($canRenderOld, $render->canRenderTrees()); + $this->assertFalse($render->canRenderTrees()); + $this->assertFalse($render->canRenderTrees('Element?')); + $this->assertTrue($render->canRenderTrees($twigModel)); } /** @@ -132,7 +136,7 @@ public function testRenderModelExNotTemplate() $sm = Bootstrap::getInstance()->getServiceManager(); $render = $sm->get(TwigRenderer::class); - $model = new \Zend\View\Model\ViewModel([ + $model = new ViewModel([ 'key1' => 'value1', 'key2' => 'value2', ]); @@ -150,7 +154,7 @@ public function testRenderModelOptions() $view = $sm->get('View'); $viewClone = clone $view; - $model = new \Zend\View\Model\ViewModel([ + $model = new ViewModel([ 'key1' => 'value1', 'key2' => 'value2', ]); @@ -212,22 +216,22 @@ public function testRenderChild() $sm = Bootstrap::getInstance()->getServiceManager(); $render = $sm->get(TwigRenderer::class); - $modelParent = new \Zend\View\Model\ViewModel([ + $modelParent = new TwigModel([ 'key1' => 'value1', ]); $modelParent->setTemplate('View/testRenderChild'); - $modelChild1 = new \Zend\View\Model\ViewModel([ + $modelChild1 = new TwigModel([ 'key1' => 'child1-1', 'key2' => 'child1-2', ]); - $modelChild2 = new \Zend\View\Model\ViewModel([ + $modelChild2 = new TwigModel([ 'key1' => 'child2-1', 'key2' => 'child2-2', ]); - $modelChild3 = new \Zend\View\Model\ViewModel([ + $modelChild3 = new TwigModel([ 'key1' => 'child3-1', 'key2' => 'child3-2', ]); @@ -262,22 +266,22 @@ public function testRenderChildNoAppend() $sm = Bootstrap::getInstance()->getServiceManager(); $render = $sm->get(TwigRenderer::class); - $modelParent = new \Zend\View\Model\ViewModel([ + $modelParent = new TwigModel([ 'key1' => 'value1', ]); $modelParent->setTemplate('View/testRenderChild'); - $modelChild1 = new \Zend\View\Model\ViewModel([ + $modelChild1 = new TwigModel([ 'key1' => 'child1-1', 'key2' => 'child1-2', ]); - $modelChild2 = new \Zend\View\Model\ViewModel([ + $modelChild2 = new TwigModel([ 'key1' => 'child2-1', 'key2' => 'child2-2', ]); - $modelChild3 = new \Zend\View\Model\ViewModel([ + $modelChild3 = new TwigModel([ 'key1' => 'child3-1', 'key2' => 'child3-2', ]); @@ -324,11 +328,11 @@ public function testForceStandaloneModel() $sm = Bootstrap::getInstance()->getServiceManager(); $render = $sm->get(TwigRenderer::class); - $modelParent = new \Zend\View\Model\ViewModel([ + $modelParent = new TwigModel([ ]); $modelParent->setTemplate('View/zend/layout'); - $modelChild1 = new \Zend\View\Model\ViewModel([ + $modelChild1 = new TwigModel([ 'username' => 'Child007', ]); @@ -350,11 +354,11 @@ public function testSimpleStandaloneModel() $sm = Bootstrap::getInstance()->getServiceManager(); $render = $sm->get(TwigRenderer::class); - $modelParent = new \Zend\View\Model\ViewModel([ + $modelParent = new TwigModel([ ]); $modelParent->setTemplate('View/zend/layout'); - $modelChild1 = new \Zend\View\Model\ViewModel([ + $modelChild1 = new TwigModel([ 'username' => 'Child007', ]); @@ -381,8 +385,8 @@ public function testIssue2() $sm = Bootstrap::getInstance()->getServiceManager(); $render = $sm->get(TwigRenderer::class); - $modelParent = new \Zend\View\Model\ViewModel(); - $modelChild1 = new \Zend\View\Model\ViewModel(); + $modelParent = new TwigModel(); + $modelChild1 = new TwigModel(); $modelParent->setTemplate('View/issue-2/layout'); $modelChild1->setTemplate('View/issue-2/index'); @@ -408,8 +412,8 @@ public function testIssue2Raw() $sm = Bootstrap::getInstance()->getServiceManager(); $render = $sm->get(TwigRenderer::class); - $modelParent = new \Zend\View\Model\ViewModel(); - $modelChild1 = new \Zend\View\Model\ViewModel(); + $modelParent = new TwigModel(); + $modelChild1 = new TwigModel(); $modelParent->setTemplate('View/issue-2/layout-raw'); $modelChild1->setTemplate('View/issue-2/index'); diff --git a/tests/ZendTwig/View/TwigStrategyTest.php b/tests/ZendTwig/View/TwigStrategyTest.php index de2f612..47aba33 100755 --- a/tests/ZendTwig/View/TwigStrategyTest.php +++ b/tests/ZendTwig/View/TwigStrategyTest.php @@ -3,10 +3,13 @@ namespace ZendTwig\Test\View; use PHPUnit\Framework\TestCase; +use Zend\View\Model\JsonModel; +use Zend\View\Model\ViewModel; use Zend\View\Renderer\PhpRenderer; use Zend\View\ViewEvent; use ZendTwig\Renderer\TwigRenderer; use ZendTwig\Test\Bootstrap; +use ZendTwig\View\TwigModel; use ZendTwig\View\TwigStrategy; class TwigStrategyTest extends TestCase @@ -14,7 +17,7 @@ class TwigStrategyTest extends TestCase /** * Check that correct render was selected */ - public function testSelectRenderer() + public function testSelectRenderForce() { $model = $this->getMockBuilder('Zend\View\Model\ModelInterface')->getMock(); $model->method('getTemplate') @@ -31,12 +34,69 @@ public function testSelectRenderer() */ $sm = Bootstrap::getInstance()->getServiceManager(); $strategy = $sm->get(TwigStrategy::class); + $strategy->setForceRender(true); + $renderA = $sm->get(TwigRenderer::class); $renderB = $strategy->selectRender($event); $this->assertSame($renderA, $renderB); } + /** + * Check that correct render was selected + * + * @var \Zend\View\Model\ModelInterface $model + * + * @dataProvider generatorSelectRender + */ + public function testSelectRenderNoRender($model, $expected) + { + $event = new ViewEvent(); + $event->setModel($model); + + /** + * @var \ZendTwig\View\TwigStrategy $strategy + */ + $sm = Bootstrap::getInstance()->getServiceManager(); + $strategy = $sm->get(TwigStrategy::class); + $strategy->setForceRender(false); + $render = $strategy->selectRender($event); + + if (!empty($expected)) { + $expected = $sm->get($expected); + } + + $this->assertSame($expected, $render); + } + + /** + * @return array + */ + public function generatorSelectRender() + { + $viewModel = $this->getMockBuilder(ViewModel::class)->getMock(); + $viewModel->method('getTemplate') + ->will($this->returnValue('some-template-string')); + + $jsonModel = $this->getMockBuilder(JsonModel::class)->getMock(); + $jsonModel->method('getTemplate') + ->will($this->returnValue('some-template-string')); + + $twigModel = $this->getMockBuilder(TwigModel::class)->getMock(); + $twigModel->method('getTemplate') + ->will($this->returnValue('some-template-string')); + + $viewModelTwig = new ViewModel(); + $viewModelTwig->setTemplate('layout'); + + return [ + [$viewModel, null], + [$jsonModel, null], + [$twigModel, TwigRenderer::class], + [$viewModelTwig, TwigRenderer::class], + ]; + } + /** * Check that response was injected *