<?php
namespace Maxia\MaxiaListingVariants6\Core\Content\Product\Cms;
use Maxia\MaxiaListingVariants6\Service\ConfigService;
use Maxia\MaxiaListingVariants6\Service\ListingVariantsLoader;
use Monolog\Logger;
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
use Shopware\Core\Content\Cms\DataResolver\CriteriaCollection;
use Shopware\Core\Content\Cms\DataResolver\Element\AbstractCmsElementResolver;
use Shopware\Core\Content\Cms\DataResolver\Element\CmsElementResolverInterface;
use Shopware\Core\Content\Cms\DataResolver\Element\ElementDataCollection;
use Shopware\Core\Content\Cms\DataResolver\FieldConfig;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
use Shopware\Core\Content\Cms\SalesChannel\Struct\ProductBoxStruct;
use Shopware\Core\Content\Product\ProductDefinition;
use Shopware\Core\Content\Product\ProductEntity;
class ProductBoxCmsElementResolver extends AbstractCmsElementResolver
{
/**
* @var Logger
*/
protected $logger;
/**
* @var CmsElementResolverInterface
*/
protected $parent;
/**
* @var ListingVariantsLoader
*/
protected $listingVariantsLoader;
/**
* @var ConfigService
*/
protected $configService;
/**
* @param Logger $logger
* @param CmsElementResolverInterface $parent
* @param ListingVariantsLoader $variantListingService
* @param ConfigService $configService
*/
public function __construct(
Logger $logger,
CmsElementResolverInterface $parent,
ListingVariantsLoader $variantListingService,
ConfigService $configService
) {
$this->logger = $logger;
$this->parent = $parent;
$this->listingVariantsLoader = $variantListingService;
$this->configService = $configService;
}
public function getType(): string
{
return $this->parent->getType();
}
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
$config = $this->configService->getBaseConfig($resolverContext->getSalesChannelContext());
if (!$config->isPluginEnabled()) {
return $this->parent->collect($slot, $resolverContext);
}
$request = $resolverContext->getRequest();
$route = $request->attributes->get('_route');
if ($route === 'frontend.plugins.maxia-listing-variants.product-box') {
// build different criteria on selection change
$criteriaCollection = new CriteriaCollection();
$criteria = $this->listingVariantsLoader->buildCriteria($request, $resolverContext->getSalesChannelContext());
$criteriaCollection->add('product_' . $slot->getUniqueIdentifier(), ProductDefinition::class, $criteria);
$config = $slot->getFieldConfig();
$config->set('product', new FieldConfig(
'product',
FieldConfig::SOURCE_STATIC,
$criteria->getFilters()[0]->getValue()
));
return $criteriaCollection;
}
return $this->parent->collect($slot, $resolverContext);
}
public function enrich(CmsSlotEntity $slot, ResolverContext $resolverContext, ElementDataCollection $result): void
{
$this->parent->enrich($slot, $resolverContext, $result);
$config = $this->configService->getBaseConfig($resolverContext->getSalesChannelContext());
if (!$config->isPluginEnabled()) {
return;
}
/** @var ProductBoxStruct $productBox */
$productBox = $slot->getData();
if (!$productBox instanceof ProductBoxStruct) return;
$product = $productBox->getProduct();
if (!$product instanceof ProductEntity) return;
$config = $this->configService->getProductConfig($product, $slot, $resolverContext->getSalesChannelContext());
$product->addExtension('maxiaListingVariants', $config);
try {
if (!$product->getParentId() && $product->getChildCount()) {
// avoid issues when main product is overridden with the preselected variant
$product = clone $product;
}
$this->listingVariantsLoader->load([$product], $resolverContext->getSalesChannelContext());
$productBox->setProduct($product);
$productBox->setProductId($product->getId());
} catch (\Exception $e) {
$this->logger->error('Error when loading variants in ProductBoxCmsElementResolver: '.
$e->getMessage().",\nStack trace: ".$e->getTraceAsString());
}
}
}