How can I make it work so that I can filter the criteria depending on the getCurrentFilter('properties') result?
So that the selected properties can be included in the criteria. Now it doesn't work because of the event sequence.
Can I tell Symfony to reload the page to get it?
Does anyone know of another Event to implement this?
<?php // declare(strict_types=1);
namespace CustomFilterBasedOnSelectedOptions\Subscriber;
class Subscriber implements EventSubscriberInterface
{
private ?array $currentPropertyOptions = null;
public static function getSubscribedEvents(): array
{
return [
ProductListingCriteriaEvent::class => 'ListingCriteria',
ProductListingResultEvent::class => 'ListingResult'
];
}
public function ListingResult(ProductListingResultEvent $event)
{
$properties = $event->getResult();
$this->currentPropertyOptions = $properties->getCurrentFilter('properties');
}
public function ListingCriteria(ProductListingCriteriaEvent $event): void
{
$event->getCriteria()->addAssociation('properties');
$event->getCriteria()->addAssociation('properties.group');
$currentPropertyOptions = $this->currentPropertyOptions;
/*
if (in_array('c0d02d1738fd4293a489695787e06b5c', $currentPropertyOptions)) {
$criteria = $event->getCriteria();
$criteria->addFilter(new MultiFilter(
MultiFilter::CONNECTION_OR,
[
new ContainsFilter('product.properties.name', 'Option1'),
new ContainsFilter('product.properties.name', 'Option2')
]
)
);
}
*/
}
}
If my assumption of what you're trying to do is correct, you don't need a property to memoize filter values in between two events. When the filters are constructed, they're stored as an extension of Criteria
. You just need to subscribe to ProductListingCriteriaEvent
with a low enough priority, so the extension will already have been set by the time your listener is called. By setting the priority to -200
it should be low enough.
Then it's just a matter of checking if the extension with the FilterCollection
is set and includes the Filter
with the key properties
, to extract filter values.
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\SalesChannel\Listing\Filter;
use Shopware\Core\Content\Product\SalesChannel\Listing\FilterCollection;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class Subscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
ProductListingCriteriaEvent::class => [
['onListingCriteria', -200],
],
];
}
public function onListingCriteria(ProductListingCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$filters = $criteria->getExtension('filters');
if (!$filters instanceof FilterCollection) {
return;
}
$propertyFilter = $filters->get('properties');
if (!$propertyFilter instanceof Filter || !\is_array($propertyFilter->getValues())) {
return;
}
$currentPropertyOptions = $propertyFilter->getValues();
// ...
}
}