merged vicb:template-factorization

This commit is contained in:
Fabien Potencier 2011-04-26 14:38:47 +02:00
commit e45d5fa857
14 changed files with 232 additions and 98 deletions

View File

@ -12,9 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\CacheWarmer;
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\TemplateFinderInterface;
use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
/**
@ -24,25 +22,19 @@ use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
*/
class TemplatePathsCacheWarmer extends CacheWarmer
{
protected $kernel;
protected $parser;
protected $rootDir;
protected $finder;
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
* @param TemplateFinderInterface $finder A template finder
* @param TemplateLocator $locator The template locator
*/
public function __construct(KernelInterface $kernel, TemplateNameParser $parser, TemplateLocator $locator, $rootDir)
public function __construct(TemplateFinderInterface $finder, TemplateLocator $locator)
{
$this->kernel = $kernel;
$this->parser = $parser;
$this->finder = $finder;
$this->locator = $locator;
$this->rootDir = $rootDir;
}
/**
@ -54,12 +46,10 @@ class TemplatePathsCacheWarmer extends CacheWarmer
{
$templates = array();
foreach ($this->kernel->getBundles() as $name => $bundle) {
$templates += $this->findTemplatesIn($bundle->getPath().'/Resources/views', $name);
foreach ($this->finder->findAllTemplates() as $template) {
$templates[$template->getSignature()] = $this->locator->locate($template);
}
$templates += $this->findTemplatesIn($this->rootDir.'/views');
$this->writeCacheFile($cacheDir.'/templates.php', sprintf('<?php return %s;', var_export($templates, true)));
}
@ -72,32 +62,4 @@ class TemplatePathsCacheWarmer extends CacheWarmer
{
return false;
}
/**
* Find templates in the given directory
*
* @param string $dir The folder where to look for templates
* @param string $bundle The name of the bundle (null when out of a bundle)
*
* @return array An array of template paths
*/
protected function findTemplatesIn($dir, $bundle = null)
{
$templates = array();
if (is_dir($dir)) {
$finder = new Finder();
foreach ($finder->files()->followLinks()->in($dir) as $file) {
$template = $this->parser->parseFromFilename($file->getRelativePathname());
if (false !== $template) {
if (null !== $bundle) {
$template->set('bundle', $bundle);
}
$templates[$template->getSignature()] = $this->locator->locate($template);
}
}
}
return $templates;
}
}

View File

@ -13,6 +13,7 @@
<parameter key="templating.loader.filesystem.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\FilesystemLoader</parameter>
<parameter key="templating.loader.cache.class">Symfony\Component\Templating\Loader\CacheLoader</parameter>
<parameter key="templating.loader.chain.class">Symfony\Component\Templating\Loader\ChainLoader</parameter>
<parameter key="templating.finder.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateFinder</parameter>
</parameters>
<services>
@ -34,13 +35,17 @@
<argument type="service" id="file_locator" />
</service>
<service id="templating.cache_warmer.template_paths" class="%templating.cache_warmer.template_paths.class%" public="false">
<service id="templating.finder" class="%templating.finder.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>
<service id="templating.cache_warmer.template_paths" class="%templating.cache_warmer.template_paths.class%" public="false">
<argument type="service" id="templating.finder" />
<argument type="service" id="templating.locator.uncached" />
</service>
<service id="templating.loader.filesystem" class="%templating.loader.filesystem.class%" public="false">
<argument type="service" id="templating.locator" />
</service>

View File

@ -0,0 +1,109 @@
<?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\Templating\Loader;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
/**
* Finds all the templates.
*
* @author Victor Berchet <victor@suumit.com>
*/
class TemplateFinder implements TemplateFinderInterface
{
private $kernel;
private $parser;
private $rootDir;
private $templates;
/**
* Constructor.
*
* @param KernelInterface $kernel A KernelInterface instance
* @param TemplateNameParser $parser A TemplateNameParser instance
* @param string $rootDir The directory where global templates can be stored
*/
public function __construct(KernelInterface $kernel, TemplateNameParser $parser, $rootDir)
{
$this->kernel = $kernel;
$this->parser = $parser;
$this->rootDir = $rootDir;
}
/**
* Find all the templates in the bundle and in the kernel Resources folder.
*
* @return array An array of templates of type TemplateReferenceInterface
*/
public function findAllTemplates()
{
if (null !== $this->templates) {
return $this->templates;
}
$templates = array();
foreach ($this->kernel->getBundles() as $name => $bundle) {
$templates = array_merge($templates, $this->findTemplatesInBundle($bundle));
}
$templates = array_merge($templates, $this->findTemplatesInFolder($this->rootDir.'/views'));
return $this->templates = $templates;
}
/**
* Find templates in the given directory.
*
* @param string $dir The folder where to look for templates
*
* @return array An array of templates of type TemplateReferenceInterface
*/
private function findTemplatesInFolder($dir)
{
$templates = array();
if (is_dir($dir)) {
$finder = new Finder();
foreach ($finder->files()->followLinks()->in($dir) as $file) {
$template = $this->parser->parseFromFilename($file->getRelativePathname());
if (false !== $template) {
$templates[] = $template;
}
}
}
return $templates;
}
/**
* Find templates in the given bundle.
*
* @param BundleInterface $bundle The bundle where to look for templates
*
* @return array An array of templates of type TemplateReferenceInterface
*/
private function findTemplatesInBundle(BundleInterface $bundle)
{
$templates = $this->findTemplatesInFolder($bundle->getPath().'/Resources/views');
$name = $bundle->getName();
foreach ($templates as $i => $template) {
$templates[$i] = $template->set('bundle', $name);
}
return $templates;
}
}

