bug #21237 [FrameworkBundle] Fix relative paths used as cache keys (nicolas-grekas)

This PR was merged into the 2.7 branch.

Discussion
----------

[FrameworkBundle] Fix relative paths used as cache keys

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

This bug fix is particularly important on 3.2, where the generated "templates.php" does contain relative paths. This turned out to generate a fatal error on our setup, because of non-normalized twig-cache keys. See also https://github.com/twigphp/Twig/pull/2354
As a bonus, this saves us a copy-on-write on PHP 7.

Commits
-------

5441e9bc90 [FrameworkBundle] Fix relative paths used as cache keys
This commit is contained in:
Fabien Potencier 2017-01-11 08:27:33 -08:00
commit 1c6dfce018
3 changed files with 23 additions and 2 deletions

View File

@ -24,6 +24,8 @@ class TemplateLocator implements FileLocatorInterface
protected $locator;
protected $cache;
private $cacheHits = array();
/**
* Constructor.
*
@ -71,12 +73,15 @@ class TemplateLocator implements FileLocatorInterface
$key = $this->getCacheKey($template);
if (isset($this->cacheHits[$key])) {
return $this->cacheHits[$key];
}
if (isset($this->cache[$key])) {
return $this->cache[$key];
return $this->cacheHits[$key] = realpath($this->cache[$key]) ?: $this->cache[$key];
}
try {
return $this->cache[$key] = $this->locator->locate($template->getPath(), $currentPath);
return $this->cacheHits[$key] = $this->locator->locate($template->getPath(), $currentPath);
} catch (\InvalidArgumentException $e) {
throw new \InvalidArgumentException(sprintf('Unable to find template "%s" : "%s".', $template, $e->getMessage()), 0, $e);
}

View File

@ -0,0 +1,5 @@
<?php
return array(
'bundle:controller:name.format.engine' => __DIR__.'/../Fixtures/Resources/views/this.is.a.template.format.engine',
);

View File

@ -35,6 +35,17 @@ class TemplateLocatorTest extends TestCase
$this->assertEquals('/path/to/template', $locator->locate($template));
}
public function testLocateATemplateFromCacheDir()
{
$template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine');
$fileLocator = $this->getFileLocator();
$locator = new TemplateLocator($fileLocator, __DIR__.'/../../Fixtures');
$this->assertEquals(realpath(__DIR__.'/../../Fixtures/Resources/views/this.is.a.template.format.engine'), $locator->locate($template));
}
public function testThrowsExceptionWhenTemplateNotFound()
{
$template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine');