bug #10894 [HttpKernel] removed absolute paths from the generated container (fabpot)

This PR was merged into the 2.3 branch.

Discussion
----------

[HttpKernel] removed absolute paths from the generated container

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | first step to resolve #6484, #3079, and #9238
| License       | MIT
| Doc PR        | n/a

This PR converts absolute paths to relative ones in the dumped container. The code is a bit "ugly", but it gets the job done and I'm not sure that there is a more elegant way without breaking everything.

Commits
-------

c1450b4 [HttpKernel] removed absolute paths from the generated container
This commit is contained in:
Fabien Potencier 2014-05-17 15:25:10 +02:00
commit 735e9a4768
7 changed files with 86 additions and 1 deletions

View File

@ -32,6 +32,7 @@ use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\Loader\DelegatingLoader;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\ClassLoader\ClassCollectionLoader;
use Symfony\Component\Filesystem\Filesystem;
/**
* The Kernel is the heart of the Symfony system.
@ -716,9 +717,43 @@ abstract class Kernel implements KernelInterface, TerminableInterface
$content = static::stripComments($content);
}
$content = $this->removeAbsolutePathsFromContainer($content);
$cache->write($content, $container->getResources());
}
/**
* Converts absolute paths to relative ones in the dumped container.
*/
private function removeAbsolutePathsFromContainer($content)
{
if (!class_exists('Symfony\Component\Filesystem\Filesystem')) {
return $content;
}
// find the "real" root dir (by finding the composer.json file)
$rootDir = $this->getRootDir();
$previous = $rootDir;
while (!file_exists($rootDir.'/composer.json')) {
if ($previous === $rootDir = realpath($rootDir.'/..')) {
// unable to detect the project root, give up
return $content;
}
$previous = $rootDir;
}
$rootDir = rtrim($rootDir, '/');
$cacheDir = $this->getCacheDir();
$filesystem = new Filesystem();
return preg_replace_callback("{'([^']*)(".preg_quote($rootDir)."[^']*)'}", function ($match) use ($filesystem, $cacheDir) {
$prefix = isset($match[1]) && $match[1] ? "'$match[1]'.__DIR__.'/" : "__DIR__.'/";
return $prefix.rtrim($filesystem->makePathRelative($match[2], $cacheDir), '/')."'";
}, $content);
}
/**
* Returns a loader for the container.
*

View File

@ -0,0 +1,7 @@
'ROOT_DIR/app/cache/dev/foo'
'ROOT_DIR/app/cache/foo'
'ROOT_DIR/foo/bar.php'
'/some/where/else/foo'
'file:ROOT_DIR/app/cache/dev/profiler'

View File

@ -0,0 +1,7 @@
__DIR__.'/foo'
__DIR__.'/../foo'
__DIR__.'/../../../foo/bar.php'
'/some/where/else/foo'
'file:'.__DIR__.'/profiler'

View File

@ -16,6 +16,11 @@ use Symfony\Component\Config\Loader\LoaderInterface;
class KernelForTest extends Kernel
{
public function setRootDir($dir)
{
$this->rootDir = $dir;
}
public function getBundleMap()
{
return $this->bundleMap;

View File

@ -824,6 +824,34 @@ EOF;
$kernel->terminate(Request::create('/'), new Response());
}
public function testRemoveAbsolutePathsFromContainer()
{
$kernel = new KernelForTest('dev', true);
$kernel->setRootDir($symfonyRootDir = __DIR__.'/Fixtures/DumpedContainers/app');
$content = file_get_contents($symfonyRootDir.'/cache/dev/withAbsolutePaths.php');
$content = str_replace('ROOT_DIR', __DIR__.'/Fixtures/DumpedContainers', $content);
$m = new \ReflectionMethod($kernel, 'removeAbsolutePathsFromContainer');
$m->setAccessible(true);
$content = $m->invoke($kernel, $content);
$this->assertEquals(file_get_contents($symfonyRootDir.'/cache/dev/withoutAbsolutePaths.php'), $content);
}
public function testRemoveAbsolutePathsFromContainerGiveUpWhenComposerJsonPathNotGuessable()
{
$kernel = new KernelForTest('dev', true);
$kernel->setRootDir($symfonyRootDir = sys_get_temp_dir());
$content = file_get_contents(__DIR__.'/Fixtures/DumpedContainers/app/cache/dev/withAbsolutePaths.php');
$content = str_replace('ROOT_DIR', __DIR__.'/Fixtures/DumpedContainers', $content);
$m = new \ReflectionMethod($kernel, 'removeAbsolutePathsFromContainer');
$m->setAccessible(true);
$newContent = $m->invoke($kernel, $content);
$this->assertEquals($newContent, $content);
}
protected function getBundle($dir = null, $parent = null, $className = null, $bundleName = null)
{
$bundle = $this

View File

@ -29,6 +29,7 @@
"symfony/console": "~2.2",
"symfony/dependency-injection": "~2.0",
"symfony/finder": "~2.0",
"symfony/filesystem": "~2.4",
"symfony/process": "~2.0",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.2",
@ -40,7 +41,8 @@
"symfony/config": "",
"symfony/console": "",
"symfony/dependency-injection": "",
"symfony/finder": ""
"symfony/finder": "",
"symfony/filesystem": ""
},
"autoload": {
"psr-0": { "Symfony\\Component\\HttpKernel\\": "" }