<?php declare(strict_types=1);
namespace EsmConfigurator\Storefront\Subscriber;
use EsmConfigurator\Core\Content\ConfigurationGroup\ConfigurationGroupCollection;
use EsmConfigurator\Core\Content\ConfigurationGroup\ConfigurationGroupEntity;
use EsmConfigurator\Core\Content\ConfigurationItem\ConfigurationItemEntity;
use EsmConfigurator\Core\Content\ResultText\ResultTextEntity;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use function array_key_exists;
class ProductSubscriber implements EventSubscriberInterface
{
private EntityRepository $configurationGroupRepository;
private SalesChannelRepositoryInterface $salesChannelProductRepository;
private EntityRepository $resultTextRepository;
private CartService $cartService;
public function __construct(
EntityRepository $configurationGroupRepository,
SalesChannelRepositoryInterface $salesChannelProductRepository,
EntityRepository $resultTextRepository,
CartService $cartService
)
{
$this->configurationGroupRepository = $configurationGroupRepository;
$this->salesChannelProductRepository = $salesChannelProductRepository;
$this->resultTextRepository = $resultTextRepository;
$this->cartService = $cartService;
}
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => [
['onProductLoaded', 50]
]
];
}
public function onProductLoaded(ProductPageLoadedEvent $event): void
{
$product = $event->getPage()->getProduct();
if(empty($product->getId())) {
return;
}
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('articleNumber', $product->getProductNumber()));
$criteria->addSorting(new FieldSorting('sorting'));
$criteria->addAssociation('configurationItems');
$criteria->addAssociation('configurationItems.product');
$criteria->addAssociation('product');
/** @var ConfigurationGroupCollection $configurationGroups */
$configurationGroups = $this->configurationGroupRepository->search($criteria, $event->getContext())->getEntities();
/** @var ConfigurationGroupEntity $configurationGroup */
foreach($configurationGroups as $groupKey => $configurationGroup) {
$configurationItems = $configurationGroup->getConfigurationItems();
if(!$configurationItems) {
$configurationGroups->remove($groupKey);
continue;
}
/** @var ConfigurationItemEntity $configurationItem */
foreach($configurationItems as $itemKey => $configurationItem) {
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('productNumber', $configurationItem->getArticleNumber()));
$criteria->addFilter(new EqualsFilter('active', 1));
$criteria->addFilter(new RangeFilter('availableStock', [RangeFilter::GT => 0]));
$criteria->addExtension('enableUpgrades', new ArrayStruct());
$product = $this->salesChannelProductRepository->search($criteria, $event->getSalesChannelContext())->first();
if(!$product) {
$configurationItems->remove($itemKey);
}
$configurationItem->setProduct($product);
}
$configurationGroup->setConfigurationItems($configurationItems);
if($configurationItems->count() <= 0 ){
$configurationGroups->remove($groupKey);
}
}
if($configurationGroups->count() === 0) {
return;
}
$cart = $this->cartService->getCart($event->getSalesChannelContext()->getToken(), $event->getSalesChannelContext());
foreach($cart->getLineItems() as $lineItem) {
if(!$lineItem->hasChildren()) {
continue;
}
/** @var OrderLineItemEntity $child */
foreach($lineItem->getChildren() as $child) {
if(array_key_exists('configurationGroupId', $child->getPayload())) {
$configurationGroup = $configurationGroups->get($child->getPayload()['configurationGroupId']);
if($configurationGroup) {
$configurationGroup->setActiveItem($child->getPayload()['configurationItemId']);
}
}
}
}
// Set default value to property if exists with same name
foreach($configurationGroups as $configurationGroup) {
$title = $configurationGroup->getTitle();
$properties = $event->getPage()->getProduct()->getProperties();
foreach ($properties as $property) {
if($property->getGroup() && $property->getGroup()->getName() === $title) {
$configurationGroup->setDefaultValue($property->getName());
}
}
}
$event->getPage()->addExtension('configurationGroups', $configurationGroups);
$scores = [];
$resultTexts = $this->resultTextRepository->search(new Criteria(), $event->getContext())->getEntities();
/** @var ResultTextEntity $resultText */
foreach($resultTexts as $resultText) {
$scores[$resultText->getScore()] = $resultText->getChartTitle();
}
$event->getPage()->addExtension('scores', new ArrayStruct($scores));
}
}