View File

@ -0,0 +1,28 @@
<?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\Templating\Loader;
/**
* Interface for finding all the templates.
*
* @author Victor Berchet <victor@suumit.com>
*/
interface TemplateFinderInterface
{
/**
* Find all the templates.
*
* @return array An array of templates of type TemplateReferenceInterface
*/
function findAllTemplates();
}

View File

@ -0,0 +1,9 @@
<?php
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BaseBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class BaseBundle extends Bundle
{
}

View File

@ -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\Tests\TestCase;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser;
use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateFinder;
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BaseBundle\BaseBundle;
class TemplateFinderTest extends TestCase
{
public function testFindAllTemplates()
{
$kernel = $this
->getMockBuilder('Symfony\Component\HttpKernel\Kernel')
->disableOriginalConstructor()
->getMock()
;
$kernel
->expects($this->any())
->method('getBundle')
;
$kernel
->expects($this->once())
->method('getBundles')
->will($this->returnValue(array('BaseBundle' => new BaseBundle())))
;
$parser = new TemplateNameParser($kernel);
$finder = new TemplateFinder($kernel, $parser, __DIR__.'/../../Fixtures/Resources');
$templates = array_map(
function ($template) { return $template->getLogicalName(); },
$finder->findAllTemplates()
);
$this->assertEquals(3, count($templates), '->findAllTemplates() find all templates in the bundles and global folders');
$this->assertContains('BaseBundle::base.format.engine', $templates);
$this->assertContains('BaseBundle:controller:base.format.engine', $templates);
$this->assertContains('::resource.format.engine', $templates);
}
}

View File

@ -11,9 +11,10 @@
namespace Symfony\Bundle\TwigBundle\CacheWarmer;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;
use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplatePathsCacheWarmer;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateFinder;
/**
* Generates the Twig cache for all templates.
@ -26,25 +27,22 @@ use Symfony\Component\Finder\Finder;
class TemplateCacheCacheWarmer implements CacheWarmerInterface
{
protected $container;
protected $parser;
protected $kernel;
protected $warmer;
/**
* Constructor.
*
* @param ContainerInterface $container The dependency injection container
* @param string $rootDir The directory where global templates can be stored
* @param ContainerInterface $container The dependency injection container
* @param TemplatePathsCacheWarmer $warmer The template paths cache warmer
*/
public function __construct(ContainerInterface $container, $rootDir)
public function __construct(ContainerInterface $container, TemplateFinder $finder)
{
// we don't inject the Twig environment directly as it needs
// the loader, which is a cached one, and the cache is not
// yet available when this instance is created (the
// TemplateCacheCacheWarmer has not been run yet).
// We don't inject the Twig environment directly as it depends on the
// template locator (via the loader) which might be a cached one.
// The cached template locator is available once the TemplatePathsCacheWarmer
// has been warmed up
$this->container = $container;
$this->parser = $container->get('templating.name_parser');
$this->kernel = $container->get('kernel');
$this->rootDir = $rootDir;
$this->finder = $finder;
}
/**
@ -56,15 +54,11 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
{
$twig = $this->container->get('twig');
foreach ($this->kernel->getBundles() as $name => $bundle) {
foreach ($this->findTemplatesIn($bundle->getPath().'/Resources/views', $name) as $template) {
foreach ($this->finder->findAllTemplates() as $template) {
if ('twig' === $template->get('engine')) {
$twig->loadTemplate($template);
}
}
foreach ($this->findTemplatesIn($this->rootDir.'/views') as $template) {
$twig->loadTemplate($template);
}
}
/**
@ -76,32 +70,4 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
{
return true;
}
/**
* Find templates in the given directory
*
* @param string $dir The folder where to look for templates
* @param string $bundle The name of the bundle (null when out of a bundle)
*
* @return array An array of TemplateReference
*/
protected function findTemplatesIn($dir, $bundle = null)
{
$templates = array();
if (is_dir($dir)) {
$finder = new Finder();
foreach ($finder->files()->followLinks()->in($dir) as $file) {
$template = $this->parser->parseFromFilename($file->getRelativePathname());
if (false !== $template && 'twig' == $template->get('engine')) {
if (null !== $bundle) {
$template->set('bundle', $bundle);
}
$templates[] = $template->getLogicalName();
}
}
}
return $templates;
}
}

View File

@ -19,7 +19,7 @@
<service id="twig.cache_warmer" class="%twig.cache_warmer.class%" public="false">
<argument type="service" id="service_container" />
<argument>%kernel.root_dir%/Resources</argument>
<argument type="service" id="templating.finder" />
</service>
<service id="twig.loader" class="%twig.loader.class%">

View File

@ -13,7 +13,6 @@ namespace Symfony\Bundle\WebProfilerBundle;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Bundle\TwigBundle\TwigEngine;