custom/plugins/SwpRealProductVariantsSix/src/Subscriber/Frontend.php line 65

Open in your IDE?
  1. <?php
  2. /**
  3.  * Shopware
  4.  * Copyright © 2020
  5.  *
  6.  * @category   Shopware
  7.  * @package    SwpRealProductVariantsSix
  8.  * @subpackage Frontend.php
  9.  *
  10.  * @copyright  2020 Iguana-Labs GmbH
  11.  * @author     Module Factory <info at module-factory.com>
  12.  * @license    https://www.module-factory.com/eula
  13.  */
  14. namespace Swp\RealProductVariantsSix\Subscriber;
  15. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  16. use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionCollection;
  17. use Shopware\Core\Content\Property\PropertyGroupCollection;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Dbal\Common\RepositoryIterator;
  19. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  20. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  21. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  22. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  23. use Shopware\Core\Framework\Struct\ArrayStruct;
  24. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepository;
  25. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  26. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  27. use Shopware\Core\System\SystemConfig\SystemConfigService;
  28. class Frontend implements EventSubscriberInterface
  29. {
  30.     /** @var SalesChannelRepository */
  31.     private $salesChannelProductRepository;
  32.     /** @var EntityRepositoryInterface */
  33.     private $optionRepository;
  34.     /** @var SystemConfigService */
  35.     private $systemConfigService;
  36.     public function __construct(
  37.         SalesChannelRepository $salesChannelProductRepository,
  38.         EntityRepositoryInterface $optionRepository,
  39.         SystemConfigService $systemConfigService)
  40.     {
  41.         $this->salesChannelProductRepository $salesChannelProductRepository;
  42.         $this->optionRepository $optionRepository;
  43.         $this->systemConfigService $systemConfigService;
  44.     }
  45.     /**
  46.      * @inheritDoc
  47.      */
  48.     public static function getSubscribedEvents()
  49.     {
  50.         return [
  51.             ProductPageLoadedEvent::class => 'onProductPageLoaded'
  52.         ];
  53.     }
  54.     /**
  55.      * @param ProductPageLoadedEvent $event
  56.      */
  57.     public function onProductPageLoaded(ProductPageLoadedEvent $event) : void
  58.     {
  59.         if ($this->isCannelActive($event) !== true) {
  60.             return;
  61.         }
  62.         $product $event->getPage()->getProduct();
  63.         $criteria = new Criteria();
  64.         $criteria->addAssociations([
  65.             'group',
  66.             'properties.group'
  67.         ]);
  68.         $criteria->addSorting(new FieldSorting('customFields.swp_real_product_variants_six_position'FieldSorting::ASCENDING));
  69.         $criteria->setLimit(1000);
  70.         $criteria->addFilter(new EqualsFilter('customFields.swp_real_product_variants_six_master_product_number'$product->getProductNumber()));
  71.         $slaveProducts $this->salesChannelProductRepository->search(
  72.             $criteria,
  73.             $event->getSalesChannelContext()
  74.         );
  75.         if (!$slaveProducts->getTotal()) {
  76.             return;
  77.         }
  78.         $filters $this->getFilter($slaveProducts->getElements(), $event);
  79.         $product->addExtension(
  80.             'swp_real_product_variants_six',
  81.             (new ArrayStruct())->assign([
  82.                 'slaveProducts' => $slaveProducts,
  83.                 'filters' => $filters
  84.             ])
  85.         );
  86.     }
  87.     /**
  88.      * @param array $slaveProducts
  89.      * @param ProductPageLoadedEvent $event
  90.      * @return PropertyGroupCollection|null
  91.      */
  92.     private function getFilter(
  93.         array $slaveProducts,
  94.         ProductPageLoadedEvent $event
  95.     ): ?PropertyGroupCollection {
  96.         $propertyIds $this->getPropertyIds($slaveProducts);
  97.         if (count($propertyIds) === 0) {
  98.             return null;
  99.         }
  100.         $criteria = new Criteria($propertyIds);
  101.         $criteria->setLimit(500);
  102.         $criteria->addAssociation('group');
  103.         $criteria->addAssociation('media');
  104.         $criteria->addFilter(new EqualsFilter('group.filterable'true));
  105.         $criteria->setTitle('product-listing::property-filter');
  106.         $criteria->addSorting(new FieldSorting('id'FieldSorting::ASCENDING));
  107.         $mergedOptions = new PropertyGroupOptionCollection();
  108.         $repositoryIterator = new RepositoryIterator($this->optionRepository$event->getContext(), $criteria);
  109.         while (($result $repositoryIterator->fetch()) !== null) {
  110.             $mergedOptions->merge($result->getEntities());
  111.         }
  112.         // group options by their property-group
  113.         $groupedFilters $mergedOptions->groupByPropertyGroups();
  114.         $groupedFilters->sortByPositions();
  115.         $groupedFilters->sortByConfig();
  116.         return $groupedFilters;
  117.     }
  118.     /**
  119.      * @param array $slaveProducts
  120.      * @return array
  121.      */
  122.     private function getPropertyIds(array $slaveProducts): array
  123.     {
  124.         $propertyIds = [];
  125.         /** @var SalesChannelProductEntity $slaveProduct */
  126.         foreach ($slaveProducts as $slaveProduct) {
  127.             if($slaveProduct->getPropertyIds()) {
  128.                 $propertyIds \array_merge($propertyIds$slaveProduct->getPropertyIds());
  129.             }
  130.         }
  131.         return \array_unique($propertyIds);
  132.     }
  133.     /**
  134.      * @param ProductPageLoadedEvent $event
  135.      * @return array|bool|float|int|string|null
  136.      */
  137.     private function isCannelActive(ProductPageLoadedEvent $event)
  138.     {
  139.         return $this->systemConfigService->get(
  140.             'SwpRealProductVariantsSix.config.channelActive',
  141.             $event->getSalesChannelContext()->getSalesChannel()->getId()
  142.         );
  143.     }
  144. }