src/Core/Content/Product/Subscriber/ProductSubscriber.php line 59
<?php declare(strict_types=1);
namespace Shopware\Core\Content\Product\Subscriber;
use Shopware\Core\Content\Product\AbstractIsNewDetector;
use Shopware\Core\Content\Product\AbstractProductMaxPurchaseCalculator;
use Shopware\Core\Content\Product\AbstractProductVariationBuilder;
use Shopware\Core\Content\Product\AbstractPropertyGroupSorter;
use Shopware\Core\Content\Product\DataAbstractionLayer\CheapestPrice\CheapestPriceContainer;
use Shopware\Core\Content\Product\ProductDefinition;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Content\Product\SalesChannel\Price\AbstractProductPriceCalculator;
use Shopware\Core\Framework\DataAbstractionLayer\Entity;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\Feature;
use Shopware\Core\Framework\Log\Package;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* @internal
*/
#[Package('inventory')]
class ProductSubscriber implements EventSubscriberInterface
{
/**
* @internal
*/
public function __construct(
private readonly AbstractProductVariationBuilder $productVariationBuilder,
private readonly AbstractProductPriceCalculator $calculator,
private readonly AbstractPropertyGroupSorter $propertyGroupSorter,
private readonly AbstractProductMaxPurchaseCalculator $maxPurchaseCalculator,
private readonly AbstractIsNewDetector $isNewDetector,
private readonly SystemConfigService $systemConfigService
) {
}
public static function getSubscribedEvents(): array
{
return [
ProductEvents::PRODUCT_LOADED_EVENT => 'loaded',
'product.partial_loaded' => 'loaded',
'sales_channel.' . ProductEvents::PRODUCT_LOADED_EVENT => 'salesChannelLoaded',
'sales_channel.product.partial_loaded' => 'salesChannelLoaded',
];
}
public function loaded(EntityLoadedEvent $event): void
{
foreach ($event->getEntities() as $product) {
$this->setDefaultLayout($product);
$this->productVariationBuilder->build($product);
}
}
public function salesChannelLoaded(SalesChannelEntityLoadedEvent $event): void
{
foreach ($event->getEntities() as $product) {
$price = $product->get('cheapestPrice');
if ($price instanceof CheapestPriceContainer) {
$product->assign([
'cheapestPrice' => $price->resolve($event->getContext()),
'cheapestPriceContainer' => $price,
]);
}
$assigns = [];
if (($properties = $product->get('properties')) !== null) {
$assigns['sortedProperties'] = $this->propertyGroupSorter->sort($properties);
}
$assigns['calculatedMaxPurchase'] = $this->maxPurchaseCalculator->calculate($product, $event->getSalesChannelContext());
$assigns['isNew'] = $this->isNewDetector->isNew($product, $event->getSalesChannelContext());
$product->assign($assigns);
$this->setDefaultLayout($product, $event->getSalesChannelContext()->getSalesChannelId());
$this->productVariationBuilder->build($product);
}
$this->calculator->calculate($event->getEntities(), $event->getSalesChannelContext());
}
/**
* @param Entity $product - typehint as Entity because it could be a ProductEntity or PartialEntity
*/
private function setDefaultLayout(Entity $product, ?string $salesChannelId = null): void
{
if (!Feature::isActive('v6.6.0.0') || !$product->has('cmsPageId')) {
return;
}
if ($product->get('cmsPageId') !== null) {
return;
}
$cmsPageId = $this->systemConfigService->get(ProductDefinition::CONFIG_KEY_DEFAULT_CMS_PAGE_PRODUCT, $salesChannelId);
if (!$cmsPageId) {
return;
}
$product->assign(['cmsPageId' => $cmsPageId]);
}
}