<?php declare(strict_types=1);
namespace Uandi\EFB\Storefront\Subscriber;
use Shopware\Core\Content\Product\Events\ProductListingCollectFilterEvent;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\Events\ProductSearchResultEvent;
use Shopware\Core\Content\Product\SalesChannel\Sorting\ProductSortingCollection;
use Shopware\Core\Content\Product\SalesChannel\Sorting\ProductSortingEntity;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductListingSubscriber implements EventSubscriberInterface
{
private const PRICE_FILTER_NAME = 'price';
private const DISABLE_SORTING_CUSTOM_FIELD_KEY = 'product_listing_disable_sorting';
public static function getSubscribedEvents(): array
{
return [
ProductListingCollectFilterEvent::class => 'removePriceFilter',
ProductListingResultEvent::class => 'removeSortingForNotLoggedInUser',
ProductSearchResultEvent::class => 'removeSortingForNotLoggedInUser',
];
}
public function removePriceFilter(ProductListingCollectFilterEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer()) {
return;
}
$filters = $event->getFilters();
if ($filters->has(self::PRICE_FILTER_NAME)) {
$filters->remove(self::PRICE_FILTER_NAME);
}
}
public function removeSortingForNotLoggedInUser(ProductListingResultEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer()) {
return;
}
$customFields = $event->getSalesChannelContext()->getSalesChannel()->getTranslation('customFields');
if (null === $customFields) {
return;
}
$sortingKeys = $customFields[self::DISABLE_SORTING_CUSTOM_FIELD_KEY] ?? null;
if (null === $sortingKeys) {
return;
}
$sortingKeys = array_map('trim', explode(';', $sortingKeys));
$listingResult = $event->getResult();
$this->filterAndReduceSorting($listingResult->getAvailableSortings(), $sortingKeys);
if (false === in_array($listingResult->getSorting(), $sortingKeys)) {
return;
}
$listingResult->setSorting(null);
}
private function filterAndReduceSorting(ProductSortingCollection $availableSortings, array $sortingKeys): void
{
$matchingSortings = $availableSortings->filter(static function (ProductSortingEntity $sorting) use ($sortingKeys) {
return in_array($sorting->getKey(), $sortingKeys);
});
if (0 >= $matchingSortings->count()) {
return;
}
foreach ($matchingSortings as $sorting) {
$availableSortings->remove($sorting->getId());
}
}
}