vendor/shopware/storefront/Theme/Subscriber/PluginLifecycleSubscriber.php line 132

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Theme\Subscriber;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\Feature;
  5. use Shopware\Core\Framework\Log\Package;
  6. use Shopware\Core\Framework\Plugin;
  7. use Shopware\Core\Framework\Plugin\Event\PluginLifecycleEvent;
  8. use Shopware\Core\Framework\Plugin\Event\PluginPostActivateEvent;
  9. use Shopware\Core\Framework\Plugin\Event\PluginPostDeactivationFailedEvent;
  10. use Shopware\Core\Framework\Plugin\Event\PluginPostUninstallEvent;
  11. use Shopware\Core\Framework\Plugin\Event\PluginPreActivateEvent;
  12. use Shopware\Core\Framework\Plugin\Event\PluginPreDeactivateEvent;
  13. use Shopware\Core\Framework\Plugin\Event\PluginPreUninstallEvent;
  14. use Shopware\Core\Framework\Plugin\Event\PluginPreUpdateEvent;
  15. use Shopware\Core\Framework\Plugin\PluginLifecycleService;
  16. use Shopware\Storefront\Theme\Exception\InvalidThemeBundleException;
  17. use Shopware\Storefront\Theme\Exception\ThemeCompileException;
  18. use Shopware\Storefront\Theme\StorefrontPluginConfiguration\AbstractStorefrontPluginConfigurationFactory;
  19. use Shopware\Storefront\Theme\StorefrontPluginConfiguration\StorefrontPluginConfiguration;
  20. use Shopware\Storefront\Theme\StorefrontPluginRegistryInterface;
  21. use Shopware\Storefront\Theme\ThemeLifecycleHandler;
  22. use Shopware\Storefront\Theme\ThemeLifecycleService;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. /**
  25.  * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
  26.  */
  27. #[Package('storefront')]
  28. class PluginLifecycleSubscriber implements EventSubscriberInterface
  29. {
  30.     private StorefrontPluginRegistryInterface $storefrontPluginRegistry;
  31.     private string $projectDirectory;
  32.     private AbstractStorefrontPluginConfigurationFactory $pluginConfigurationFactory;
  33.     private ThemeLifecycleHandler $themeLifecycleHandler;
  34.     private ThemeLifecycleService $themeLifecycleService;
  35.     /**
  36.      * @internal
  37.      */
  38.     public function __construct(
  39.         StorefrontPluginRegistryInterface $storefrontPluginRegistry,
  40.         string $projectDirectory,
  41.         AbstractStorefrontPluginConfigurationFactory $pluginConfigurationFactory,
  42.         ThemeLifecycleHandler $themeLifecycleHandler,
  43.         ThemeLifecycleService $themeLifecycleService
  44.     ) {
  45.         $this->storefrontPluginRegistry $storefrontPluginRegistry;
  46.         $this->projectDirectory $projectDirectory;
  47.         $this->pluginConfigurationFactory $pluginConfigurationFactory;
  48.         $this->themeLifecycleHandler $themeLifecycleHandler;
  49.         $this->themeLifecycleService $themeLifecycleService;
  50.     }
  51.     /**
  52.      * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>>
  53.      */
  54.     public static function getSubscribedEvents()
  55.     {
  56.         if (Feature::isActive('v6.5.0.0')) {
  57.             return [
  58.                 PluginPostActivateEvent::class => 'pluginPostActivate',
  59.                 PluginPreUpdateEvent::class => 'pluginUpdate',
  60.                 PluginPreDeactivateEvent::class => 'pluginDeactivateAndUninstall',
  61.                 PluginPostDeactivationFailedEvent::class => 'pluginPostDeactivateFailed',
  62.                 PluginPreUninstallEvent::class => 'pluginDeactivateAndUninstall',
  63.                 PluginPostUninstallEvent::class => 'pluginPostUninstall',
  64.             ];
  65.         }
  66.         return [
  67.             PluginPreActivateEvent::class => 'pluginActivate',
  68.             PluginPostActivateEvent::class => 'pluginPostActivate',
  69.             PluginPreUpdateEvent::class => 'pluginUpdate',
  70.             PluginPreDeactivateEvent::class => 'pluginDeactivateAndUninstall',
  71.             PluginPostDeactivationFailedEvent::class => 'pluginPostDeactivateFailed',
  72.             PluginPreUninstallEvent::class => 'pluginDeactivateAndUninstall',
  73.             PluginPostUninstallEvent::class => 'pluginPostUninstall',
  74.         ];
  75.     }
  76.     /**
  77.      * @deprecated tag:v6.5.0 - Method will be removed. use pluginPostActivate instead
  78.      */
  79.     public function pluginActivate(PluginPreActivateEvent $event): void
  80.     {
  81.         Feature::triggerDeprecationOrThrow(
  82.             'v6.5.0.0',
  83.             sprintf('Method pluginActivate of Class %s is deprecated. Use method pluginPostActivate instead', static::class)
  84.         );
  85.         // do nothing
  86.     }
  87.     public function pluginPostActivate(PluginPostActivateEvent $event): void
  88.     {
  89.         $this->doPostActivate($event);
  90.     }
  91.     public function pluginPostDeactivateFailed(PluginPostDeactivationFailedEvent $event): void
  92.     {
  93.         $this->doPostActivate($event);
  94.     }
  95.     public function pluginUpdate(PluginPreUpdateEvent $event): void
  96.     {
  97.         if ($this->skipCompile($event->getContext()->getContext())) {
  98.             return;
  99.         }
  100.         $pluginName $event->getPlugin()->getName();
  101.         $config $this->storefrontPluginRegistry->getConfigurations()->getByTechnicalName($pluginName);
  102.         if (!$config) {
  103.             return;
  104.         }
  105.         $this->themeLifecycleHandler->handleThemeInstallOrUpdate(
  106.             $config,
  107.             $this->storefrontPluginRegistry->getConfigurations(),
  108.             $event->getContext()->getContext()
  109.         );
  110.     }
  111.     /**
  112.      * @param PluginPreDeactivateEvent|PluginPreUninstallEvent $event
  113.      */
  114.     public function pluginDeactivateAndUninstall($event): void
  115.     {
  116.         if ($this->skipCompile($event->getContext()->getContext())) {
  117.             return;
  118.         }
  119.         $pluginName $event->getPlugin()->getName();
  120.         $config $this->storefrontPluginRegistry->getConfigurations()->getByTechnicalName($pluginName);
  121.         if (!$config) {
  122.             return;
  123.         }
  124.         $this->themeLifecycleHandler->handleThemeUninstall($config$event->getContext()->getContext());
  125.     }
  126.     public function pluginPostUninstall(PluginPostUninstallEvent $event): void
  127.     {
  128.         if ($event->getContext()->keepUserData()) {
  129.             return;
  130.         }
  131.         $this->themeLifecycleService->removeTheme($event->getPlugin()->getName(), $event->getContext()->getContext());
  132.     }
  133.     /**
  134.      * @throws ThemeCompileException
  135.      * @throws InvalidThemeBundleException
  136.      */
  137.     private function createConfigFromClassName(string $pluginPathstring $className): StorefrontPluginConfiguration
  138.     {
  139.         /** @var Plugin $plugin */
  140.         $plugin = new $className(true$pluginPath$this->projectDirectory);
  141.         if (!$plugin instanceof Plugin) {
  142.             throw new \RuntimeException(
  143.                 sprintf('Plugin class "%s" must extend "%s"', \get_class($plugin), Plugin::class)
  144.             );
  145.         }
  146.         return $this->pluginConfigurationFactory->createFromBundle($plugin);
  147.     }
  148.     private function doPostActivate(PluginLifecycleEvent $event): void
  149.     {
  150.         if (!($event instanceof PluginPostActivateEvent) && !($event instanceof PluginPostDeactivationFailedEvent)) {
  151.             return;
  152.         }
  153.         if ($this->skipCompile($event->getContext()->getContext())) {
  154.             return;
  155.         }
  156.         // create instance of the plugin to create a configuration
  157.         // (the kernel boot is already finished and the activated plugin is missing)
  158.         $storefrontPluginConfig $this->createConfigFromClassName(
  159.             $event->getPlugin()->getPath() ?: '',
  160.             $event->getPlugin()->getBaseClass()
  161.         );
  162.         // add plugin configuration to the list of all active plugin configurations
  163.         $configurationCollection = clone $this->storefrontPluginRegistry->getConfigurations();
  164.         $configurationCollection->add($storefrontPluginConfig);
  165.         $this->themeLifecycleHandler->handleThemeInstallOrUpdate(
  166.             $storefrontPluginConfig,
  167.             $configurationCollection,
  168.             $event->getContext()->getContext()
  169.         );
  170.     }
  171.     private function skipCompile(Context $context): bool
  172.     {
  173.         return $context->hasState(PluginLifecycleService::STATE_SKIP_ASSET_BUILDING);
  174.     }
  175. }