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

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