vendor/shopware/core/Framework/Adapter/Twig/EntityTemplateLoader.php line 58

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Adapter\Twig;
  3. use Doctrine\DBAL\Connection;
  4. use Shopware\Core\DevOps\Environment\EnvironmentHelper;
  5. use Shopware\Core\Framework\DependencyInjection\CompilerPass\TwigLoaderConfigCompilerPass;
  6. use Shopware\Core\Framework\Feature;
  7. use Shopware\Core\Framework\Log\Package;
  8. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  9. use Symfony\Contracts\Service\ResetInterface;
  10. use Twig\Error\LoaderError;
  11. use Twig\Loader\LoaderInterface;
  12. use Twig\Source;
  13. /**
  14.  * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
  15.  */
  16. #[Package('core')]
  17. class EntityTemplateLoader implements LoaderInterfaceEventSubscriberInterfaceResetInterface
  18. {
  19.     /**
  20.      * @var array<string, array<string, array{template: string, updatedAt: \DateTimeInterface|null}|null>>
  21.      */
  22.     private array $databaseTemplateCache = [];
  23.     private Connection $connection;
  24.     private string $environment;
  25.     /**
  26.      * @internal
  27.      */
  28.     public function __construct(Connection $connectionstring $environment)
  29.     {
  30.         $this->connection $connection;
  31.         $this->environment $environment;
  32.     }
  33.     public static function getSubscribedEvents(): array
  34.     {
  35.         return ['app_template.written' => 'reset'];
  36.     }
  37.     /**
  38.      * @deprecated tag:v6.5.0 will be removed, use `reset()` instead
  39.      */
  40.     public function clearInternalCache(): void
  41.     {
  42.         Feature::triggerDeprecationOrThrow(
  43.             'v6.5.0.0',
  44.             Feature::deprecatedMethodMessage(__CLASS____METHOD__'v6.5.0.0''reset()')
  45.         );
  46.         $this->reset();
  47.     }
  48.     public function reset(): void
  49.     {
  50.         $this->databaseTemplateCache = [];
  51.     }
  52.     public function getSourceContext(string $name): Source
  53.     {
  54.         $template $this->findDatabaseTemplate($name);
  55.         if (!$template) {
  56.             throw new LoaderError(sprintf('Template "%s" is not defined.'$name));
  57.         }
  58.         return new Source($template['template'], $name);
  59.     }
  60.     public function getCacheKey(string $name): string
  61.     {
  62.         return $name;
  63.     }
  64.     public function isFresh(string $nameint $time): bool
  65.     {
  66.         $template $this->findDatabaseTemplate($name);
  67.         if (!$template) {
  68.             return false;
  69.         }
  70.         return $template['updatedAt'] === null || $template['updatedAt']->getTimestamp() < $time;
  71.     }
  72.     /**
  73.      * @return bool
  74.      */
  75.     public function exists(string $name)
  76.     {
  77.         $template $this->findDatabaseTemplate($name);
  78.         if (!$template) {
  79.             return false;
  80.         }
  81.         return true;
  82.     }
  83.     /**
  84.      * @return array{template: string, updatedAt: \DateTimeInterface|null}|null
  85.      */
  86.     private function findDatabaseTemplate(string $name): ?array
  87.     {
  88.         if (EnvironmentHelper::getVariable('DISABLE_EXTENSIONS'false)) {
  89.             return null;
  90.         }
  91.         /*
  92.          * In dev env app templates are directly loaded over the filesystem
  93.          * @see TwigLoaderConfigCompilerPass::addAppTemplatePaths()
  94.          */
  95.         if ($this->environment === 'dev') {
  96.             return null;
  97.         }
  98.         $templateName $this->splitTemplateName($name);
  99.         $namespace $templateName['namespace'];
  100.         $path $templateName['path'];
  101.         if (empty($this->databaseTemplateCache)) {
  102.             /** @var array<array{path: string, template: string, updatedAt: string|null, namespace: string}> $templates */
  103.             $templates $this->connection->fetchAllAssociative('
  104.                 SELECT
  105.                     `app_template`.`path` AS `path`,
  106.                     `app_template`.`template` AS `template`,
  107.                     `app_template`.`updated_at` AS `updatedAt`,
  108.                     `app`.`name` AS `namespace`
  109.                 FROM `app_template`
  110.                 INNER JOIN `app` ON `app_template`.`app_id` = `app`.`id`
  111.                 WHERE `app_template`.`active` = 1 AND `app`.`active` = 1
  112.             ');
  113.             foreach ($templates as $template) {
  114.                 $this->databaseTemplateCache[$template['path']][$template['namespace']] = [
  115.                     'template' => $template['template'],
  116.                     'updatedAt' => $template['updatedAt'] ? new \DateTimeImmutable($template['updatedAt']) : null,
  117.                 ];
  118.             }
  119.         }
  120.         if (\array_key_exists($path$this->databaseTemplateCache) && \array_key_exists($namespace$this->databaseTemplateCache[$path])) {
  121.             return $this->databaseTemplateCache[$path][$namespace];
  122.         }
  123.         /** @deprecated tag:v6.5.0 - only for intermediate backwards compatibility */
  124.         if (
  125.             \array_key_exists('../' $path$this->databaseTemplateCache)
  126.             && \array_key_exists($namespace$this->databaseTemplateCache['../' $path])
  127.         ) {
  128.             return $this->databaseTemplateCache['../' $path][$namespace];
  129.         }
  130.         // we have already loaded all DB templates
  131.         // if the namespace is not included return null
  132.         return $this->databaseTemplateCache[$path][$namespace] = null;
  133.     }
  134.     /**
  135.      * @return array{namespace: string, path: string}
  136.      */
  137.     private function splitTemplateName(string $template): array
  138.     {
  139.         // remove static template inheritance prefix
  140.         if (mb_strpos($template'@') !== 0) {
  141.             return ['path' => $template'namespace' => ''];
  142.         }
  143.         // remove "@"
  144.         $template mb_substr($template1);
  145.         $template explode('/'$template);
  146.         $namespace array_shift($template);
  147.         $template implode('/'$template);
  148.         return ['path' => $template'namespace' => $namespace];
  149.     }
  150. }