<?php declare(strict_types=1);
namespace Nd\Fashion\Subscriber;
use DateTime;
use Nd\Fashion\Service\ProductManufacturerUrlService;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaEntity;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Content\Product\SalesChannel\Detail\ProductConfiguratorLoader;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\ProductEvents;
class AddChildrenToProductPage implements EventSubscriberInterface
{
private SalesChannelRepositoryInterface $productRepository;
private ProductManufacturerUrlService $productManufacturerUrlService;
public function __construct(SalesChannelRepositoryInterface $productRepository,
ProductManufacturerUrlService $productManufacturerUrlService)
{
$this->productRepository = $productRepository;
$this->productManufacturerUrlService = $productManufacturerUrlService;
}
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded'
];
}
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
$product = $event->getPage()->getProduct();
$context = $event->getSalesChannelContext();
if ($context->hasState('elasticsearchAware')) {
$context->removeState('elasticsearchAware');
}
if ($product->getParentId() == null && $product->getChildCount() > 0 && $product->getChildren() == null) {
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $product->getId()));
$criteria->addAssociation("configuratorSettings.option.group");
$productsWithConfiguratorSettings = $this->productRepository->search($criteria, $context);
if ($productsWithConfiguratorSettings->count() != 1) {
return;
}
$productWithConfiguratorSettings = $productsWithConfiguratorSettings->first();
$configuratorSettings = $productWithConfiguratorSettings->getConfiguratorSettings();
$optionSorting = [];
foreach ($configuratorSettings as $configuratorSetting) {
while (in_array($configuratorSetting->getPosition(), array_keys($optionSorting))) {
$configuratorSetting->setPosition($configuratorSetting->getPosition() + 1);
}
$optionSorting[$configuratorSetting->getPosition()] = $configuratorSetting->getOptionId();
}
ksort($optionSorting);
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('parentId', $product->getId()));
$criteria->addAssociation("options");
$children = $this->productRepository->search($criteria, $context);
$optionSortingFlipped = array_flip($optionSorting);
$productSorting = [];
foreach ($children as $child) {
if (!$child->getOptionIds()) {
continue;
}
$id = $child->getOptionIds()[0];
if (!$id || !in_array($id, array_keys($optionSortingFlipped))) {
continue;
}
$productSorting[$optionSortingFlipped[$id]] = $child->getId();
}
ksort($productSorting);
if (count($productSorting) > 0) {
$children->getEntities()->sortByIdArray($productSorting);
}
$product->setChildren($children->getEntities());
$event->getPage()->setProduct($product);
}
if ($product->getManufacturer() && !in_array("url", $product->getManufacturer()->getExtensions())) {
$manufacturer = $product->getManufacturer();
$url = $this->productManufacturerUrlService->retrieveUrl($manufacturer, $context);
$manufacturer->addExtension("url", new ArrayStruct([$url]));
}
}
}