bug #27764 [TwigBundle] Fixed caching of templates in default path on cache warmup (yceruto)

This PR was merged into the 3.4 branch.

Discussion
----------

[TwigBundle] Fixed caching of templates in default path on cache warmup

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

**Reproducer**
```bash
$ git clone https://github.com/symfony/demo && cd demo
$ bin/console cache:clear
$ find var/cache/dev/twig -printf "%y\n" | awk '/f/{f++}/d/{d++}END{printf "%d directories, %d files\n", d, f}'
...
```
**Before:**
```bash
...
131 directories, 167 files
```
Twig `paths` config:
44ce4dd625/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php (L104)
`%kernel.root_dir%/Resources/views`:
2b01d59481/src/Symfony/Bundle/TwigBundle/TemplateIterator.php (L50)
**After:**
```bash
...
141 directories, 193 files
```
Adding `%twig.default_path%`.

Commits
-------

245c860ab4 Fixed caching of templates in default path on cache warmup
This commit is contained in:
Fabien Potencier 2018-09-05 10:48:23 +02:00
commit eaeb124093
4 changed files with 19 additions and 9 deletions

View File

@ -41,6 +41,7 @@
<argument type="service" id="kernel" /> <argument type="service" id="kernel" />
<argument>%kernel.root_dir%</argument> <argument>%kernel.root_dir%</argument>
<argument type="collection" /> <!-- Twig paths --> <argument type="collection" /> <!-- Twig paths -->
<argument>%twig.default_path%</argument>
</service> </service>
<service id="twig.template_cache_warmer" class="Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer"> <service id="twig.template_cache_warmer" class="Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer">

View File

@ -25,17 +25,20 @@ class TemplateIterator implements \IteratorAggregate
private $rootDir; private $rootDir;
private $templates; private $templates;
private $paths; private $paths;
private $defaultPath;
/** /**
* @param KernelInterface $kernel A KernelInterface instance * @param KernelInterface $kernel A KernelInterface instance
* @param string $rootDir The directory where global templates can be stored * @param string $rootDir The directory where global templates can be stored
* @param array $paths Additional Twig paths to warm * @param array $paths Additional Twig paths to warm
* @param string $defaultPath The directory where global templates can be stored
*/ */
public function __construct(KernelInterface $kernel, $rootDir, array $paths = array()) public function __construct(KernelInterface $kernel, $rootDir, array $paths = array(), $defaultPath = null)
{ {
$this->kernel = $kernel; $this->kernel = $kernel;
$this->rootDir = $rootDir; $this->rootDir = $rootDir;
$this->paths = $paths; $this->paths = $paths;
$this->defaultPath = $defaultPath;
} }
/** /**
@ -47,7 +50,10 @@ class TemplateIterator implements \IteratorAggregate
return $this->templates; return $this->templates;
} }
$this->templates = $this->findTemplatesInDirectory($this->rootDir.'/Resources/views'); $this->templates = array_merge(
$this->findTemplatesInDirectory($this->rootDir.'/Resources/views'),
$this->findTemplatesInDirectory($this->defaultPath, null, array('bundles'))
);
foreach ($this->kernel->getBundles() as $bundle) { foreach ($this->kernel->getBundles() as $bundle) {
$name = $bundle->getName(); $name = $bundle->getName();
if ('Bundle' === substr($name, -6)) { if ('Bundle' === substr($name, -6)) {
@ -57,7 +63,8 @@ class TemplateIterator implements \IteratorAggregate
$this->templates = array_merge( $this->templates = array_merge(
$this->templates, $this->templates,
$this->findTemplatesInDirectory($bundle->getPath().'/Resources/views', $name), $this->findTemplatesInDirectory($bundle->getPath().'/Resources/views', $name),
$this->findTemplatesInDirectory($this->rootDir.'/'.$bundle->getName().'/views', $name) $this->findTemplatesInDirectory($this->rootDir.'/'.$bundle->getName().'/views', $name),
$this->findTemplatesInDirectory($this->defaultPath.'/bundles/'.$bundle->getName(), $name)
); );
} }
@ -76,14 +83,14 @@ class TemplateIterator implements \IteratorAggregate
* *
* @return array * @return array
*/ */
private function findTemplatesInDirectory($dir, $namespace = null) private function findTemplatesInDirectory($dir, $namespace = null, array $excludeDirs = array())
{ {
if (!is_dir($dir)) { if (!is_dir($dir)) {
return array(); return array();
} }
$templates = array(); $templates = array();
foreach (Finder::create()->files()->followLinks()->in($dir) as $file) { foreach (Finder::create()->files()->followLinks()->in($dir)->exclude($excludeDirs) as $file) {
$templates[] = (null !== $namespace ? '@'.$namespace.'/' : '').str_replace('\\', '/', $file->getRelativePathname()); $templates[] = (null !== $namespace ? '@'.$namespace.'/' : '').str_replace('\\', '/', $file->getRelativePathname());
} }

View File

@ -25,13 +25,14 @@ class TemplateIteratorTest extends TestCase
$kernel->expects($this->any())->method('getBundles')->will($this->returnValue(array( $kernel->expects($this->any())->method('getBundles')->will($this->returnValue(array(
$bundle, $bundle,
))); )));
$iterator = new TemplateIterator($kernel, __DIR__.'/Fixtures/templates', array(__DIR__.'/Fixtures/templates/Foo' => 'Foo')); $iterator = new TemplateIterator($kernel, __DIR__.'/Fixtures/templates', array(__DIR__.'/Fixtures/templates/Foo' => 'Foo'), __DIR__.'/DependencyInjection/Fixtures/templates');
$sorted = iterator_to_array($iterator); $sorted = iterator_to_array($iterator);
sort($sorted); sort($sorted);
$this->assertEquals( $this->assertEquals(
array( array(
'@Bar/index.html.twig', '@Bar/index.html.twig',
'@Bar/layout.html.twig',
'@Foo/index.html.twig', '@Foo/index.html.twig',
'layout.html.twig', 'layout.html.twig',
'sub/sub.html.twig', 'sub/sub.html.twig',