diff --git a/src/Symfony/Bridge/Twig/Command/DebugCommand.php b/src/Symfony/Bridge/Twig/Command/DebugCommand.php index 072022c0a417e..e9d9eda30e05b 100644 --- a/src/Symfony/Bridge/Twig/Command/DebugCommand.php +++ b/src/Symfony/Bridge/Twig/Command/DebugCommand.php @@ -208,8 +208,8 @@ private function displayGeneralText(SymfonyStyle $io, string $filter = null) $io->table(array('Namespace', 'Paths'), $this->buildTableRows($paths)); } - if ($wronBundles = $this->findWrongBundleOverrides()) { - foreach ($this->buildWarningMessages($wronBundles) as $message) { + if ($wrongBundles = $this->findWrongBundleOverrides()) { + foreach ($this->buildWarningMessages($wrongBundles) as $message) { $io->warning($message); } } @@ -253,13 +253,7 @@ private function getLoaderPaths(string $name = null): array } foreach ($namespaces as $namespace) { - $paths = array_map(function ($path) { - if (null !== $this->projectDir && 0 === strpos($path, $this->projectDir)) { - $path = ltrim(substr($path, \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); - } - - return $path; - }, $loader->getPaths($namespace)); + $paths = array_map(array($this, 'getRelativePath'), $loader->getPaths($namespace)); if (FilesystemLoader::MAIN_NAMESPACE === $namespace) { $namespace = '(None)'; @@ -368,53 +362,38 @@ private function findWrongBundleOverrides(): array if ($this->rootDir && $this->projectDir) { $folders = glob($this->rootDir.'/Resources/*/views', GLOB_ONLYDIR); - $relativePath = ltrim(substr($this->rootDir.'/Resources/', \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); - $bundleNames = array_reduce( - $folders, - function ($carry, $absolutePath) use ($relativePath) { - if (0 === strpos($absolutePath, $this->projectDir)) { - $name = basename(\dirname($absolutePath)); - $path = $relativePath.$name; - $carry[$name] = $path; - } + $relativePath = ltrim(substr($this->rootDir.\DIRECTORY_SEPARATOR.'Resources/', \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); + $bundleNames = array_reduce($folders, function ($carry, $absolutePath) use ($relativePath) { + if (0 === strpos($absolutePath, $this->projectDir)) { + $name = basename(\dirname($absolutePath)); + $path = ltrim($relativePath.$name, \DIRECTORY_SEPARATOR); + $carry[$name] = $path; + + @trigger_error(sprintf('Templates directory "%s" is deprecated since Symfony 4.2, use "%s" instead.', $absolutePath, $this->twigDefaultPath.'/bundles/'.$name), E_USER_DEPRECATED); + } - return $carry; - }, - $bundleNames - ); + return $carry; + }, $bundleNames); } if ($this->twigDefaultPath && $this->projectDir) { $folders = glob($this->twigDefaultPath.'/bundles/*', GLOB_ONLYDIR); - $relativePath = ltrim(substr($this->twigDefaultPath.'/bundles', \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); - $bundleNames = array_reduce( - $folders, - function ($carry, $absolutePath) use ($relativePath) { - if (0 === strpos($absolutePath, $this->projectDir)) { - $path = ltrim(substr($absolutePath, \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); - $name = ltrim(substr($path, \strlen($relativePath)), \DIRECTORY_SEPARATOR); - $carry[$name] = $path; - } - - return $carry; - }, - $bundleNames - ); - } - - if (\count($bundleNames)) { - $notFoundBundles = array_diff_key($bundleNames, $this->bundlesMetadata); - if (\count($notFoundBundles)) { - $alternatives = array(); - foreach ($notFoundBundles as $notFoundBundle => $path) { - $alternatives[$path] = array(); - foreach ($this->bundlesMetadata as $name => $bundle) { - $lev = levenshtein($notFoundBundle, $name); - if ($lev <= \strlen($notFoundBundle) / 3 || false !== strpos($name, $notFoundBundle)) { - $alternatives[$path][] = $name; - } - } + $relativePath = ltrim(substr($this->twigDefaultPath.'/bundles/', \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); + $bundleNames = array_reduce($folders, function ($carry, $absolutePath) use ($relativePath) { + if (0 === strpos($absolutePath, $this->projectDir)) { + $name = basename($absolutePath); + $path = ltrim($relativePath.$name, \DIRECTORY_SEPARATOR); + $carry[$name] = $path; } + + return $carry; + }, $bundleNames); + } + + if ($notFoundBundles = array_diff_key($bundleNames, $this->bundlesMetadata)) { + $alternatives = array(); + foreach ($notFoundBundles as $notFoundBundle => $path) { + $alternatives[$path] = $this->findAlternatives($notFoundBundle, array_keys($this->bundlesMetadata)); } } diff --git a/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php index ed3fea871e68f..e648a52d84a73 100644 --- a/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php @@ -42,6 +42,52 @@ public function testFilterAndJsonFormatOptions() $this->assertEquals($expected, json_decode($tester->getDisplay(true), true)); } + public function testWarningsWrongBundleOverriding() + { + $bundleMetadata = array( + 'TwigBundle' => 'vendor/twig-bundle/', + 'WebProfilerBundle' => 'vendor/web-profiler-bundle/', + ); + $defaultPath = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'templates'; + + $tester = $this->createCommandTester(array(), $bundleMetadata, $defaultPath); + $ret = $tester->execute(array('--filter' => 'unknown', '--format' => 'json'), array('decorated' => false)); + + $expected = array('warnings' => array( + 'Path "templates/bundles/UnknownBundle" not matching any bundle found', + 'Path "templates/bundles/WebProfileBundle" not matching any bundle found, did you mean "WebProfilerBundle"?', + )); + + $this->assertEquals(0, $ret, 'Returns 0 in case of success'); + $this->assertEquals($expected, json_decode($tester->getDisplay(true), true)); + } + + /** + * @group legacy + * @expectedDeprecation Templates directory "%sResources/BarBundle/views" is deprecated since Symfony 4.2, use "%stemplates/bundles/BarBundle" instead. + */ + public function testDeprecationForWrongBundleOverridingInLegacyPath() + { + $bundleMetadata = array( + 'TwigBundle' => 'vendor/twig-bundle/', + 'WebProfilerBundle' => 'vendor/web-profiler-bundle/', + ); + $defaultPath = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'templates'; + $rootDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'; + + $tester = $this->createCommandTester(array(), $bundleMetadata, $defaultPath, $rootDir); + $ret = $tester->execute(array('--filter' => 'unknown', '--format' => 'json'), array('decorated' => false)); + + $expected = array('warnings' => array( + 'Path "Resources/BarBundle" not matching any bundle found', + 'Path "templates/bundles/UnknownBundle" not matching any bundle found', + 'Path "templates/bundles/WebProfileBundle" not matching any bundle found, did you mean "WebProfilerBundle"?', + )); + + $this->assertEquals(0, $ret, 'Returns 0 in case of success'); + $this->assertEquals($expected, json_decode($tester->getDisplay(true), true)); + } + /** * @expectedException \Symfony\Component\Console\Exception\InvalidArgumentException * @expectedExceptionMessage Malformed namespaced template name "@foo" (expecting "@namespace/template_name"). @@ -233,7 +279,7 @@ public function getDebugTemplateNameTestData() ); } - private function createCommandTester(array $paths = array()): CommandTester + private function createCommandTester(array $paths = array(), array $bundleMetadata = array(), string $defaultPath = null, string $rootDir = null): CommandTester { $projectDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'; $loader = new FilesystemLoader(array(), $projectDir); @@ -246,7 +292,7 @@ private function createCommandTester(array $paths = array()): CommandTester } $application = new Application(); - $application->add(new DebugCommand(new Environment($loader), $projectDir)); + $application->add(new DebugCommand(new Environment($loader), $projectDir, $bundleMetadata, $defaultPath, $rootDir)); $command = $application->find('debug:twig'); return new CommandTester($command); diff --git a/src/Symfony/Bridge/Twig/Tests/Fixtures/Resources/BarBundle/views/base.html.twig b/src/Symfony/Bridge/Twig/Tests/Fixtures/Resources/BarBundle/views/base.html.twig new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/Symfony/Bridge/Twig/Tests/Fixtures/templates/bundles/UnknownBundle/base.html.twig b/src/Symfony/Bridge/Twig/Tests/Fixtures/templates/bundles/UnknownBundle/base.html.twig new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/Symfony/Bridge/Twig/Tests/Fixtures/templates/bundles/WebProfileBundle/Profiler/base.html.twig b/src/Symfony/Bridge/Twig/Tests/Fixtures/templates/bundles/WebProfileBundle/Profiler/base.html.twig new file mode 100644 index 0000000000000..e69de29bb2d1d