vendor/shopware/core/Framework/App/Lifecycle/Persister/ScriptPersister.php line 106

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\App\Lifecycle\Persister;
  3. use Shopware\Core\Framework\App\AppEntity;
  4. use Shopware\Core\Framework\App\Lifecycle\ScriptFileReaderInterface;
  5. use Shopware\Core\Framework\Context;
  6. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  9. use Shopware\Core\Framework\Log\Package;
  10. use Shopware\Core\Framework\Script\ScriptCollection;
  11. use Shopware\Core\Framework\Script\ScriptEntity;
  12. /**
  13.  * @internal only for use by the app-system
  14.  */
  15. #[Package('core')]
  16. class ScriptPersister
  17. {
  18.     public function __construct(
  19.         private readonly ScriptFileReaderInterface $scriptReader,
  20.         private readonly EntityRepository $scriptRepository,
  21.         private readonly EntityRepository $appRepository
  22.     ) {
  23.     }
  24.     public function updateScripts(string $appIdContext $context): void
  25.     {
  26.         $app $this->getAppWithExistingScripts($appId$context);
  27.         /** @var ScriptCollection $existingScripts */
  28.         $existingScripts $app->getScripts();
  29.         $scriptPaths $this->scriptReader->getScriptPathsForApp($app->getPath());
  30.         $upserts = [];
  31.         foreach ($scriptPaths as $scriptPath) {
  32.             $payload = [
  33.                 'script' => $this->scriptReader->getScriptContent($scriptPath$app->getPath()),
  34.             ];
  35.             /** @var ScriptEntity|null $existing */
  36.             $existing $existingScripts->filterByProperty('name'$scriptPath)->first();
  37.             if ($existing) {
  38.                 $existingScripts->remove($existing->getId());
  39.                 if ($existing->getScript() === $payload['script']) {
  40.                     // Don't update DB when content is identical
  41.                     continue;
  42.                 }
  43.                 $payload['id'] = $existing->getId();
  44.             } else {
  45.                 $payload['appId'] = $appId;
  46.                 $payload['active'] = $app->isActive();
  47.                 $payload['name'] = $scriptPath;
  48.                 $payload['hook'] = explode('/'$scriptPath)[0];
  49.             }
  50.             $upserts[] = $payload;
  51.         }
  52.         if (!empty($upserts)) {
  53.             $this->scriptRepository->upsert($upserts$context);
  54.         }
  55.         $this->deleteOldScripts($existingScripts$context);
  56.     }
  57.     public function activateAppScripts(string $appIdContext $context): void
  58.     {
  59.         $criteria = new Criteria();
  60.         $criteria->setTitle('app-scripts::activate');
  61.         $criteria->addFilter(new EqualsFilter('appId'$appId));
  62.         $criteria->addFilter(new EqualsFilter('active'false));
  63.         /** @var array<string> $scripts */
  64.         $scripts $this->scriptRepository->searchIds($criteria$context)->getIds();
  65.         $updateSet array_map(fn (string $id) => ['id' => $id'active' => true], $scripts);
  66.         $this->scriptRepository->update($updateSet$context);
  67.     }
  68.     public function deactivateAppScripts(string $appIdContext $context): void
  69.     {
  70.         $criteria = new Criteria();
  71.         $criteria->setTitle('app-scripts::deactivate');
  72.         $criteria->addFilter(new EqualsFilter('appId'$appId));
  73.         $criteria->addFilter(new EqualsFilter('active'true));
  74.         /** @var array<string> $scripts */
  75.         $scripts $this->scriptRepository->searchIds($criteria$context)->getIds();
  76.         $updateSet array_map(fn (string $id) => ['id' => $id'active' => false], $scripts);
  77.         $this->scriptRepository->update($updateSet$context);
  78.     }
  79.     public function refresh(): void
  80.     {
  81.         $criteria = new Criteria();
  82.         $criteria->setTitle('app-scripts::refresh');
  83.         $criteria->addFilter(new EqualsFilter('active'true));
  84.         $apps $this->appRepository->search($criteriaContext::createDefaultContext())->getEntities();
  85.         /** @var AppEntity $app */
  86.         foreach ($apps as $app) {
  87.             $this->updateScripts($app->getId(), Context::createDefaultContext());
  88.         }
  89.     }
  90.     private function deleteOldScripts(ScriptCollection $toBeRemovedContext $context): void
  91.     {
  92.         /** @var array<string> $ids */
  93.         $ids $toBeRemoved->getIds();
  94.         if (!empty($ids)) {
  95.             $ids array_map(static fn (string $id): array => ['id' => $id], array_values($ids));
  96.             $this->scriptRepository->delete($ids$context);
  97.         }
  98.     }
  99.     private function getAppWithExistingScripts(string $appIdContext $context): AppEntity
  100.     {
  101.         $criteria = new Criteria([$appId]);
  102.         $criteria->addAssociation('scripts');
  103.         /** @var AppEntity $app */
  104.         $app $this->appRepository->search($criteria$context)->first();
  105.         return $app;
  106.     }
  107. }