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\Finder\Finder;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\ChainLoader;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
|
||||
/**
|
||||
@ -36,6 +37,7 @@ class DebugCommand extends Command
|
||||
private $bundlesMetadata;
|
||||
private $twigDefaultPath;
|
||||
private $rootDir;
|
||||
private $filesystemLoaders;
|
||||
|
||||
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');
|
||||
$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));
|
||||
}
|
||||
|
||||
@ -150,9 +152,11 @@ EOF
|
||||
$message = 'No template paths configured for your application';
|
||||
} else {
|
||||
$message = sprintf('No template paths configured for "@%s" namespace', $namespace);
|
||||
$namespaces = $this->twig->getLoader()->getNamespaces();
|
||||
foreach ($this->findAlternatives($namespace, $namespaces) as $namespace) {
|
||||
$alternatives[] = '@'.$namespace;
|
||||
foreach ($this->getFilesystemLoaders() as $loader) {
|
||||
$namespaces = $loader->getNamespaces();
|
||||
foreach ($this->findAlternatives($namespace, $namespaces) as $namespace) {
|
||||
$alternatives[] = '@'.$namespace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,25 +247,25 @@ EOF
|
||||
|
||||
private function getLoaderPaths(string $name = null): array
|
||||
{
|
||||
/** @var FilesystemLoader $loader */
|
||||
$loader = $this->twig->getLoader();
|
||||
$loaderPaths = [];
|
||||
$namespaces = $loader->getNamespaces();
|
||||
if (null !== $name) {
|
||||
$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;
|
||||
foreach ($this->getFilesystemLoaders() as $loader) {
|
||||
$namespaces = $loader->getNamespaces();
|
||||
if (null !== $name) {
|
||||
$namespace = $this->parseTemplateName($name)[0];
|
||||
$namespaces = array_intersect([$namespace], $namespaces);
|
||||
}
|
||||
|
||||
$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;
|
||||
@ -437,22 +441,22 @@ EOF
|
||||
|
||||
private function findTemplateFiles(string $name): array
|
||||
{
|
||||
/** @var FilesystemLoader $loader */
|
||||
$loader = $this->twig->getLoader();
|
||||
$files = [];
|
||||
list($namespace, $shortname) = $this->parseTemplateName($name);
|
||||
|
||||
foreach ($loader->getPaths($namespace) as $path) {
|
||||
if (!$this->isAbsolutePath($path)) {
|
||||
$path = $this->projectDir.'/'.$path;
|
||||
}
|
||||
$filename = $path.'/'.$shortname;
|
||||
$files = [];
|
||||
foreach ($this->getFilesystemLoaders() as $loader) {
|
||||
foreach ($loader->getPaths($namespace) as $path) {
|
||||
if (!$this->isAbsolutePath($path)) {
|
||||
$path = $this->projectDir.'/'.$path;
|
||||
}
|
||||
$filename = $path.'/'.$shortname;
|
||||
|
||||
if (is_file($filename)) {
|
||||
if (false !== $realpath = realpath($filename)) {
|
||||
$files[] = $this->getRelativePath($realpath);
|
||||
} else {
|
||||
$files[] = $this->getRelativePath($filename);
|
||||
if (is_file($filename)) {
|
||||
if (false !== $realpath = realpath($filename)) {
|
||||
$files[] = $this->getRelativePath($realpath);
|
||||
} else {
|
||||
$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 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\Tester\CommandTester;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\ChainLoader;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
|
||||
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';
|
||||
$loader = new FilesystemLoader([], $projectDir);
|
||||
@ -291,6 +301,10 @@ TXT
|
||||
}
|
||||
}
|
||||
|
||||
if ($useChainLoader) {
|
||||
$loader = new ChainLoader([$loader]);
|
||||
}
|
||||
|
||||
$application = new Application();
|
||||
$application->add(new DebugCommand(new Environment($loader), $projectDir, $bundleMetadata, $defaultPath, $rootDir));
|
||||
$command = $application->find('debug:twig');
|
||||
|
@ -18,7 +18,7 @@
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"symfony/contracts": "^1.0.2",
|
||||
"twig/twig": "^1.37.1|^2.6.2"
|
||||
"twig/twig": "^1.38.1|^2.7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/asset": "~3.4|~4.0",
|
||||
|
Reference in New Issue
Block a user