Browse Source

Merge remote branch 'vicb/locate_template2'

* vicb/locate_template2:
  [FrameworkBundle] Enforce templates instances of TemplateReferenceInterface
  [FrameworkBundle] Add unit tests for the CacheTemplateLocator class
  [FrameworkBundle] Add unit tests for the TemplateLocator class
  [TwigBundle] Fix the cache warmer
  [TwigBundle] Tweak cache warmer configuration
  [FrameworkBundle] Fix resource inheritance in the template cache warmer
Fabien Potencier 14 years ago
parent
commit
0c93b6bbe4

+ 9 - 6
src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.php

@@ -15,6 +15,7 @@ use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;
 use Symfony\Component\HttpKernel\KernelInterface;
 use Symfony\Component\Finder\Finder;
 use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser;
+use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
 
 /**
  * Computes the association between template names and their paths on the disk.
@@ -24,20 +25,23 @@ use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser;
 class TemplatePathsCacheWarmer extends CacheWarmer
 {
     protected $kernel;
-    protected $rootDir;
     protected $parser;
+    protected $rootDir;
+    protected $locator;
 
     /**
      * Constructor.
      *
      * @param KernelInterface      $kernel  A KernelInterface instance
      * @param TemplateNameParser   $parser  A TemplateNameParser instance
+     * @param TemplateLocator      $locator The template locator
      * @param string               $rootDir The directory where global templates can be stored
      */
-    public function __construct(KernelInterface $kernel, TemplateNameParser $parser, $rootDir)
+    public function __construct(KernelInterface $kernel, TemplateNameParser $parser, TemplateLocator $locator, $rootDir)
     {
         $this->kernel = $kernel;
         $this->parser = $parser;
+        $this->locator = $locator;
         $this->rootDir = $rootDir;
     }
 
@@ -51,7 +55,6 @@ class TemplatePathsCacheWarmer extends CacheWarmer
         $templates = array();
 
         foreach ($this->kernel->getBundles() as $name => $bundle) {
-            $templates += $this->findTemplatesIn($this->rootDir.'/'.$name.'/views', $name);
             $templates += $this->findTemplatesIn($bundle->getPath().'/Resources/views', $name);
         }
 
@@ -88,9 +91,9 @@ class TemplatePathsCacheWarmer extends CacheWarmer
                 $template = $this->parser->parseFromFilename($file->getRelativePathname());
                 if (false !== $template) {
                     if (null !== $bundle) {
-                      $template->set('bundle', $bundle);
-                    }
-                    $templates[$template->getSignature()] = $file->getRealPath();
+                        $template->set('bundle', $bundle);                        
+                    } 
+                    $templates[$template->getSignature()] = $this->locator->locate($template);
                 }
             }
         }

+ 2 - 0
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

