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.                    LOWER(HEX(`app`.`integration_id`)) AS integrationId,
  65.                    `app`.`version` AS appVersion
  66.             FROM `script`
  67.             LEFT JOIN `app` ON `script`.`app_id` = `app`.`id`
  68.             WHERE `script`.`hook` != 'include'
  69.             ORDER BY `app`.`created_at`, `app`.`id`, `script`.`name`
  70.         ");
  71.         $includes $this->connection->fetchAllAssociative("
  72.             SELECT LOWER(HEX(`script`.`app_id`)) as `app_id`,
  73.                    `script`.`name` AS name,
  74.                    `script`.`script` AS script,
  75.                    `app`.`name` AS appName,
  76.                    LOWER(HEX(`app`.`integration_id`)) AS integrationId,
  77.                    IFNULL(`script`.`updated_at`, `script`.`created_at`) AS lastModified
  78.             FROM `script`
  79.             LEFT JOIN `app` ON `script`.`app_id` = `app`.`id`
  80.             WHERE `script`.`hook` = 'include'
  81.             ORDER BY `app`.`created_at`, `app`.`id`, `script`.`name`
  82.         ");
  83.         $allIncludes FetchModeHelper::group($includes);
  84.         $executableScripts = [];
  85.         /** @var array $script */
  86.         foreach ($scripts as $script) {
  87.             $appId $script['app_id'];
  88.             $includes $allIncludes[$appId] ?? [];
  89.             $dates array_merge([$script['lastModified']], array_column($includes'lastModified'));
  90.             /** @var \DateTimeInterface $lastModified */
  91.             $lastModified = new \DateTimeImmutable(max($dates));
  92.             /** @var string $cachePrefix */
  93.             $cachePrefix $script['appName'] ? md5($script['appName'] . $script['appVersion']) : EnvironmentHelper::getVariable('INSTANCE_ID''');
  94.             $includes array_map(function (array $script) use ($appId) {
  95.                 $script['app_id'] = $appId;
  96.                 return new Script(
  97.                     $script['name'],
  98.                     $script['script'],
  99.                     new \DateTimeImmutable($script['lastModified']),
  100.                     $this->getAppInfo($script)
  101.                 );
  102.             }, $includes);
  103.             $options = [];
  104.             if (!$this->debug) {
  105.                 $options['cache'] = new FilesystemCache($this->cacheDir '/' $cachePrefix);
  106.             } else {
  107.                 $options['debug'] = true;
  108.             }
  109.             $executableScripts[$script['hook']][] = new Script(
  110.                 $script['scriptName'],
  111.                 $script['script'],
  112.                 $lastModified,
  113.                 $this->getAppInfo($script),
  114.                 $options,
  115.                 $includes
  116.             );
  117.         }
  118.         return $executableScripts;
  119.     }
  120.     private function getAppInfo(array $script): ?ScriptAppInformation
  121.     {
  122.         if (!$script['app_id'] || !$script['appName'] || !$script['integrationId']) {
  123.             return null;
  124.         }
  125.         return new ScriptAppInformation(
  126.             $script['app_id'],
  127.             $script['appName'],
  128.             $script['integrationId']
  129.         );
  130.     }
  131. }