custom/plugins/MaxiaListingVariants6/src/Subscriber/Storefront.php line 90

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Maxia\MaxiaListingVariants6\Subscriber;
  3. use Maxia\MaxiaListingVariants6\Service\ConfigService;
  4. use Maxia\MaxiaListingVariants6\Service\ListingVariantsLoader;
  5. use Monolog\Logger;
  6. use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
  7. use Shopware\Core\Content\Product\Events\ProductSearchResultEvent;
  8. use Shopware\Core\Framework\Struct\ArrayEntity;
  9. use Shopware\Storefront\Event\StorefrontRenderEvent;
  10. use Shopware\Storefront\Event\ThemeCompilerEnrichScssVariablesEvent;
  11. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use TypeError;
  14. /**
  15.  * @package Maxia\MaxiaListingVariants6\Subscriber
  16.  */
  17. class Storefront implements EventSubscriberInterface
  18. {
  19.     public static function getSubscribedEvents(): array
  20.     {
  21.         $events = [
  22.             StorefrontRenderEvent::class => 'onStorefrontRender',
  23.             ThemeCompilerEnrichScssVariablesEvent::class => 'enrichScssVariables',
  24.             ProductSearchResultEvent::class => ['onSearchResult', -10],
  25.             ProductPageLoadedEvent::class => ['onProductPageLoaded', -10],
  26.             ProductListingResultEvent::class => ['onProductListingResult', -10]
  27.         ];
  28.         if (class_exists('\Acris\Search\Core\Content\Product\Events\ProductManufacturerResultEvent')) {
  29.             $events[\Acris\Search\Core\Content\Product\Events\ProductManufacturerResultEvent::class]
  30.                 = 'onAcrisProductManufacturerResultEvent';
  31.         }
  32.         return $events;
  33.     }
  34.     /**
  35.      * @var ListingVariantsLoader
  36.      */
  37.     private $listingVariantsLoader;
  38.     /**
  39.      * @var ConfigService
  40.      */
  41.     private $configService;
  42.     /**
  43.      * @var Logger
  44.      */
  45.     private $logger;
  46.     public function __construct(
  47.         ListingVariantsLoader $variantListingService,
  48.         Logger $logger,
  49.         ConfigService $configService
  50.     ) {
  51.         $this->listingVariantsLoader $variantListingService;
  52.         $this->configService $configService;
  53.         $this->logger $logger;
  54.     }
  55.     public function enrichScssVariables(ThemeCompilerEnrichScssVariablesEvent $event)
  56.     {
  57.         $databaseUrl getenv('DATABASE_URL');
  58.         if (!$databaseUrl || $databaseUrl === 'mysql://_placeholder.test') {
  59.             // deployment server without database
  60.             return;
  61.         }
  62.         $prefix 'maxia-listing-variants-';
  63.         $config $this->configService->getBaseConfig($event->getSalesChannelId());
  64.         if ($config->getBuyButtonHeight()) {
  65.             $event->addVariable($prefix 'actions-height'$config->getBuyButtonHeight());
  66.         }
  67.         if ($config->getMediaOptionHeight()) {
  68.             $event->addVariable($prefix 'media-option-height'$config->getMediaOptionHeight());
  69.         }
  70.         if ($config->getColorOptionHeight()) {
  71.             $event->addVariable($prefix 'color-option-height'$config->getColorOptionHeight());
  72.         }
  73.     }
  74.     public function onStorefrontRender(StorefrontRenderEvent $event)
  75.     {
  76.         // add plugin config to context
  77.         $context $event->getSalesChannelContext();
  78.         $config $this->configService->getBaseConfig($context);
  79.         $context->addExtension('maxiaListingVariants'$config);
  80.         if (!$config->isPluginEnabled() || $config->getDisplayMode() === 'none') {
  81.             return;
  82.         }
  83.         $request $event->getRequest();
  84.         // CbaxModulManufacturers: Load variants on storefront render (plugin has no result event)
  85.         if ($request->attributes->get('_route') === 'frontend.cbax.manufacturer.detail') {
  86.             try {
  87.                 /** @var \Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult $products */
  88.                 $products $event->getParameters()['cbaxModulManufacturers']['products'];
  89.                 if ($products && $products->getEntities() && $products->getTotal()) {
  90.                     $this->listingVariantsLoader->load($products->getEntities()->getElements(), $event->getSalesChannelContext());
  91.                 }
  92.             } catch (\Exception $e) {
  93.                 $this->logger->error('Exception occurred when loading variants in cbax manufacturer listing: '.
  94.                     $e->getMessage().",\nStack trace: ".$e->getTraceAsString());
  95.             }
  96.         }
  97.     }
  98.     /**
  99.      * Loads variants in search results listing.
  100.      *
  101.      * @param ProductSearchResultEvent $event
  102.      */
  103.     public function onSearchResult(ProductSearchResultEvent $event)
  104.     {
  105.         $products $event->getResult()->getEntities();
  106.         $config $this->configService->getBaseConfig($event->getSalesChannelContext());
  107.         if ($config->isPluginEnabled() && $config->isShowInSearchListing()) {
  108.             $disablePreselection $config->isDisablePreselectionInSearch();
  109.             if ($event->getSalesChannelContext()->hasExtension('acris_exact_search')
  110.                 && $event->getResult()->getTotal() === 1)
  111.             {
  112.                 $disablePreselection true;
  113.             }
  114.             if ($disablePreselection) {
  115.                 $event->getRequest()->attributes->set('maxia-handle-variant-preselection'false);
  116.             }
  117.             try {
  118.                 $this->listingVariantsLoader->load($products->getElements(), $event->getSalesChannelContext());
  119.             } catch (\Exception $e) {
  120.                 $this->logger->error('Exception occurred when loading variants in search result: '.
  121.                     $e->getMessage().",\nStack trace: ".$e->getTraceAsString());
  122.             }
  123.         }
  124.     }
  125.     /**
  126.      * Loads variants via ProductListingResultEvent
  127.      *
  128.      * @param ProductListingResultEvent $event
  129.      */
  130.     public function onProductListingResult(ProductListingResultEvent $event)
  131.     {
  132.         $products $event->getResult()->getEntities();
  133.         $config $this->configService->getBaseConfig($event->getSalesChannelContext());
  134.         /** @var ArrayEntity $extension */
  135.         $extension $event->getResult()->getExtension('maxiaListingVariants');
  136.         if ($config->isPluginEnabled() && $extension && $extension->get('loadVariants')) {
  137.             try {
  138.                 $this->listingVariantsLoader->load($products->getElements(), $event->getSalesChannelContext());
  139.             } catch (\Exception $e) {
  140.                 $this->logger->error('Exception occurred when loading variants in product listing result: '.
  141.                     $e->getMessage().",\nStack trace: ".$e->getTraceAsString());
  142.             }
  143.         }
  144.     }
  145.     /**
  146.      * Load variants in cross selling when no cms layout is assigned.
  147.      * Otherwise, variants will be loaded from CrossSellingCmsElementResolver
  148.      *
  149.      * @param ProductPageLoadedEvent $event
  150.      */
  151.     public function onProductPageLoaded(ProductPageLoadedEvent $event)
  152.     {
  153.         $config $this->configService->getBaseConfig($event->getSalesChannelContext());
  154.         if (!$config->isPluginEnabled()) {
  155.             return;
  156.         }
  157.         try {
  158.             $crossSellings $event->getPage()->getCrossSellings();
  159.         } catch (TypeError $e) {
  160.             // @todo: remove try catch when possible
  161.             return;
  162.         }
  163.         $products = [];
  164.         if ($crossSellings && $config->isShowInCrossSelling()) {
  165.             foreach ($crossSellings as $crossSelling) {
  166.                 if ($crossSelling->getProducts()) {
  167.                     foreach ($crossSelling->getProducts()->getElements() as $product) {
  168.                         $products[] = $product;
  169.                     }
  170.                 }
  171.             }
  172.         }
  173.         if ($products) {
  174.             try {
  175.                 $this->listingVariantsLoader->load($products$event->getSalesChannelContext());
  176.             } catch (\Exception $e) {
  177.                 $this->logger->error('Exception occurred when loading variants in cross selling: '.
  178.                     $e->getMessage().",\nStack trace: ".$e->getTraceAsString());
  179.             }
  180.         }
  181.     }
  182.     /**
  183.      * AcrisSearchCS manufacturer product listing
  184.      *
  185.      * @param \Acris\Search\Core\Content\Product\Events\ProductManufacturerResultEvent $event
  186.      */
  187.     /** @phpstan-ignore-next-line */
  188.     public function onAcrisProductManufacturerResultEvent(\Acris\Search\Core\Content\Product\Events\ProductManufacturerResultEvent $event)
  189.     {
  190.         $products $event->getResult()->getEntities();
  191.         $config $this->configService->getBaseConfig($event->getSalesChannelContext());
  192.         if ($config->isPluginEnabled() && $config->getDisplayMode() !== 'none') {
  193.             try {
  194.                 $this->listingVariantsLoader->load($products->getElements(), $event->getSalesChannelContext());
  195.             } catch (\Exception $e) {
  196.                 $this->logger->error('Exception occurred when loading variants on ProductManufacturerResultEvent: '.
  197.                     $e->getMessage().",\nStack trace: ".$e->getTraceAsString());
  198.             }
  199.         }
  200.     }
  201. }