TemplateIterator.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\TwigBundle;
  11. use Symfony\Component\Finder\Finder;
  12. use Symfony\Component\HttpKernel\KernelInterface;
  13. /**
  14. * Iterator for all templates in bundles and in the application Resources directory.
  15. *
  16. * @author Fabien Potencier <fabien@symfony.com>
  17. *
  18. * @internal
  19. */
  20. class TemplateIterator implements \IteratorAggregate
  21. {
  22. private $kernel;
  23. private $templates;
  24. private $paths;
  25. private $defaultPath;
  26. /**
  27. * @param array $paths Additional Twig paths to warm
  28. * @param string|null $defaultPath The directory where global templates can be stored
  29. */
  30. public function __construct(KernelInterface $kernel, array $paths = [], string $defaultPath = null)
  31. {
  32. $this->kernel = $kernel;
  33. $this->paths = $paths;
  34. $this->defaultPath = $defaultPath;
  35. }
  36. public function getIterator(): \Traversable
  37. {
  38. if (null !== $this->templates) {
  39. return $this->templates;
  40. }
  41. $templates = null !== $this->defaultPath ? $this->findTemplatesInDirectory($this->defaultPath, null, ['bundles']) : [];
  42. foreach ($this->kernel->getBundles() as $bundle) {
  43. $name = $bundle->getName();
  44. if ('Bundle' === substr($name, -6)) {
  45. $name = substr($name, 0, -6);
  46. }
  47. $bundleTemplatesDir = is_dir($bundle->getPath().'/Resources/views') ? $bundle->getPath().'/Resources/views' : $bundle->getPath().'/templates';
  48. $templates = array_merge(
  49. $templates,
  50. $this->findTemplatesInDirectory($bundleTemplatesDir, $name),
  51. null !== $this->defaultPath ? $this->findTemplatesInDirectory($this->defaultPath.'/bundles/'.$bundle->getName(), $name) : []
  52. );
  53. }
  54. foreach ($this->paths as $dir => $namespace) {
  55. $templates = array_merge($templates, $this->findTemplatesInDirectory($dir, $namespace));
  56. }
  57. return $this->templates = new \ArrayIterator(array_unique($templates));
  58. }
  59. /**
  60. * Find templates in the given directory.
  61. *
  62. * @return string[]
  63. */
  64. private function findTemplatesInDirectory(string $dir, string $namespace = null, array $excludeDirs = []): array
  65. {
  66. if (!is_dir($dir)) {
  67. return [];
  68. }
  69. $templates = [];
  70. foreach (Finder::create()->files()->followLinks()->in($dir)->exclude($excludeDirs) as $file) {
  71. $templates[] = (null !== $namespace ? '@'.$namespace.'/' : '').str_replace('\\', '/', $file->getRelativePathname());
  72. }
  73. return $templates;
  74. }
  75. }