vendor/shopware/core/Framework/Script/Execution/ScriptLoader.php line 63

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Script\Execution;
  3. use Doctrine\DBAL\Connection;
  4. use Shopware\Core\DevOps\Environment\EnvironmentHelper;
  5. use Shopware\Core\Framework\Adapter\Cache\CacheCompressor;
  6. use Shopware\Core\Framework\App\Lifecycle\Persister\ScriptPersister;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Doctrine\FetchModeHelper;
  8. use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use Twig\Cache\FilesystemCache;
  11. /**
  12.  * @internal only for use by the app-system
  13.  */
  14. class ScriptLoader implements EventSubscriberInterface
  15. {
  16.     public const CACHE_KEY 'shopware-app-scripts';
  17.     private Connection $connection;
  18.     private string $cacheDir;
  19.     private ScriptPersister $scriptPersister;
  20.     private bool $debug;
  21.     private TagAwareAdapterInterface $cache;
  22.     public function __construct(Connection $connectionScriptPersister $scriptPersisterTagAwareAdapterInterface $cachestring $cacheDirbool $debug)
  23.     {
  24.         $this->connection $connection;
  25.         $this->cacheDir $cacheDir '/twig/scripts';
  26.         $this->scriptPersister $scriptPersister;
  27.         $this->debug $debug;
  28.         $this->cache $cache;
  29.     }
  30.     public static function getSubscribedEvents(): array
  31.     {
  32.         return ['script.written' => 'invalidateCache'];
  33.     }
  34.     /**
  35.      * @return Script[]
  36.      */
  37.     public function get(string $hook): array
  38.     {
  39.         $cacheItem $this->cache->getItem(self::CACHE_KEY);
  40.         if ($cacheItem->isHit() && $cacheItem->get() && !$this->debug) {
  41.             return CacheCompressor::uncompress($cacheItem)[$hook] ?? [];
  42.         }
  43.         $scripts $this->load();
  44.         $cacheItem CacheCompressor::compress($cacheItem$scripts);
  45.         $this->cache->save($cacheItem);
  46.         return $scripts[$hook] ?? [];
  47.     }
  48.     public function invalidateCache(): void
  49.     {
  50.         $this->cache->deleteItem(self::CACHE_KEY);
  51.     }
  52.     private function load(): array
  53.     {
  54.         if ($this->debug) {
  55.             $this->scriptPersister->refresh();
  56.         }
  57.         $scripts $this->connection->fetchAllAssociative("
  58.             SELECT LOWER(HEX(`script`.`app_id`)) as `app_id`,
  59.                    `script`.`name` AS scriptName,
  60.                    `script`.`script` AS script,
  61.                    `script`.`hook` AS hook,
  62.                    IFNULL(`script`.`updated_at`, `script`.`created_at`) AS lastModified,
  63.                    `app`.`name` AS appName,
  64.                    `app`.`version` AS appVersion
  65.             FROM `script`
  66.             LEFT JOIN `app` ON `script`.`app_id` = `app`.`id`
  67.             WHERE `script`.`hook` != 'include'
  68.             ORDER BY `app`.`created_at`, `app`.`id`, `script`.`name`
  69.         ");
  70.         $includes $this->connection->fetchAllAssociative("
  71.             SELECT LOWER(HEX(`script`.`app_id`)) as `app_id`,
  72.                    `script`.`name` AS name,
  73.                    `script`.`script` AS script,
  74.                    IFNULL(`script`.`updated_at`, `script`.`created_at`) AS lastModified
  75.             FROM `script`
  76.             LEFT JOIN `app` ON `script`.`app_id` = `app`.`id`
  77.             WHERE `script`.`hook` = 'include'
  78.             ORDER BY `app`.`created_at`, `app`.`id`, `script`.`name`
  79.         ");
  80.         $allIncludes FetchModeHelper::group($includes);
  81.         $executableScripts = [];
  82.         /** @var array $script */
  83.         foreach ($scripts as $script) {
  84.             $appId $script['app_id'];
  85.             $includes $allIncludes[$appId] ?? [];
  86.             $dates array_merge([$script['lastModified']], array_column($includes'lastModified'));
  87.             /** @var \DateTimeInterface $lastModified */
  88.             $lastModified = new \DateTimeImmutable(max($dates));
  89.             /** @var string $cachePrefix */
  90.             $cachePrefix $script['appName'] ? md5($script['appName'] . $script['appVersion']) : EnvironmentHelper::getVariable('INSTANCE_ID''');
  91.             $includes array_map(function (array $script) use ($appId) {
  92.                 return new Script(
  93.                     $script['name'],
  94.                     $script['script'],
  95.                     new \DateTimeImmutable($script['lastModified']),
  96.                     $appId
  97.                 );
  98.             }, $includes);
  99.             $options = [];
  100.             if (!$this->debug) {
  101.                 $options['cache'] = new FilesystemCache($this->cacheDir '/' $cachePrefix);
  102.             } else {
  103.                 $options['debug'] = true;
  104.             }
  105.             $executableScripts[$script['hook']][] = new Script(
  106.                 $script['scriptName'],
  107.                 $script['script'],
  108.                 $lastModified,
  109.                 $appId,
  110.                 $options,
  111.                 $includes
  112.             );
  113.         }
  114.         return $executableScripts;
  115.     }
  116. }