<?php
namespace Crehler\MojeBambinoEngine\Subscriber;
use Crehler\MojeBambinoEngine\Service\FilterService;
use Crehler\MojeBambinoEngine\Struct\FilterOrientationStruct;
use Crehler\MojeBambinoEngine\Struct\FilterSettingsStruct;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Property\PropertyGroupCollection;
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
use Shopware\Core\Framework\DataAbstractionLayer\Search\AggregationResult\AggregationResult;
use Shopware\Core\Framework\DataAbstractionLayer\Search\AggregationResult\AggregationResultCollection;
use Shopware\Core\Framework\DataAbstractionLayer\Search\AggregationResult\Metric\EntityResult;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductListingResultSubscriber implements EventSubscriberInterface
{
private FilterService $filterService;
private string $colorFilterOrientation = 'vertical';
public function __construct(FilterService $filterService, SystemConfigService $systemConfigService)
{
$this->filterService = $filterService;
$this->colorFilterOrientation = $systemConfigService->get('CrehlerMojeBambinoEngine.config.colorFilterOrientation') ?? $this->colorFilterOrientation;
}
public static function getSubscribedEvents(): array
{
return [
ProductListingResultEvent::class => 'handleProductListingResult',
];
}
public function handleProductListingResult(ProductListingResultEvent $event): void
{
try {
$result = $event->getResult();
$context = $event->getContext();
$navigationId = $result->getCurrentFilter('navigationId');
$aggregations = $result->getAggregations();
$categorySettings = $this->filterService->getCategorySettings($navigationId, $context);
if (!is_null($categorySettings->getFilterSettings()) && !is_null($categorySettings->getPropertyGroupSettings())) {
$this->sortFilters($aggregations, $categorySettings->getFilterSettings(), $categorySettings->getPropertyGroupSettings());
} else {
$this->addExtensions($aggregations);
}
} catch (\Throwable $exception) {
dd($exception);
}
}
private function sortFilters(AggregationResultCollection $aggregations, EntityCollection $filterSettings, EntityCollection $propertyGroupSettings): void
{
$aggregationsFilters = $aggregations->getElements();
$aggregations->clear();
foreach ($filterSettings as $filterSetting) {
$filterName = $filterSetting->get('name');
if (array_key_exists($filterName, $aggregationsFilters)) {
$filter = $aggregationsFilters[$filterName];
if ($filterName === 'properties') {
$filter = $this->sortProperties($filter, $propertyGroupSettings);
}
if ($filter !== null) {
$filter->addExtension(
'filterSettings',
new FilterSettingsStruct($filterSetting->get('show'), $filterSetting->get('expanded'))
);
$aggregations->add($filter);
}
unset($aggregationsFilters[$filterName]);
}
}
if (!empty($aggregationsFilters)) {
foreach ($aggregationsFilters as $filter) {
$aggregations->add($filter);
}
}
}
private function sortProperties(AggregationResult $filter, EntityCollection $propertyGroupSettings): ?EntityResult
{
if ($filter instanceof EntityResult) {
/** @var PropertyGroupCollection $propertyGroups */
$propertyGroups = $filter->getEntities();
$propertyGroupsIds = $propertyGroups->getIds();
$propertyGroupCollection = new PropertyGroupCollection();
foreach ($propertyGroupSettings as $propertyGroupSetting) {
$propertyGroupId = $propertyGroupSetting->get('propertyGroupId');
$key = array_search($propertyGroupId, $propertyGroupsIds);
if ($key !== false) {
$property = $propertyGroups->get($key);
$property->addExtension(
'orientation',
new FilterOrientationStruct(
$property->getDisplayType() === 'color' ? $this->colorFilterOrientation : null
)
);
$property->addExtension(
'filterSettings',
new FilterSettingsStruct($propertyGroupSetting->get('show'), $propertyGroupSetting->get('expanded'))
);
$propertyGroupCollection->add($property);
$propertyGroups->remove($propertyGroupId);
}
}
if ($propertyGroups->count() > 0) {
foreach ($propertyGroups as $propertyGroup) {
$propertyGroupCollection->add($propertyGroup);
}
}
return new EntityResult('properties', $propertyGroupCollection);
}
return null;
}
private function addExtensions(AggregationResultCollection $aggregations)
{
foreach ($aggregations->getElements() as $name => $filterSetting) {
if ($name === 'properties') {
if ($filterSetting instanceof EntityResult) {
$propertyGroups = $filterSetting->getEntities();
foreach ($propertyGroups->getElements() as $property) {
$property->addExtension(
'orientation',
new FilterOrientationStruct(
$property->getDisplayType() === 'color' ? $this->colorFilterOrientation : null
)
);
}
}
}
}
}
}