vendor/shopware/storefront/Theme/Subscriber/UpdateSubscriber.php line 48

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Theme\Subscriber;
  3. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  4. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  6. use Shopware\Core\Framework\Log\Package;
  7. use Shopware\Core\Framework\Plugin\PluginLifecycleService;
  8. use Shopware\Core\Framework\Update\Event\UpdatePostFinishEvent;
  9. use Shopware\Core\System\SalesChannel\SalesChannelEntity;
  10. use Shopware\Storefront\Theme\Exception\ThemeCompileException;
  11. use Shopware\Storefront\Theme\ThemeCollection;
  12. use Shopware\Storefront\Theme\ThemeEntity;
  13. use Shopware\Storefront\Theme\ThemeLifecycleService;
  14. use Shopware\Storefront\Theme\ThemeService;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. /**
  17.  * @internal
  18.  */
  19. #[Package('storefront')]
  20. class UpdateSubscriber implements EventSubscriberInterface
  21. {
  22.     /**
  23.      * @internal
  24.      */
  25.     public function __construct(
  26.         private readonly ThemeService $themeService,
  27.         private readonly ThemeLifecycleService $themeLifecycleService,
  28.         private readonly EntityRepository $salesChannelRepository
  29.     ) {
  30.     }
  31.     /**
  32.      * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>>
  33.      */
  34.     public static function getSubscribedEvents(): array
  35.     {
  36.         return [
  37.             UpdatePostFinishEvent::class => 'updateFinished',
  38.         ];
  39.     }
  40.     /**
  41.      * @internal
  42.      */
  43.     public function updateFinished(UpdatePostFinishEvent $event): void
  44.     {
  45.         $context $event->getContext();
  46.         $this->themeLifecycleService->refreshThemes($context);
  47.         if ($context->hasState(PluginLifecycleService::STATE_SKIP_ASSET_BUILDING)) {
  48.             return;
  49.         }
  50.         $criteria = new Criteria();
  51.         $criteria->addFilter(new EqualsFilter('active'true));
  52.         $criteria->getAssociation('themes')
  53.             ->addFilter(new EqualsFilter('active'true));
  54.         $alreadyCompiled = [];
  55.         /** @var SalesChannelEntity $salesChannel */
  56.         foreach ($this->salesChannelRepository->search($criteria$context) as $salesChannel) {
  57.             $themes $salesChannel->getExtension('themes');
  58.             if (!$themes instanceof ThemeCollection) {
  59.                 continue;
  60.             }
  61.             $failedThemes = [];
  62.             /** @var ThemeEntity $theme */
  63.             foreach ($themes as $theme) {
  64.                 // NEXT-21735 - his is covered randomly
  65.                 // @codeCoverageIgnoreStart
  66.                 if (\in_array($theme->getId(), $alreadyCompiledtrue) !== false) {
  67.                     continue;
  68.                 }
  69.                 // @codeCoverageIgnoreEnd
  70.                 try {
  71.                     $alreadyCompiled += $this->themeService->compileThemeById($theme->getId(), $context);
  72.                 } catch (ThemeCompileException $e) {
  73.                     $failedThemes[] = $theme->getName();
  74.                     $alreadyCompiled[] = $theme->getId();
  75.                 }
  76.             }
  77.             if (!empty($failedThemes)) {
  78.                 $event->appendPostUpdateMessage('Theme(s): ' implode(', '$failedThemes) . ' could not be recompiled.');
  79.             }
  80.         }
  81.     }
  82. }