custom/plugins/ThemeOkeOnline/src/Storefront/Page/Product/ProductPageLoadedEventSubscriber.php line 73

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace ThemeOkeOnline\Storefront\Page\Product;
  3. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  4. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  5. use Shopware\Core\Content\Product\Exception\ReviewNotActiveExeption;
  6. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  7. use Shopware\Core\System\SystemConfig\SystemConfigService;
  8. use Shopware\Storefront\Page\Product\ProductLoaderCriteriaEvent;
  9. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  10. use Shopware\Storefront\Page\Product\Review\ProductReviewLoader;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. class ProductPageLoadedEventSubscriber implements EventSubscriberInterface
  13. {
  14.     /**
  15.      * @var ProductPageLoadedEvent
  16.      */
  17.     private $event;
  18.     private $context;
  19.     private $page;
  20.     private $request;
  21.     /**
  22.      * @var EntityRepository
  23.      */
  24.     private $productRepository;
  25.     /**
  26.      * @var EntityRepository
  27.      */
  28.     private $propertyGroupRepository;
  29.     /**
  30.      * @var EntityRepository
  31.      */
  32.     private $propertyGroupOptionRepository;
  33.     /**
  34.      * @var ProductReviewLoader
  35.      */
  36.     private $productReviewLoader;
  37.     /**
  38.      * @var SystemConfigService
  39.      */
  40.     private $systemConfigService;
  41.     public function __construct(
  42.         EntityRepository $productRepository,
  43.         EntityRepository $propertyGroupRepository,
  44.         EntityRepository $propertyGroupOptionRepository,
  45.         ProductReviewLoader $productReviewLoader,
  46.         SystemConfigService $systemConfigService
  47.     )
  48.     {
  49.         $this->productRepository $productRepository;
  50.         $this->propertyGroupRepository $propertyGroupRepository;
  51.         $this->propertyGroupOptionRepository $propertyGroupOptionRepository;
  52.         $this->productReviewLoader $productReviewLoader;
  53.         $this->systemConfigService $systemConfigService;
  54.     }
  55.     public static function getSubscribedEvents(): array
  56.     {
  57.         return [
  58.             'Shopware\Storefront\Page\Product\ProductPageLoadedEvent' => ['productLoaded']
  59.         ];
  60.     }
  61.     public function productLoaded(ProductPageLoadedEvent $event): void
  62.     {
  63.         $this->addReviewDataToProductPage($event);
  64.         $this->addSiblingDataToProductPage($event);
  65.     }
  66.     private function mapToKeyValue($items){
  67.         $keyValue = [];
  68.         foreach ($items as $item) {
  69.             $key $item->getGroupId();
  70.             $value $item->getId();
  71.             if(!array_key_exists($key$keyValue))
  72.                 $keyValue[$key] = [];
  73.             $keyValue[$key][] = $value;
  74.         }
  75.         return $keyValue;
  76.     }
  77.     public function addSiblingDataToProductPage(ProductPageLoadedEvent $event): void
  78.     {
  79.         $this->event $event;
  80.         $context $event->getContext();
  81.         $page $event->getPage();
  82.         $product $page->getProduct();
  83.         $configuratorSettings $page->getConfiguratorSettings();
  84.         //Config variables
  85.         $parentProperty $this->systemConfigService->get('ThemeOkeOnline.config.parentProperty'); //String
  86.         $persistentOptions $this->systemConfigService->get('ThemeOkeOnline.config.persistentOptions'); //Array with strings
  87.         //Show warning on top of page when missing config
  88.         if($parentProperty == null || $persistentOptions == null)
  89.             return;
  90.         //Create key-value arrays for easy reference
  91.         $productOptionsKeyValue $this->mapToKeyValue($product->getOptions());
  92.         $productPropertiesKeyValue $this->mapToKeyValue($product->getProperties());
  93.         //Stop when the product does not have the required properties
  94.         if(sizeof($productPropertiesKeyValue) == || !array_key_exists($parentProperty$productPropertiesKeyValue))
  95.             return;
  96.         //Search for siblings
  97.         $criteria = new Criteria();
  98.         $criteria->addAssociation('name');
  99.         $criteria->addAssociation('properties');
  100.         $criteria->addAssociation('options');
  101.         $criteria->addAssociation('cover');
  102.         $criteria->addFilter(
  103.             new EqualsFilter('properties.id'$productPropertiesKeyValue[$parentProperty][0])
  104.         );
  105.         if(sizeof($productOptionsKeyValue) > 0) foreach($persistentOptions as $option){
  106.             $criteria->addFilter(
  107.             //Always take first value of this option (no multi-selects)
  108.                 new EqualsFilter('options.id'$productOptionsKeyValue[$option][0])
  109.             );
  110.         }
  111.         $data $this->productRepository->search($criteria$context);
  112.         $page->addExtension('siblings'$data);
  113.         return;
  114.     }
  115.     /*
  116.      * Somehow the reviews are not available when using our plugin, but we will get them back!
  117.      */
  118.     public function addReviewDataToProductPage($event): void
  119.     {
  120.         $this->event $event;
  121.         $this->context $event->getSalesChannelContext();
  122.         $this->page $event->getPage();
  123.         $this->request $event->getRequest();
  124.         $this->checkReviewsActive();
  125.         $reviews $this->getProductReviews();
  126.         $this->page->addExtension('reviews'$reviews);
  127.     }
  128.     private function getProductReviews(): Object
  129.     {
  130.         $product $this->page->getProduct();
  131.         $reviews $this->productReviewLoader->load($this->request$this->context);
  132.         $reviews->setParentId($product->getParentId() ?? $product->getId());
  133.         return $reviews;
  134.     }
  135.     /**
  136.      * @throws ReviewNotActiveExeption
  137.      */
  138.     private function checkReviewsActive(): void
  139.     {
  140.         $showReview $this->systemConfigService->get('core.listing.showReview'$this->context->getSalesChannel()->getId());
  141.         if (!$showReview) {
  142.             throw new ReviewNotActiveExeption();
  143.         }
  144.     }
  145. }