@@ -368,6 +368,8 @@ class FrameworkExtension extends Extension
         if ($config['cache_warmer']) {
             $container->getDefinition('templating.cache_warmer.template_paths')->addTag('kernel.cache_warmer');
             $container->setAlias('templating.locator', 'templating.locator.cached');
+        } else {
+            $container->setAlias('templating.locator', 'templating.locator.uncached');
         }
 
         $this->addClassesToCompile(array(

+ 2 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml

@@ -25,7 +25,7 @@
             <argument type="service" id="kernel" />
         </service>
 
-        <service id="templating.locator" class="%templating.locator.class%" public="false">
+        <service id="templating.locator.uncached" class="%templating.locator.class%" public="false">
             <argument type="service" id="file_locator" />
             <argument>%kernel.root_dir%/Resources</argument>
         </service>
@@ -39,6 +39,7 @@
         <service id="templating.cache_warmer.template_paths" class="%templating.cache_warmer.template_paths.class%" public="false">
             <argument type="service" id="kernel" />
             <argument type="service" id="templating.name_parser" />
+            <argument type="service" id="templating.locator.uncached" />
             <argument>%kernel.root_dir%/Resources</argument>
         </service>
 

+ 19 - 5
src/Symfony/Bundle/FrameworkBundle/Templating/Loader/CachedTemplateLocator.php

@@ -49,16 +49,30 @@ class CachedTemplateLocator extends TemplateLocator
      *
      * @return string The full path for the file
      *
+     * @throws \InvalidArgumentException When the template is not an instance of TemplateReferenceInterface
      * @throws \InvalidArgumentException When file is not found
      */
     public function locate($template, $currentPath = null, $first = true)
     {
-        $key = $template->getSignature();
-
-        if (!isset($this->templates[$key])) {
-            return parent::locate($template, $currentPath, $first);
+        if (!$template instanceof TemplateReferenceInterface) {
+            throw new \InvalidArgumentException("The template must be an instance of TemplateReferenceInterface.");
         }
 
-        return $this->templates[$key];
+        $path = $this->getCachedTemplatePath($template);
+
+        return $path === null ? parent::locate($template) : $path;
+    }
+
+    /**
+     * Returns the template path from the cache
+     * 
+     * @param TemplateReferenceInterface $template The template
+     * 
+     * @return string|null The path when it is present in the cache, false otherwise
+     */
+    protected function getCachedTemplatePath(TemplateReferenceInterface $template)
+    {
+        $key = $template->getSignature();
+        return isset($this->templates[$key]) ? $this->templates[$key] : null;
     }
 }

+ 6 - 1
src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.php

@@ -47,10 +47,15 @@ class TemplateLocator implements FileLocatorInterface
      *
      * @return string The full path for the file
      *
-     * @throws \InvalidArgumentException When file is not found
+     * @throws \InvalidArgumentException When the template is not an instance of TemplateReferenceInterface
+     * @throws \InvalidArgumentException When the template file can not be found
      */
     public function locate($template, $currentPath = null, $first = true)
     {
+        if (!$template instanceof TemplateReferenceInterface) {
+            throw new \InvalidArgumentException("The template must be an instance of TemplateReferenceInterface.");
+        }
+
         $key = $template->getSignature();
 
         if (isset($this->cache[$key])) {

+ 56 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/CachedTemplateLocatorTest.php

@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Loader;
+
+use Symfony\Bundle\FrameworkBundle\Templating\Loader\CachedTemplateLocator;
+use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
+use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
+use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
+
+class CachedTemplateLocatorTest extends TestCase
+{
+    public function testLocateACachedTemplate()
+    {
+        $template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine');
+
+        $locator = $this
+            ->getMockBuilder('Symfony\Bundle\FrameworkBundle\Templating\Loader\CachedTemplateLocator')
+            ->setMethods(array('getCachedTemplatePath'))
+            ->disableOriginalConstructor()
+            ->getMock()
+        ;
+
+        $locator
+            ->expects($this->once())
+            ->method('getCachedTemplatePath')
+            ->with($template)
+            ->will($this->returnValue('/cached/path/to/template'))
+        ;
+
+        $this->assertEquals('/cached/path/to/template', $locator->locate($template));
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testThrowsAnExceptionWhenTemplateIsNotATemplateReferenceInterface()
+    {
+        $locator = $this
+            ->getMockBuilder('Symfony\Bundle\FrameworkBundle\Templating\Loader\CachedTemplateLocator')
+            ->setMethods(array('getCacheTemplatePath'))
+            ->disableOriginalConstructor()
+            ->getMock()
+        ;
+
+        $locator->locate('template');
+    }
+}

+ 76 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/TemplateLocatorTest.php

@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Loader;
+
+use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
+use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
+use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
+
+class TemplateLocatorTest extends TestCase
+{
+    public function testLocateATemplate()
+    {
+        $template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine');
+
+        $fileLocator = $this->getFileLocator();
+
+        $fileLocator
+            ->expects($this->once())
+            ->method('locate')
+            ->with($template->getPath(), '/path/to/fallback')
+            ->will($this->returnValue('/path/to/template'))
+        ;
+
+        $locator = new TemplateLocator($fileLocator, '/path/to/fallback');
+
+        $this->assertEquals('/path/to/template', $locator->locate($template));
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testThrowsExceptionWhenTemplateNotFound()
+    {
+        $template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine');
+
+        $fileLocator = $this->getFileLocator();
+
+        $fileLocator
+            ->expects($this->once())
+            ->method('locate')
+            ->will($this->throwException(new \InvalidArgumentException()))
+        ;
+
+        $locator = new TemplateLocator($fileLocator, '/path/to/fallback');
+
+        $locator->locate($template);
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testThrowsAnExceptionWhenTemplateIsNotATemplateReferenceInterface()
+    {
+        $locator = new TemplateLocator($this->getFileLocator(), '/path/to/fallback');
+        $locator->locate('template');
+    }
+
+    protected function getFileLocator()
+    {
+        return $this
+            ->getMockBuilder('Symfony\Component\Config\FileLocator')
+            ->setMethods(array('locate'))
+            ->setConstructorArgs(array('/path/to/fallback'))
+            ->getMock()
+        ;
+    }
+}

+ 1 - 4
src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php

@@ -60,9 +60,6 @@ class TemplateCacheCacheWarmer extends CacheWarmer
             foreach ($this->findTemplatesIn($bundle->getPath().'/Resources/views', $name) as $template) {
                 $twig->loadTemplate($template);
             }
-            foreach ($this->findTemplatesIn($this->rootDir.'/'.$name.'/views', $name) as $template) {
-                $twig->loadTemplate($template);
-            }
         }
 
         foreach ($this->findTemplatesIn($this->rootDir.'/views') as $template) {
@@ -100,7 +97,7 @@ class TemplateCacheCacheWarmer extends CacheWarmer
                     if (null !== $bundle) {
                       $template->set('bundle', $bundle);
                     }
-                    $templates[] = $template;
+                    $templates[] = $template->getLogicalName();
                 }
             }
         }

+ 1 - 1
src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php

@@ -25,7 +25,7 @@ class Configuration implements ConfigurationInterface
 
         $rootNode
             ->children()
-                ->scalarNode('cache_warmer')->end()
+                ->scalarNode('cache_warmer')->defaultFalse()->end()
             ->end();
         ;
 

+ 1 - 1
src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php

@@ -60,7 +60,7 @@ class TwigExtension extends Extension
             }
         }
 
-        if (!empty($config['cache_warmer'])) {
+        if ($config['cache_warmer']) {
             $container->getDefinition('twig.cache_warmer')->addTag('kernel.cache_warmer');
         }
 

+ 9 - 3
src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php

@@ -76,12 +76,18 @@ class FilesystemLoader implements \Twig_LoaderInterface
         return filemtime($this->findTemplate($name)) < $time;
     }
 
+    /**
+     * Returns the path to the template file
+     *
+     * @param $name The template logical name
+     *
+     * @return string The path to the template file
+     */
     protected function findTemplate($name)
     {
-        $tpl = ($name instanceof TemplateReferenceInterface) ? $name : $this->parser->parse($name);
+        $tpl = $this->parser->parse($name);
 
-        $key = $tpl->getSignature();
-        if (isset($this->cache[$key])) {
+        if (isset($this->cache[$key = $tpl->getSignature()])) {
             return $this->cache[$key];
         }