Fix DebugCommand when chain loader is involved
This commit is contained in:
parent
675c45850c
commit
f647b4a29d
@ -20,6 +20,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
use Symfony\Component\Finder\Finder;
|
use Symfony\Component\Finder\Finder;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
|
use Twig\Loader\ChainLoader;
|
||||||
use Twig\Loader\FilesystemLoader;
|
use Twig\Loader\FilesystemLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,6 +37,7 @@ class DebugCommand extends Command
|
|||||||
private $bundlesMetadata;
|
private $bundlesMetadata;
|
||||||
private $twigDefaultPath;
|
private $twigDefaultPath;
|
||||||
private $rootDir;
|
private $rootDir;
|
||||||
|
private $filesystemLoaders;
|
||||||
|
|
||||||
public function __construct(Environment $twig, string $projectDir = null, array $bundlesMetadata = [], string $twigDefaultPath = null, string $rootDir = null)
|
public function __construct(Environment $twig, string $projectDir = null, array $bundlesMetadata = [], string $twigDefaultPath = null, string $rootDir = null)
|
||||||
{
|
{
|
||||||
@ -87,7 +89,7 @@ EOF
|
|||||||
$name = $input->getArgument('name');
|
$name = $input->getArgument('name');
|
||||||
$filter = $input->getOption('filter');
|
$filter = $input->getOption('filter');
|
||||||
|
|
||||||
if (null !== $name && !$this->twig->getLoader() instanceof FilesystemLoader) {
|
if (null !== $name && [] === $this->getFilesystemLoaders()) {
|
||||||
throw new InvalidArgumentException(sprintf('Argument "name" not supported, it requires the Twig loader "%s"', FilesystemLoader::class));
|
throw new InvalidArgumentException(sprintf('Argument "name" not supported, it requires the Twig loader "%s"', FilesystemLoader::class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,9 +152,11 @@ EOF
|
|||||||
$message = 'No template paths configured for your application';
|
$message = 'No template paths configured for your application';
|
||||||
} else {
|
} else {
|
||||||
$message = sprintf('No template paths configured for "@%s" namespace', $namespace);
|
$message = sprintf('No template paths configured for "@%s" namespace', $namespace);
|
||||||
$namespaces = $this->twig->getLoader()->getNamespaces();
|
foreach ($this->getFilesystemLoaders() as $loader) {
|
||||||
foreach ($this->findAlternatives($namespace, $namespaces) as $namespace) {
|
$namespaces = $loader->getNamespaces();
|
||||||
$alternatives[] = '@'.$namespace;
|
foreach ($this->findAlternatives($namespace, $namespaces) as $namespace) {
|
||||||
|
$alternatives[] = '@'.$namespace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,25 +247,25 @@ EOF
|
|||||||
|
|
||||||
private function getLoaderPaths(string $name = null): array
|
private function getLoaderPaths(string $name = null): array
|
||||||
{
|
{
|
||||||
/** @var FilesystemLoader $loader */
|
|
||||||
$loader = $this->twig->getLoader();
|
|
||||||
$loaderPaths = [];
|
$loaderPaths = [];
|
||||||
$namespaces = $loader->getNamespaces();
|
foreach ($this->getFilesystemLoaders() as $loader) {
|
||||||
if (null !== $name) {
|
$namespaces = $loader->getNamespaces();
|
||||||
$namespace = $this->parseTemplateName($name)[0];
|
if (null !== $name) {
|
||||||
$namespaces = array_intersect([$namespace], $namespaces);
|
$namespace = $this->parseTemplateName($name)[0];
|
||||||
}
|
$namespaces = array_intersect([$namespace], $namespaces);
|
||||||
|
|
||||||
foreach ($namespaces as $namespace) {
|
|
||||||
$paths = array_map([$this, 'getRelativePath'], $loader->getPaths($namespace));
|
|
||||||
|
|
||||||
if (FilesystemLoader::MAIN_NAMESPACE === $namespace) {
|
|
||||||
$namespace = '(None)';
|
|
||||||
} else {
|
|
||||||
$namespace = '@'.$namespace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$loaderPaths[$namespace] = $paths;
|
foreach ($namespaces as $namespace) {
|
||||||
|
$paths = array_map([$this, 'getRelativePath'], $loader->getPaths($namespace));
|
||||||
|
|
||||||
|
if (FilesystemLoader::MAIN_NAMESPACE === $namespace) {
|
||||||
|
$namespace = '(None)';
|
||||||
|
} else {
|
||||||
|
$namespace = '@'.$namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
$loaderPaths[$namespace] = $paths;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $loaderPaths;
|
return $loaderPaths;
|
||||||
@ -437,22 +441,22 @@ EOF
|
|||||||
|
|
||||||
private function findTemplateFiles(string $name): array
|
private function findTemplateFiles(string $name): array
|
||||||
{
|
{
|
||||||
/** @var FilesystemLoader $loader */
|
|
||||||
$loader = $this->twig->getLoader();
|
|
||||||
$files = [];
|
|
||||||
list($namespace, $shortname) = $this->parseTemplateName($name);
|
list($namespace, $shortname) = $this->parseTemplateName($name);
|
||||||
|
|
||||||
foreach ($loader->getPaths($namespace) as $path) {
|
$files = [];
|
||||||
if (!$this->isAbsolutePath($path)) {
|
foreach ($this->getFilesystemLoaders() as $loader) {
|
||||||
$path = $this->projectDir.'/'.$path;
|
foreach ($loader->getPaths($namespace) as $path) {
|
||||||
}
|
if (!$this->isAbsolutePath($path)) {
|
||||||
$filename = $path.'/'.$shortname;
|
$path = $this->projectDir.'/'.$path;
|
||||||
|
}
|
||||||
|
$filename = $path.'/'.$shortname;
|
||||||
|
|
||||||
if (is_file($filename)) {
|
if (is_file($filename)) {
|
||||||
if (false !== $realpath = realpath($filename)) {
|
if (false !== $realpath = realpath($filename)) {
|
||||||
$files[] = $this->getRelativePath($realpath);
|
$files[] = $this->getRelativePath($realpath);
|
||||||
} else {
|
} else {
|
||||||
$files[] = $this->getRelativePath($filename);
|
$files[] = $this->getRelativePath($filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,4 +539,28 @@ EOF
|
|||||||
{
|
{
|
||||||
return strspn($file, '/\\', 0, 1) || (\strlen($file) > 3 && ctype_alpha($file[0]) && ':' === $file[1] && strspn($file, '/\\', 2, 1)) || null !== parse_url($file, PHP_URL_SCHEME);
|
return strspn($file, '/\\', 0, 1) || (\strlen($file) > 3 && ctype_alpha($file[0]) && ':' === $file[1] && strspn($file, '/\\', 2, 1)) || null !== parse_url($file, PHP_URL_SCHEME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return FilesystemLoader[]
|
||||||
|
*/
|
||||||
|
private function getFilesystemLoaders(): array
|
||||||
|
{
|
||||||
|
if (null !== $this->filesystemLoaders) {
|
||||||
|
return $this->filesystemLoaders;
|
||||||
|
}
|
||||||
|
$this->filesystemLoaders = [];
|
||||||
|
|
||||||
|
$loader = $this->twig->getLoader();
|
||||||
|
if ($loader instanceof FilesystemLoader) {
|
||||||
|
$this->filesystemLoaders[] = $loader;
|
||||||
|
} elseif ($loader instanceof ChainLoader) {
|
||||||
|
foreach ($loader->getLoaders() as $l) {
|
||||||
|
if ($l instanceof FilesystemLoader) {
|
||||||
|
$this->filesystemLoaders[] = $l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->filesystemLoaders;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use Symfony\Bridge\Twig\Command\DebugCommand;
|
|||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
use Symfony\Component\Console\Tester\CommandTester;
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
|
use Twig\Loader\ChainLoader;
|
||||||
use Twig\Loader\FilesystemLoader;
|
use Twig\Loader\FilesystemLoader;
|
||||||
|
|
||||||
class DebugCommandTest extends TestCase
|
class DebugCommandTest extends TestCase
|
||||||
@ -279,7 +280,16 @@ TXT
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createCommandTester(array $paths = [], array $bundleMetadata = [], string $defaultPath = null, string $rootDir = null): CommandTester
|
public function testDebugTemplateNameWithChainLoader()
|
||||||
|
{
|
||||||
|
$tester = $this->createCommandTester(['templates/' => null], [], null, null, true);
|
||||||
|
$ret = $tester->execute(['name' => 'base.html.twig'], ['decorated' => false]);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
|
||||||
|
$this->assertContains('[OK]', $tester->getDisplay());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createCommandTester(array $paths = [], array $bundleMetadata = [], string $defaultPath = null, string $rootDir = null, bool $useChainLoader = false): CommandTester
|
||||||
{
|
{
|
||||||
$projectDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures';
|
$projectDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures';
|
||||||
$loader = new FilesystemLoader([], $projectDir);
|
$loader = new FilesystemLoader([], $projectDir);
|
||||||
@ -291,6 +301,10 @@ TXT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($useChainLoader) {
|
||||||
|
$loader = new ChainLoader([$loader]);
|
||||||
|
}
|
||||||
|
|
||||||
$application = new Application();
|
$application = new Application();
|
||||||
$application->add(new DebugCommand(new Environment($loader), $projectDir, $bundleMetadata, $defaultPath, $rootDir));
|
$application->add(new DebugCommand(new Environment($loader), $projectDir, $bundleMetadata, $defaultPath, $rootDir));
|
||||||
$command = $application->find('debug:twig');
|
$command = $application->find('debug:twig');
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^7.1.3",
|
"php": "^7.1.3",
|
||||||
"symfony/contracts": "^1.0.2",
|
"symfony/contracts": "^1.0.2",
|
||||||
"twig/twig": "^1.37.1|^2.6.2"
|
"twig/twig": "^1.38.1|^2.7.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/asset": "~3.4|~4.0",
|
"symfony/asset": "~3.4|~4.0",
|
||||||
|
Reference in New Issue
Block a user