feature #19687 [FrameworkBundle] Use relative paths in templates paths cache (tgalopin)

This PR was merged into the 3.2-dev branch.

Discussion
----------

[FrameworkBundle] Use relative paths in templates paths cache

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

This implements the usage of relative paths instead of absolute ones in `var/cache/*/templates.php`, important for ability to build the cache in a different context than where it will be used.

This PR transforms the following `templates.php`:

``` php
<?php return array (
  ':default:index.html.twig' => '/home/tgalopin/www/symfony-standard/app/Resources/views/default/index.html.twig',
  '::base.html.twig' => '/home/tgalopin/www/symfony-standard/app/Resources/views/base.html.twig',
);
```

Into:

``` php
<?php return array (
  ':default:index.html.twig' => __DIR__.'/../../../app/Resources/views/default/index.html.twig',
  '::base.html.twig' => __DIR__.'/../../../app/Resources/views/base.html.twig',
);
```

I also added tests for the TemplateCachePathsWarmer and improved tests for the TemplateLocator.

Commits
-------

6f6139c [FrameworkBundle] Use relative paths in templates paths cache
This commit is contained in:
Fabien Potencier 2016-08-23 10:17:40 -07:00
commit f5f1e103c4
6 changed files with 117 additions and 3 deletions

View File

@ -11,6 +11,7 @@
namespace Symfony\Bundle\FrameworkBundle\CacheWarmer;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;
use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
@ -34,6 +35,7 @@ class TemplatePathsCacheWarmer extends CacheWarmer
{
$this->finder = $finder;
$this->locator = $locator;
$this->filesystem = new Filesystem();
}
/**
@ -46,10 +48,12 @@ class TemplatePathsCacheWarmer extends CacheWarmer
$templates = array();
foreach ($this->finder->findAllTemplates() as $template) {
$templates[$template->getLogicalName()] = $this->locator->locate($template);
$templates[$template->getLogicalName()] = rtrim($this->filesystem->makePathRelative($this->locator->locate($template), $cacheDir), '/');
}
$this->writeCacheFile($cacheDir.'/templates.php', sprintf('<?php return %s;', var_export($templates, true)));
$templates = str_replace("' => '", "' => __DIR__.'/", var_export($templates, true));
$this->writeCacheFile($cacheDir.'/templates.php', sprintf("<?php return %s;\n", $templates));
}
/**

View File

@ -32,7 +32,7 @@ class TemplateLocator implements FileLocatorInterface
*/
public function __construct(FileLocatorInterface $locator, $cacheDir = null)
{
if (null !== $cacheDir && is_file($cache = $cacheDir.'/templates.php')) {
if (null !== $cacheDir && file_exists($cache = $cacheDir.'/templates.php')) {
$this->cache = require $cache;
}

View File

@ -0,0 +1,102 @@
<?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\CacheWarmer;
use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinderInterface;
use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplatePathsCacheWarmer;
use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Filesystem\Filesystem;
class TemplatePathsCacheWarmerTest extends TestCase
{
/** @var Filesystem */
private $filesystem;
/** @var TemplateFinderInterface */
private $templateFinder;
/** @var FileLocator */
private $fileLocator;
/** @var TemplateLocator */
private $templateLocator;
private $tmpDir;
public function setUp()
{
$this->templateFinder = $this
->getMockBuilder(TemplateFinderInterface::class)
->setMethods(array('findAllTemplates'))
->getMock();
$this->fileLocator = $this
->getMockBuilder(FileLocator::class)
->setMethods(array('locate'))
->setConstructorArgs(array('/path/to/fallback'))
->getMock();
$this->templateLocator = new TemplateLocator($this->fileLocator);
$this->tmpDir = sys_get_temp_dir().DIRECTORY_SEPARATOR.uniqid('cache_template_paths_', true);
$this->filesystem = new Filesystem();
$this->filesystem->mkdir($this->tmpDir);
}
public function tearDown()
{
$this->filesystem->remove($this->tmpDir);
}
public function testWarmUp()
{
$template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine');
$this->templateFinder
->expects($this->once())
->method('findAllTemplates')
->will($this->returnValue(array($template)));
$this->fileLocator
->expects($this->once())
->method('locate')
->with($template->getPath())
->will($this->returnValue(dirname($this->tmpDir).'/path/to/template.html.twig'));
$warmer = new TemplatePathsCacheWarmer($this->templateFinder, $this->templateLocator);
$warmer->warmUp($this->tmpDir);
$this->assertFileEquals(__DIR__.'/../Fixtures/TemplatePathsCache/templates.php', $this->tmpDir.'/templates.php');
}
public function testWarmUpEmpty()
{
$this->templateFinder
->expects($this->once())
->method('findAllTemplates')
->will($this->returnValue(array()));
$this->fileLocator
->expects($this->never())
->method('locate');
$warmer = new TemplatePathsCacheWarmer($this->templateFinder, $this->templateLocator);
$warmer->warmUp($this->tmpDir);
$this->assertFileExists($this->tmpDir.'/templates.php');
$this->assertSame(file_get_contents(__DIR__.'/../Fixtures/TemplatePathsCache/templates-empty.php'), file_get_contents($this->tmpDir.'/templates.php'));
}
}

View File

@ -0,0 +1,2 @@
<?php return array (
);

View File

@ -0,0 +1,3 @@
<?php return array (
'bundle:controller:name.format.engine' => __DIR__.'/../path/to/template.html.twig',
);

View File

@ -33,6 +33,9 @@ class TemplateLocatorTest extends TestCase
$locator = new TemplateLocator($fileLocator);
$this->assertEquals('/path/to/template', $locator->locate($template));
// Assert cache is used as $fileLocator->locate should be called only once
$this->assertEquals('/path/to/template', $locator->locate($template));
}
public function testThrowsExceptionWhenTemplateNotFound()