Przeglądaj źródła

[TwigBundle] Allow Renderer::evaluate() even when Request and Session are not available

This is helpful for using Twig outside of a request-serving context, such during a console command.  Added unit tests the original behavior and new behavior for this patch.
Jeremy Mikola 14 lat temu
rodzic
commit
9553971d06

+ 6 - 4
src/Symfony/Bundle/TwigBundle/Renderer/Renderer.php

@@ -37,10 +37,12 @@ class Renderer extends BaseRenderer
      */
     public function evaluate(Storage $template, array $parameters = array())
     {
-        // cannot be set in the constructor as we need the current request
-        $request = $this->engine->getContainer()->get('request');
-        $this->environment->addGlobal('request', $request);
-        $this->environment->addGlobal('session', $request->getSession());
+        if ($this->engine->getContainer()->has('request')) {
+            // cannot be set in the constructor as we need the current request
+            $request = $this->engine->getContainer()->get('request');
+            $this->environment->addGlobal('request', $request);
+            $this->environment->addGlobal('session', $request->getSession());
+        }
 
         return $this->environment->loadTemplate($template)->render($parameters);
     }

+ 103 - 0
src/Symfony/Bundle/TwigBundle/Tests/Renderer/RendererTest.php

@@ -0,0 +1,103 @@
+<?php
+
+namespace Symfony\Bundle\TwigBundle\Tests;
+
+use Symfony\Bundle\FrameworkBundle\Templating\Engine;
+use Symfony\Bundle\TwigBundle\Renderer\Renderer;
+use Symfony\Bundle\TwigBundle\Tests\TestCase;
+use Symfony\Component\DependencyInjection\Container;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Session;
+use Symfony\Component\HttpFoundation\SessionStorage\ArraySessionStorage;
+
+class RendererTest extends TestCase
+{
+    public function testEvalutateAddsRequestAndSessionGlobals()
+    {
+        $environment = $this->getTwigEnvironment();
+        $renderer = new Renderer($environment);
+
+        $container = $this->getContainer();
+        $engine = new Engine($container, $this->getMock('Symfony\Component\Templating\Loader\LoaderInterface'), array());
+
+        $storage = $this->getStorage();
+        $template = $this->getMock('\Twig_TemplateInterface');
+
+        $environment->expects($this->once())
+            ->method('loadTemplate')
+            ->with($storage)
+            ->will($this->returnValue($template));
+
+        $renderer->setEngine($engine);
+        $renderer->evaluate($storage);
+
+        $request = $container->get('request');
+        $globals = $environment->getGlobals();
+        $this->assertSame($request, $globals['request']);
+        $this->assertSame($request->getSession(), $globals['session']);
+    }
+
+    public function testEvalutateWithoutAvailableRequest()
+    {
+        $environment = $this->getTwigEnvironment();
+        $renderer = new Renderer($environment);
+
+        $engine = new Engine(new Container(), $this->getMock('Symfony\Component\Templating\Loader\LoaderInterface'), array());
+
+        $storage = $this->getStorage();
+        $template = $this->getMock('\Twig_TemplateInterface');
+
+        $environment->expects($this->once())
+            ->method('loadTemplate')
+            ->with($storage)
+            ->will($this->returnValue($template));
+
+        $renderer->setEngine($engine);
+        $renderer->evaluate($storage);
+
+        $this->assertEmpty($environment->getGlobals());
+    }
+
+    /**
+     * Creates a Container with a Session-containing Request service.
+     *
+     * @return Container
+     */
+    protected function getContainer()
+    {
+        $container = new Container();
+        $request = new Request();
+        $session = new Session(new ArraySessionStorage());
+
+        $request->setSession($session);
+        $container->set('request', $request);
+
+        return $container;
+    }
+
+    /**
+     * Creates a mock Storage object.
+     *
+     * @return Storage
+     */
+    protected function getStorage()
+    {
+        return $this
+            ->getMockBuilder('Symfony\Component\Templating\Storage\Storage')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    /**
+     * Creates a mock Twig_Environment object.
+     *
+     * @return \Twig_Environment
+     */
+    protected function getTwigEnvironment()
+    {
+        return $this
+            ->getMockBuilder('\Twig_Environment')
+            ->setMethods(array('loadTemplate'))
+            ->getMock();
+    }
+}