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

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