Can someone give an advice on disabling/ including Shopware 6 properties options in criteria?
I'm able to reach properties names (though filter works a bit not correct in this case, as we need to disable options, not properties) using this filtering:
new PrefixFilter('product.properties.name', 'OptionName1')
But how can I reach options names to disable some of them in this case? Here the Subscriber I have:
namespace CustomFilterBasedOnSelectedOptions\Subscriber;
use ..
class Subscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
ProductListingCriteriaEvent::class => [
['onListingCriteria', -200],
],
];
}
public function onListingCriteria(ProductListingCriteriaEvent $event): void
{
$event->getCriteria()->addAssociation('properties');
$event->getCriteria()->addAssociation('properties.group');
$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();
$criteria = $event->getCriteria();
if (in_array('c0d02d1738fd4293a489695787e06b5c', $currentPropertyOptions)) {
$criteria->addFilter(
new NotFilter(
NotFilter::CONNECTION_OR,
[
new PrefixFilter('product.properties.name', 'OptionName1'), //can get, but we need disable some options
new PrefixFilter('product.options.name', 'OptionName2') // can't get
]
)
);
}
}
}
Furthermore we are going to set this selection available for admin backend setting. So I think, this eventually should be done using IDs? Can someone give a tip on where to move on to set this up to be adjustable via the backend? I mean to assign some options of one property to be available only for some selected options of another property.
P.S. No, this doesn't work using standard features like Variants.
First of all, product.options.name
should be the correct accessor in this case.
I think you might have a misconception in your filter. You're using NotFilter::CONNECTION_OR
as your operator for your NotFilter
. That means either one of the conditions has not to be met. So if product.properties.name
doesn't match, it doesn't matter if product.options.name
matches or not. I think for your use case you might want to use NotFilter::CONNECTION_AND
instead, so both expressions need to not hold true.
new NotFilter(
NotFilter::CONNECTION_AND,
[
new PrefixFilter('product.properties.name', 'OptionName1'),
new PrefixFilter('product.options.name', 'OptionName2'),
]
)
To make this configurable via the administration there are various different approaches. You might want to introduce a custom entity, that has a one-to-one association to an option and a many-to-many association to multiple other options to be excluded. Create a custom module in the administration where you manage your custom entities and set the option with their respective excludes. Then in your listing criteria listener, you could fetch your custom entity by the options included in the filter and set the excludes dynamically from the fetched results.