<?php declare(strict_types=1);namespace WodkaHoverOnListingSW6\Subscriber;use WodkaHoverOnListingSW6\Services\HoverOnListingConfiguration;use WodkaHoverOnListingSW6\Services\HoverOnListingConfigurationService;use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaEntity;use Shopware\Core\Content\Product\Events\ProductCrossSellingIdsCriteriaEvent;use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;use Shopware\Core\Content\Product\Events\ProductListingResultEvent;use Shopware\Core\Content\Product\Events\ProductSearchCriteriaEvent;use Shopware\Core\Content\Product\Events\ProductSearchResultEvent;use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;use Shopware\Core\System\SalesChannel\SalesChannelContext;use Shopware\Storefront\Event\StorefrontRenderEvent;use Symfony\Component\EventDispatcher\EventSubscriberInterface;class FrontendSubscriber implements EventSubscriberInterface{ /** * @var array */ protected array $pluginConfig; /** * @var HoverOnListingConfigurationService */ protected HoverOnListingConfigurationService $hoverOnListingConfigurationService; /** * @param HoverOnListingConfigurationService $hoverOnListingConfigurationService */ public function __construct(HoverOnListingConfigurationService $hoverOnListingConfigurationService) { $this->hoverOnListingConfigurationService = $hoverOnListingConfigurationService; $this->pluginConfig = []; } /** * @return string[] */ public static function getSubscribedEvents(): array { return [ ProductListingCriteriaEvent::class => 'onProductListingCriteria', ProductSearchCriteriaEvent::class => 'onProductSearchCriteria', ProductListingResultEvent::class => 'handleResult', ProductSearchResultEvent::class => 'handleResult', ProductCrossSellingIdsCriteriaEvent::class => 'onCrossSellingProductListCriteria', StorefrontRenderEvent::class => 'onStorefrontRender' ]; } /** * @param SalesChannelContext $salesChannelContext * @return HoverOnListingConfiguration|null */ private function getPluginConfig(SalesChannelContext $salesChannelContext): ?HoverOnListingConfiguration { if (!isset($this->pluginConfig[$salesChannelContext->getToken()]) || !($this->pluginConfig[$salesChannelContext->getToken()] instanceof HoverOnListingConfiguration)) { $this->pluginConfig[$salesChannelContext->getToken()] = $this->hoverOnListingConfigurationService->getConfiguration($salesChannelContext); } return $this->pluginConfig[$salesChannelContext->getToken()]; } /** * @param SalesChannelContext $salesChannelContext * @return bool */ private function isPluginActive(SalesChannelContext $salesChannelContext): bool { return $this->getPluginConfig($salesChannelContext) && $this->getPluginConfig($salesChannelContext)->isActive(); } /** * @param StorefrontRenderEvent $event * @return void */ public function onStorefrontRender(StorefrontRenderEvent $event): void { $event->getSalesChannelContext() ->addExtension('WodkaHoverOnListingSW6', $this->getPluginConfig($event->getSalesChannelContext())); } /** * @param ProductSearchCriteriaEvent $event * @return void */ public function onProductSearchCriteria(ProductSearchCriteriaEvent $event): void { if ($this->isPluginActive($event->getSalesChannelContext())) { $criteria = $event->getCriteria(); $criteria->addAssociation('media'); } } /** * @param ProductCrossSellingIdsCriteriaEvent $event * @return void */ public function onCrossSellingProductListCriteria(ProductCrossSellingIdsCriteriaEvent $event): void { if ($this->isPluginActive($event->getSalesChannelContext())) { $criteria = $event->getCriteria(); $criteria->addAssociation('media'); } } /** * @param ProductListingCriteriaEvent $event * @return void */ public function onProductListingCriteria(ProductListingCriteriaEvent $event): void { if ($this->isPluginActive($event->getSalesChannelContext())) { $criteria = $event->getCriteria(); $criteria->addAssociation('media'); } } /** * @param ProductListingResultEvent $event * @return void */ public function handleResult(ProductListingResultEvent $event): void { if ($this->isPluginActive($event->getSalesChannelContext())) { /** @var SalesChannelProductEntity $product */ foreach ($event->getResult()->getEntities() as $product) { // Check if we have more than 1 images if ($product->getMedia() && $product->getMedia()->count() >= 2) { $hoverPosition = 1; if ($product->getCover() && $product->getCover()->getPosition() === 0) { /** @var ProductMediaEntity $productMedia */ foreach ($product->getMedia() as $productMedia) { if ($productMedia->getPosition() === $hoverPosition) { $product->addExtension("hover", $productMedia->getMedia()); break; } } } else { // Product media position is sometimes broken and its value is 1 for all product media /** @var ProductMediaEntity $productMedia */ foreach ($product->getMedia() as $productMedia) { if ($product->getCover() && $productMedia->getMedia() && $product->getCover()->getMediaId() && $product->getCover()->getMediaId() !== $productMedia->getMediaId()) { $product->addExtension("hover", $productMedia->getMedia()); break; } } } } } } }}