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

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