<?php declare(strict_types=1);
namespace LogBchange\Subscriber;
use LogBchange\Service\HighlightPropertyService;
use Shopware\Core\Content\Product\Events\ProductListingCollectFilterEvent;
use Shopware\Core\Content\Product\SalesChannel\Listing\Filter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\StatsAggregation;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
class ProductListingSubscriber implements EventSubscriberInterface
{
private HighlightPropertyService $highlightPropertyService;
public function __construct(HighlightPropertyService $highlightPropertyService)
{
$this->highlightPropertyService = $highlightPropertyService;
}
public static function getSubscribedEvents(): array
{
return [
ProductListingCollectFilterEvent::class => 'addDurationFilter',
ProductEvents::PRODUCT_LISTING_CRITERIA => 'onProductListingCriteria',
ProductEvents::PRODUCT_LISTING_RESULT => 'onProductListingResult',
];
}
public function addDurationFilter(ProductListingCollectFilterEvent $event): void
{
// fetch existing filters
$filters = $event->getFilters();
$request = $event->getRequest();
$min = $request->get('min-duration');
$max = $request->get('max-duration');
$range = [];
if ($min !== null && $min >= 0) {
$range[RangeFilter::GTE] = $min;
}
if ($max !== null && $max >= 0) {
$range[RangeFilter::LTE] = $max;
}
$filter = new Filter(
// unique name of the filter
'duration',
// defines if this filter is active
!empty($range),
// Defines aggregations behind a filter. A filter can contain multiple aggregations like properties
[new StatsAggregation('duration', 'product.customFields.custom_product_fields_duration', true, true, false, false)],
// defines the DAL filter which should be added to the criteria
new RangeFilter('product.customFields.custom_product_fields_duration', $range),
// defines the values which will be added as currentFilter to the result
[
'min' => (float) $request->get('min-duration'),
'max' => (float) $request->get('max-duration'),
]
);
// Add your custom filter
$filters->add($filter);
}
public function onProductListingCriteria(ProductListingCriteriaEvent $event): void
{
$event->getCriteria()->addAssociation('properties.media');
$event->getCriteria()->addAssociation('properties.group');
}
public function onProductListingResult(ProductListingResultEvent $event): void
{
foreach ($event->getResult()->getEntities() as $product) {
$this->highlightPropertyService->enrichHighlightProperties($product);
}
}
}