bug #22570 Fixes twig bundle project root dir discovery (Pierre Rineau)

This PR was squashed before being merged into the 3.3-dev branch (closes #22570).

Discussion
----------

Fixes twig bundle project root dir discovery

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

<!--
- Bug fixes must be submitted against the lowest branch where they apply
  (lowest branches are regularly merged to upper ones so they get the fixes too).
- Features and deprecations must be submitted against the master branch.
- Please fill in this template according to the PR you're about to submit.
- Replace this comment by a description of what your PR is solving.
-->

TwigBundle ExtensionPass uses a directory lookup algorithm to find the composer.json file. When working under open_basedir restrictions, if the project root folder is not allowed PHP runtime to read, the composer.json will never be found, throwing PHP notices along the way and ending up using the filesystem root instead.

Since that 3.3 introduced the kernel getProjectRoot() method and kernel.project_dir variable, the TwigBundle can now leverage it, in order to get more consistent, and allow site builders to override the getProjectRoot() kernel method, hence bypass the open_basedir restrictions in reliable and safe way.

Commits
-------

3cb2e5b7dd Fixes twig bundle project root dir discovery
This commit is contained in:
Fabien Potencier 2017-04-28 10:16:56 -07:00
commit 143b5ff26a
5 changed files with 4 additions and 20 deletions

View File

@ -80,16 +80,13 @@ class ExtensionPass implements CompilerPassInterface
$container->getDefinition('twig.extension.debug')->addTag('twig.extension');
}
$composerRootDir = $this->getComposerRootDir($container->getParameter('kernel.root_dir'));
$twigLoader = $container->getDefinition('twig.loader.native_filesystem');
if ($container->has('templating')) {
$loader = $container->getDefinition('twig.loader.filesystem');
$loader->setMethodCalls(array_merge($twigLoader->getMethodCalls(), $loader->getMethodCalls()));
$loader->replaceArgument(2, $composerRootDir);
$twigLoader->clearTag('twig.loader');
} else {
$twigLoader->replaceArgument(1, $composerRootDir);
$container->setAlias('twig.loader.filesystem', new Alias('twig.loader.native_filesystem', false));
}
@ -109,18 +106,4 @@ class ExtensionPass implements CompilerPassInterface
$container->getDefinition('twig.extension.expression')->addTag('twig.extension');
}
}
private function getComposerRootDir($rootDir)
{
$dir = $rootDir;
while (!file_exists($dir.'/composer.json')) {
if ($dir === dirname($dir)) {
return $rootDir;
}
$dir = dirname($dir);
}
return $dir;
}
}

View File

@ -7,7 +7,7 @@
<service id="twig.loader.filesystem" class="Symfony\Bundle\TwigBundle\Loader\FilesystemLoader" public="false">
<argument type="service" id="templating.locator" />
<argument type="service" id="templating.name_parser" />
<argument /> <!-- project's root dir -->
<argument>%kernel.project_dir%</argument>
<tag name="twig.loader"/>
</service>

View File

@ -48,7 +48,7 @@
<service id="twig.loader.native_filesystem" class="Twig_Loader_Filesystem" public="false">
<argument type="collection" /> <!-- paths -->
<argument /> <!-- project's root dir -->
<argument>%kernel.project_dir%</argument>
<tag name="twig.loader"/>
</service>

View File

@ -256,6 +256,7 @@ class TwigExtensionTest extends TestCase
$container = new ContainerBuilder(new ParameterBag(array(
'kernel.cache_dir' => __DIR__,
'kernel.root_dir' => __DIR__.'/Fixtures',
'kernel.project_dir' => __DIR__,
'kernel.charset' => 'UTF-8',
'kernel.debug' => false,
'kernel.bundles' => array(

View File

@ -20,7 +20,7 @@
"symfony/config": "~3.2",
"symfony/twig-bridge": "^3.2.1",
"symfony/http-foundation": "~2.8|~3.0",
"symfony/http-kernel": "~2.8.16|~3.1.9|^3.2.2",
"symfony/http-kernel": "^3.3",
"twig/twig": "^1.32|^2.2"
},
"require-dev": {