vendor/contao/core-bundle/src/Twig/Loader/ContaoFilesystemLoaderWarmer.php line 92

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of Contao.
  5.  *
  6.  * (c) Leo Feyer
  7.  *
  8.  * @license LGPL-3.0-or-later
  9.  */
  10. namespace Contao\CoreBundle\Twig\Loader;
  11. use Contao\CoreBundle\Twig\ContaoTwigUtil;
  12. use Symfony\Component\Filesystem\Exception\IOException;
  13. use Symfony\Component\Filesystem\Filesystem;
  14. use Symfony\Component\Filesystem\Path;
  15. use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
  16. use Symfony\Component\HttpKernel\Event\RequestEvent;
  17. /**
  18.  * @experimental
  19.  */
  20. class ContaoFilesystemLoaderWarmer implements CacheWarmerInterface
  21. {
  22.     private ContaoFilesystemLoader $loader;
  23.     private TemplateLocator $templateLocator;
  24.     private string $projectDir;
  25.     private string $cacheDir;
  26.     private string $environment;
  27.     private ?Filesystem $filesystem;
  28.     public function __construct(ContaoFilesystemLoader $contaoFilesystemLoader, TemplateLocator $templateLocator, string $projectDir, string $cacheDir, string $environment, Filesystem $filesystem = null)
  29.     {
  30.         $this->loader = $contaoFilesystemLoader;
  31.         $this->templateLocator = $templateLocator;
  32.         $this->projectDir = $projectDir;
  33.         $this->cacheDir = $cacheDir;
  34.         $this->environment = $environment;
  35.         $this->filesystem = $filesystem;
  36.     }
  37.     public function warmUp(string $cacheDir = null): array
  38.     {
  39.         // Theme paths
  40.         $themePaths = $this->templateLocator->findThemeDirectories();
  41.         foreach ($themePaths as $slug => $path) {
  42.             $this->loader->addPath($path, "Contao_Theme_$slug", true);
  43.         }
  44.         // Global templates path
  45.         $globalTemplatesPath = Path::join($this->projectDir, 'templates');
  46.         $this->loader->addPath($globalTemplatesPath);
  47.         $this->loader->addPath($globalTemplatesPath, 'Contao_Global', true);
  48.         // Bundle paths (including App)
  49.         foreach ($this->templateLocator->findResourcesPaths() as $name => $resourcesPaths) {
  50.             foreach ($resourcesPaths as $path) {
  51.                 $this->loader->addPath($path);
  52.                 $this->loader->addPath($path, "Contao_$name", true);
  53.             }
  54.         }
  55.         $this->loader->buildInheritanceChains();
  56.         $this->loader->persist();
  57.         if ('dev' === $this->environment) {
  58.             $this->writeIdeAutoCompletionMapping($cacheDir ?? $this->cacheDir);
  59.         }
  60.         return [];
  61.     }
  62.     public function isOptional(): bool
  63.     {
  64.         return false;
  65.     }
  66.     public function refresh(): void
  67.     {
  68.         $this->loader->clear();
  69.         $this->warmUp();
  70.     }
  71.     /**
  72.      * Auto refresh in dev mode.
  73.      */
  74.     public function onKernelRequest(RequestEvent $event): void
  75.     {
  76.         if ('dev' === $this->environment && $event->isMainRequest()) {
  77.             $this->refresh();
  78.         }
  79.     }
  80.     /**
  81.      * Writes an "ide-twig.json" file with path mapping information that
  82.      * enables IDE auto-completion for all our dynamic namespaces.
  83.      */
  84.     private function writeIdeAutoCompletionMapping(string $cacheDir): void
  85.     {
  86.         $mappings = [];
  87.         $targetDir = Path::join($cacheDir, 'contao');
  88.         foreach ($this->loader->getInheritanceChains() as $chain) {
  89.             foreach ($chain as $path => $name) {
  90.                 $mappings[Path::getDirectory(Path::makeRelative($path, $targetDir))] = ContaoTwigUtil::parseContaoName($name)[0];
  91.             }
  92.         }
  93.         $data = [];
  94.         foreach ($mappings as $path => $namespace) {
  95.             $data['namespaces'][] = ['namespace' => 'Contao', 'path' => $path];
  96.             $data['namespaces'][] = compact('namespace', 'path');
  97.         }
  98.         if (null === $this->filesystem) {
  99.             $this->filesystem = new Filesystem();
  100.         }
  101.         try {
  102.             $this->filesystem->dumpFile(
  103.                 Path::join($targetDir, 'ide-twig.json'),
  104.                 json_encode($data, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES)
  105.             );
  106.         } catch (IOException $e) {
  107.             // ignore
  108.         }
  109.     }
  110. }