vendor/shopware/core/Content/Product/Subscriber/ProductSubscriber.php line 90

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\Product\Subscriber;
  3. use Shopware\Core\Content\Product\AbstractIsNewDetector;
  4. use Shopware\Core\Content\Product\AbstractProductMaxPurchaseCalculator;
  5. use Shopware\Core\Content\Product\AbstractProductVariationBuilder;
  6. use Shopware\Core\Content\Product\AbstractPropertyGroupSorter;
  7. use Shopware\Core\Content\Product\AbstractSalesChannelProductBuilder;
  8. use Shopware\Core\Content\Product\DataAbstractionLayer\CheapestPrice\CheapestPriceContainer;
  9. use Shopware\Core\Content\Product\ProductEntity;
  10. use Shopware\Core\Content\Product\ProductEvents;
  11. use Shopware\Core\Content\Product\SalesChannel\Price\AbstractProductPriceCalculator;
  12. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  13. use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionCollection;
  14. use Shopware\Core\Framework\Context;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Entity;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Event\PartialEntityLoadedEvent;
  18. use Shopware\Core\Framework\Feature;
  19. use Shopware\Core\System\SalesChannel\Entity\PartialSalesChannelEntityLoadedEvent;
  20. use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
  21. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  22. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  23. class ProductSubscriber implements EventSubscriberInterface
  24. {
  25.     private AbstractSalesChannelProductBuilder $salesChannelProductBuilder;
  26.     private AbstractProductVariationBuilder $productVariationBuilder;
  27.     private AbstractProductPriceCalculator $calculator;
  28.     private AbstractPropertyGroupSorter $propertyGroupSorter;
  29.     private AbstractProductMaxPurchaseCalculator $maxPurchaseCalculator;
  30.     private AbstractIsNewDetector $isNewDetector;
  31.     /**
  32.      * @internal
  33.      */
  34.     public function __construct(
  35.         AbstractSalesChannelProductBuilder $salesChannelProductBuilder,
  36.         AbstractProductVariationBuilder $productVariationBuilder,
  37.         AbstractProductPriceCalculator $calculator,
  38.         AbstractPropertyGroupSorter $propertyGroupSorter,
  39.         AbstractProductMaxPurchaseCalculator $maxPurchaseCalculator,
  40.         AbstractIsNewDetector $isNewDetector
  41.     ) {
  42.         $this->salesChannelProductBuilder $salesChannelProductBuilder;
  43.         $this->productVariationBuilder $productVariationBuilder;
  44.         $this->calculator $calculator;
  45.         $this->propertyGroupSorter $propertyGroupSorter;
  46.         $this->maxPurchaseCalculator $maxPurchaseCalculator;
  47.         $this->isNewDetector $isNewDetector;
  48.     }
  49.     public static function getSubscribedEvents(): array
  50.     {
  51.         return [
  52.             ProductEvents::PRODUCT_LOADED_EVENT => 'loaded',
  53.             'product.partial_loaded' => 'partialEntityLoaded',
  54.             'sales_channel.' ProductEvents::PRODUCT_LOADED_EVENT => 'salesChannelLoaded',
  55.             'sales_channel.product.partial_loaded' => 'partialSalesChannelLoaded',
  56.         ];
  57.     }
  58.     public function loaded(EntityLoadedEvent $event): void
  59.     {
  60.         $this->entityLoaded($event->getEntities(), $event->getContext());
  61.     }
  62.     /**
  63.      * @internal
  64.      */
  65.     public function partialEntityLoaded(PartialEntityLoadedEvent $event): void
  66.     {
  67.         $this->entityLoaded($event->getEntities(), $event->getContext());
  68.     }
  69.     public function salesChannelLoaded(SalesChannelEntityLoadedEvent $event): void
  70.     {
  71.         $this->productSalesChannelLoaded($event->getEntities(), $event->getSalesChannelContext());
  72.     }
  73.     /**
  74.      * @internal
  75.      */
  76.     public function partialSalesChannelLoaded(PartialSalesChannelEntityLoadedEvent $event): void
  77.     {
  78.         $this->productSalesChannelLoaded($event->getEntities(), $event->getSalesChannelContext());
  79.     }
  80.     /**
  81.      * @param Entity[] $collection
  82.      */
  83.     private function entityLoaded(array $collectionContext $context): void
  84.     {
  85.         /** @var ProductEntity $product */
  86.         foreach ($collection as $product) {
  87.             // CheapestPrice will only be added to SalesChannelProductEntities in the Future
  88.             if (!Feature::isActive('FEATURE_NEXT_16151')) {
  89.                 $price $product->get('cheapestPrice');
  90.                 if ($price instanceof CheapestPriceContainer) {
  91.                     $resolved $price->resolve($context);
  92.                     $product->assign([
  93.                         'cheapestPrice' => $resolved,
  94.                         'cheapestPriceContainer' => $price,
  95.                     ]);
  96.                 }
  97.             }
  98.             $this->productVariationBuilder->build($product);
  99.         }
  100.     }
  101.     /**
  102.      * @param Entity[] $elements
  103.      */
  104.     private function productSalesChannelLoaded(array $elementsSalesChannelContext $context): void
  105.     {
  106.         /** @var SalesChannelProductEntity $product */
  107.         foreach ($elements as $product) {
  108.             if (Feature::isActive('FEATURE_NEXT_16151')) {
  109.                 $price $product->get('cheapestPrice');
  110.                 if ($price instanceof CheapestPriceContainer) {
  111.                     $resolved $price->resolve($context->getContext());
  112.                     $product->assign([
  113.                         'cheapestPrice' => $resolved,
  114.                         'cheapestPriceContainer' => $price,
  115.                     ]);
  116.                 }
  117.             }
  118.             if (Feature::isActive('v6.5.0.0')) {
  119.                 $assigns = [];
  120.                 if (($properties $product->get('properties')) !== null && $properties instanceof PropertyGroupOptionCollection) {
  121.                     $assigns['sortedProperties'] = $this->propertyGroupSorter->sort($properties);
  122.                 }
  123.                 $assigns['calculatedMaxPurchase'] = $this->maxPurchaseCalculator->calculate($product$context);
  124.                 $assigns['isNew'] = $this->isNewDetector->isNew($product$context);
  125.                 $product->assign($assigns);
  126.             } else {
  127.                 Feature::callSilentIfInactive('v6.5.0.0', function () use ($product$context): void {
  128.                     $this->salesChannelProductBuilder->build($product$context);
  129.                 });
  130.             }
  131.         }
  132.         $this->calculator->calculate($elements$context);
  133.     }
  134. }