vendor/shopware/core/Framework/Script/Execution/ScriptLoader.php line 92
<?php declare(strict_types=1);namespace Shopware\Core\Framework\Script\Execution;use Doctrine\DBAL\Connection;use Shopware\Core\DevOps\Environment\EnvironmentHelper;use Shopware\Core\Framework\Adapter\Cache\CacheCompressor;use Shopware\Core\Framework\App\Lifecycle\Persister\ScriptPersister;use Shopware\Core\Framework\DataAbstractionLayer\Doctrine\FetchModeHelper;use Shopware\Core\Framework\Log\Package;use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Twig\Cache\FilesystemCache;/*** @internal only for use by the app-system** @phpstan-type ScriptInfo = array{app_id: ?string, scriptName: string, script: string, hook: string, appName: ?string, integrationId: ?string, lastModified: string, appVersion: string, active: bool}* @phpstan-type IncludesInfo = array{app_id: ?string, name: string, script: string, appName: ?string, integrationId: ?string, lastModified: string}*/#[Package('core')]class ScriptLoader implements EventSubscriberInterface{final public const CACHE_KEY = 'shopware-app-scripts';private readonly string $cacheDir;public function __construct(private readonly Connection $connection,private readonly ScriptPersister $scriptPersister,private readonly TagAwareAdapterInterface $cache,string $cacheDir,private readonly bool $debug) {$this->cacheDir = $cacheDir . '/scripts';}public static function getSubscribedEvents(): array{return ['script.written' => 'invalidateCache'];}/*** @return Script[]*/public function get(string $hook): array{$cacheItem = $this->cache->getItem(self::CACHE_KEY);if ($cacheItem->isHit() && $cacheItem->get() && !$this->debug) {return CacheCompressor::uncompress($cacheItem)[$hook] ?? [];}$scripts = $this->load();$cacheItem = CacheCompressor::compress($cacheItem, $scripts);$this->cache->save($cacheItem);return $scripts[$hook] ?? [];}public function invalidateCache(): void{$this->cache->deleteItem(self::CACHE_KEY);}/*** @return array<string, list<Script>>*/private function load(): array{if ($this->debug) {$this->scriptPersister->refresh();}/** @var list<ScriptInfo> $scripts */$scripts = $this->connection->fetchAllAssociative('SELECT LOWER(HEX(`script`.`app_id`)) as `app_id`,`script`.`name` AS scriptName,`script`.`script` AS script,`script`.`hook` AS hook,IFNULL(`script`.`updated_at`, `script`.`created_at`) AS lastModified,`app`.`name` AS appName,LOWER(HEX(`app`.`integration_id`)) AS integrationId,`app`.`version` AS appVersion,`script`.`active` AS activeFROM `script`LEFT JOIN `app` ON `script`.`app_id` = `app`.`id`WHERE `script`.`hook` != \'include\'ORDER BY `app`.`created_at`, `app`.`id`, `script`.`name`');$includes = $this->connection->fetchAllAssociative('SELECT LOWER(HEX(`script`.`app_id`)) as `app_id`,`script`.`name` AS name,`script`.`script` AS script,`app`.`name` AS appName,LOWER(HEX(`app`.`integration_id`)) AS integrationId,IFNULL(`script`.`updated_at`, `script`.`created_at`) AS lastModifiedFROM `script`LEFT JOIN `app` ON `script`.`app_id` = `app`.`id`WHERE `script`.`hook` = \'include\'ORDER BY `app`.`created_at`, `app`.`id`, `script`.`name`');/** @var array<string, list<IncludesInfo>> $allIncludes */$allIncludes = FetchModeHelper::group($includes);$executableScripts = [];foreach ($scripts as $script) {$appId = $script['app_id'];$includes = $allIncludes[$appId] ?? [];$dates = [...[$script['lastModified']], ...array_column($includes, 'lastModified')];/** @var \DateTimeInterface $lastModified */$lastModified = new \DateTimeImmutable(max($dates));/** @var string $cachePrefix */$cachePrefix = $script['appName'] ? md5($script['appName'] . $script['appVersion']) : EnvironmentHelper::getVariable('INSTANCE_ID', '');$includes = array_map(function (array $script) use ($appId) {$script['app_id'] = $appId;return new Script($script['name'],$script['script'],new \DateTimeImmutable($script['lastModified']),$this->getAppInfo($script));}, $includes);$options = [];if (!$this->debug) {$options['cache'] = new FilesystemCache($this->cacheDir . '/' . $cachePrefix);} else {$options['debug'] = true;}$executableScripts[$script['hook']][] = new Script($script['scriptName'],$script['script'],$lastModified,$this->getAppInfo($script),$options,$includes,(bool) $script['active']);}return $executableScripts;}/*** @param ScriptInfo|IncludesInfo $script*/private function getAppInfo(array $script): ?ScriptAppInformation{if (!$script['app_id'] || !$script['appName'] || !$script['integrationId']) {return null;}return new ScriptAppInformation($script['app_id'],$script['appName'],$script['integrationId']);}}