custom/plugins/GbmedEnev/src/Subscriber/ProductPage.php line 96

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /**
  3.  * gb media
  4.  * All Rights Reserved.
  5.  *
  6.  * Unauthorized copying of this file, via any medium is strictly prohibited.
  7.  * The content of this file is proprietary and confidential.
  8.  *
  9.  * @category       Shopware
  10.  * @package        Shopware_Plugins
  11.  * @subpackage     GbmedEnev
  12.  * @copyright      Copyright (c) 2019, gb media
  13.  * @license        proprietary
  14.  * @author         Giuseppe Bottino
  15.  * @link           http://www.gb-media.biz
  16.  */
  17. namespace Gbmed\Enev\Subscriber;
  18. use Gbmed\Enev\Core\Content\Enev\EnevCollection;
  19. use Gbmed\Enev\Core\Content\Enev\EnevDefinition;
  20. use Gbmed\Enev\Service\Filter;
  21. use Gbmed\Enev\Service\Product as ProductService;
  22. use Shopware\Core\Content\Product\Events\ProductCrossSellingCriteriaEvent;
  23. use Shopware\Core\Content\Product\Events\ProductCrossSellingIdsCriteriaEvent;
  24. use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
  25. use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
  26. use Shopware\Core\Content\Product\Events\ProductSearchCriteriaEvent;
  27. use Shopware\Core\Content\Product\ProductEntity;
  28. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  29. use Shopware\Core\Content\ProductExport\Event\ProductExportProductCriteriaEvent;
  30. use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
  31. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  32. use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
  33. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  34. use Shopware\Core\System\SystemConfig\SystemConfigService;
  35. use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
  36. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  37. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  38. use Exception;
  39. use Shopware\Core\Content\Product\Events\ProductCrossSellingsLoadedEvent;
  40. class ProductPage implements EventSubscriberInterface
  41. {
  42.     /** @var ProductService */
  43.     private $productService;
  44.     /**
  45.      * @var Filter
  46.      */
  47.     private $filterService;
  48.     private SystemConfigService $systemConfigService;
  49.     /**
  50.      * Product constructor.
  51.      *
  52.      * @param ProductService $productService
  53.      * @param Filter $filterService
  54.      * @param SystemConfigService $systemConfigService
  55.      */
  56.     public function __construct(
  57.         ProductService $productService,
  58.         Filter $filterService,
  59.         SystemConfigService $systemConfigService
  60.     ) {
  61.         $this->productService $productService;
  62.         $this->filterService $filterService;
  63.         $this->systemConfigService $systemConfigService;
  64.     }
  65.     public static function getSubscribedEvents(): array
  66.     {
  67.         return [
  68.             ProductExportProductCriteriaEvent::class => 'onProductExportProductCriteriaEvent',
  69.             ProductSearchCriteriaEvent::class => 'onProductSearchCriteriaEvent',
  70.             ProductListingCriteriaEvent::class => 'onProductListingCriteriaEvent',
  71.             ProductListingResultEvent::class => 'onProductListingResultEvent',
  72.             ProductPageCriteriaEvent::class => 'onProductPageCriteriaEvent',
  73.             ProductPageLoadedEvent::class => 'onProductPageLoadedEvent',
  74.             ProductCrossSellingCriteriaEvent::class => 'onProductCrossSellingCriteriaEvent',
  75.             ProductCrossSellingIdsCriteriaEvent::class => 'onProductCrossSellingIdsCriteriaEvent',
  76.             ProductCrossSellingsLoadedEvent::class => 'onProductCrossSellingsLoadedEvent',
  77.             'sales_channel.product.loaded' => 'onSalesChannelEntityLoadedEvent',
  78.         ];
  79.     }
  80.     public function onProductExportProductCriteriaEvent(ProductExportProductCriteriaEvent $event): void
  81.     {
  82.         $this->addCriteria($event->getCriteria());
  83.     }
  84.     public function onProductSearchCriteriaEvent(ProductSearchCriteriaEvent $event): void
  85.     {
  86.         $this->addCriteria($event->getCriteria());
  87.     }
  88.     public function onProductListingCriteriaEvent(ProductListingCriteriaEvent $event): void
  89.     {
  90.         $this->addCriteria($event->getCriteria());
  91.     }
  92.     public function onProductPageCriteriaEvent(ProductPageCriteriaEvent $event): void
  93.     {
  94.         $this->addCriteria($event->getCriteria());
  95.     }
  96.     public function onProductCrossSellingCriteriaEvent(ProductCrossSellingCriteriaEvent $event): void
  97.     {
  98.         $this->addCriteria($event->getCriteria());
  99.     }
  100.     public function onProductCrossSellingIdsCriteriaEvent(ProductCrossSellingIdsCriteriaEvent $event): void
  101.     {
  102.         $this->addCriteria($event->getCriteria());
  103.     }
  104.     /**
  105.      * add data into listing
  106.      *
  107.      * @param ProductListingResultEvent $event
  108.      * @throws Exception
  109.      */
  110.     public function onProductListingResultEvent(ProductListingResultEvent $event): void
  111.     {
  112.         $salesChannelContext $event->getSalesChannelContext();
  113.         $products $event->getResult();
  114.         /** workaround to set the correct filter list */
  115.         $this->filterService->setFilterList($productsEnevDefinition::ENTITY_NAME'class');
  116.         /** @var SalesChannelProductEntity $product */
  117.         foreach ($products as $product) {
  118.             $this->prepareProduct($product$salesChannelContext);
  119.         }
  120.     }
  121.     /**
  122.      * add data into detail
  123.      *
  124.      * @param ProductPageLoadedEvent $event
  125.      * @throws Exception
  126.      */
  127.     public function onProductPageLoadedEvent(ProductPageLoadedEvent $event): void
  128.     {
  129.         $product $event->getPage()->getProduct();
  130.         $salesChannelContext $event->getSalesChannelContext();
  131.         $this->prepareProduct($product$salesChannelContext);
  132.     }
  133.     /**
  134.      * add data into product-slider
  135.      *
  136.      * @param ProductCrossSellingsLoadedEvent $event
  137.      * @throws Exception
  138.      */
  139.     public function onProductCrossSellingsLoadedEvent(ProductCrossSellingsLoadedEvent $event): void
  140.     {
  141.         $salesChannelContext $event->getSalesChannelContext();
  142.         $crossSellings $event->getCrossSellings()->getElements();
  143.         /** @var \Shopware\Core\Content\Product\SalesChannel\CrossSelling\CrossSellingElement $crossSelling */
  144.         foreach ($crossSellings as $crossSelling) {
  145.             /** @var SalesChannelProductEntity $product */
  146.             foreach ($crossSelling->getProducts() as $product) {
  147.                 $this->prepareProduct($product$salesChannelContext);
  148.             }
  149.         }
  150.     }
  151.     /**
  152.      * add data into product-slider
  153.      *
  154.      * @param SalesChannelEntityLoadedEvent $event
  155.      * @throws Exception
  156.      */
  157.     public function onSalesChannelEntityLoadedEvent(SalesChannelEntityLoadedEvent $event): void
  158.     {
  159.         $salesChannelContext $event->getSalesChannelContext();
  160.         $products $event->getEntities();
  161.         /** @var SalesChannelProductEntity $product */
  162.         foreach ($products as $product) {
  163.             $this->prepareProduct($product$salesChannelContext);
  164.         }
  165.     }
  166.     private function prepareProduct(
  167.         ProductEntity $product,
  168.         SalesChannelContext $salesChannelContext
  169.     ): void {
  170.         $result null;
  171.         /** @var EnevCollection $collection */
  172.         $collection $product->getExtension(EnevDefinition::propertyName());
  173.         if ($collection instanceof EnevCollection) {
  174.             $result $this->productService->prepareEprel(
  175.                 $collection,
  176.                 $salesChannelContext
  177.             );
  178.         }
  179.         // TODO, add systemConfig to find always enev data (e.g. productSlider doesn't have CriteriaEvent)
  180.         $configFindAlways $this->systemConfigService->get('GbmedEnev.config.findAlways');
  181.         $findAlways = !($configFindAlways !== null) || (bool)$configFindAlways;
  182.         if ($findAlways && (!($result instanceof EnevCollection) || !count($result->getElements()))) {
  183.             $result $this->findEnevByProduct($product$salesChannelContext);
  184.         }
  185.         if ($result instanceof EnevCollection) {
  186.             $product->addExtension(EnevDefinition::propertyName(), $result);
  187.         }
  188.     }
  189.     /**
  190.      * helper to find enev
  191.      *
  192.      * @param ProductEntity $product
  193.      * @param SalesChannelContext $salesChannelContext
  194.      * @return EntityCollection|null
  195.      * @throws \GuzzleHttp\Exception\GuzzleException
  196.      */
  197.     private function findEnevByProduct(
  198.         ProductEntity $product,
  199.         SalesChannelContext $salesChannelContext
  200.     ): ?EntityCollection {
  201.         $result null;
  202.         try {
  203.             $result $this->productService->findEnevByProductId($product->getId(), $salesChannelContext->getContext());
  204.             if (!$result->getTotal() && $product->getParentId()) {
  205.                 $result $this->productService->findEnevByProductId(
  206.                     $product->getParentId(),
  207.                     $salesChannelContext->getContext()
  208.                 );
  209.             }
  210.             $result $result->getTotal()
  211.                 ? $this->productService->prepareEprel($result->getEntities(), $salesChannelContext)
  212.                 : null;
  213.         } catch (Exception $e) {
  214.             throw new Exception($e->getMessage());
  215.         }
  216.         return $result;
  217.     }
  218.     private function addCriteria(Criteria $criteria): void
  219.     {
  220.         $criteria->addAssociation(EnevDefinition::propertyName())
  221.             ->addAssociation(EnevDefinition::propertyName() . '.media')
  222.             ->addAssociation(EnevDefinition::propertyName() . '.datasheet')
  223.             ->addAssociation(EnevDefinition::propertyName() . '.icon');
  224.     }
  225. }