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

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