src/Core/Content/Product/Subscriber/ProductSubscriber.php line 50

  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\DataAbstractionLayer\CheapestPrice\CheapestPriceContainer;
  8. use Shopware\Core\Content\Product\ProductDefinition;
  9. use Shopware\Core\Content\Product\ProductEvents;
  10. use Shopware\Core\Content\Product\SalesChannel\Price\AbstractProductPriceCalculator;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Entity;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
  13. use Shopware\Core\Framework\Feature;
  14. use Shopware\Core\Framework\Log\Package;
  15. use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
  16. use Shopware\Core\System\SystemConfig\SystemConfigService;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. /**
  19.  * @internal
  20.  */
  21. #[Package('inventory')]
  22. class ProductSubscriber implements EventSubscriberInterface
  23. {
  24.     /**
  25.      * @internal
  26.      */
  27.     public function __construct(
  28.         private readonly AbstractProductVariationBuilder $productVariationBuilder,
  29.         private readonly AbstractProductPriceCalculator $calculator,
  30.         private readonly AbstractPropertyGroupSorter $propertyGroupSorter,
  31.         private readonly AbstractProductMaxPurchaseCalculator $maxPurchaseCalculator,
  32.         private readonly AbstractIsNewDetector $isNewDetector,
  33.         private readonly SystemConfigService $systemConfigService
  34.     ) {
  35.     }
  36.     public static function getSubscribedEvents(): array
  37.     {
  38.         return [
  39.             ProductEvents::PRODUCT_LOADED_EVENT => 'loaded',
  40.             'product.partial_loaded' => 'loaded',
  41.             'sales_channel.' ProductEvents::PRODUCT_LOADED_EVENT => 'salesChannelLoaded',
  42.             'sales_channel.product.partial_loaded' => 'salesChannelLoaded',
  43.         ];
  44.     }
  45.     public function loaded(EntityLoadedEvent $event): void
  46.     {
  47.         foreach ($event->getEntities() as $product) {
  48.             $this->setDefaultLayout($product);
  49.             $this->productVariationBuilder->build($product);
  50.         }
  51.     }
  52.     public function salesChannelLoaded(SalesChannelEntityLoadedEvent $event): void
  53.     {
  54.         foreach ($event->getEntities() as $product) {
  55.             $price $product->get('cheapestPrice');
  56.             if ($price instanceof CheapestPriceContainer) {
  57.                 $product->assign([
  58.                     'cheapestPrice' => $price->resolve($event->getContext()),
  59.                     'cheapestPriceContainer' => $price,
  60.                 ]);
  61.             }
  62.             $assigns = [];
  63.             if (($properties $product->get('properties')) !== null) {
  64.                 $assigns['sortedProperties'] = $this->propertyGroupSorter->sort($properties);
  65.             }
  66.             $assigns['calculatedMaxPurchase'] = $this->maxPurchaseCalculator->calculate($product$event->getSalesChannelContext());
  67.             $assigns['isNew'] = $this->isNewDetector->isNew($product$event->getSalesChannelContext());
  68.             $product->assign($assigns);
  69.             $this->setDefaultLayout($product$event->getSalesChannelContext()->getSalesChannelId());
  70.             $this->productVariationBuilder->build($product);
  71.         }
  72.         $this->calculator->calculate($event->getEntities(), $event->getSalesChannelContext());
  73.     }
  74.     /**
  75.      * @param Entity $product - typehint as Entity because it could be a ProductEntity or PartialEntity
  76.      */
  77.     private function setDefaultLayout(Entity $product, ?string $salesChannelId null): void
  78.     {
  79.         if (!Feature::isActive('v6.6.0.0') || !$product->has('cmsPageId')) {
  80.             return;
  81.         }
  82.         if ($product->get('cmsPageId') !== null) {
  83.             return;
  84.         }
  85.         $cmsPageId $this->systemConfigService->get(ProductDefinition::CONFIG_KEY_DEFAULT_CMS_PAGE_PRODUCT$salesChannelId);
  86.         if (!$cmsPageId) {
  87.             return;
  88.         }
  89.         $product->assign(['cmsPageId' => $cmsPageId]);
  90.     }
  91. }