<?php
declare(strict_types=1);
namespace MadProductVisibility\Subscriber;
use MadProductVisibility\Struct\NotEqualsAnyFilter;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductSearchCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductSuggestCriteriaEvent;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NandFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NorFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\SingleFieldFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\XOrFilter;
use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $productRepository;
private EntityRepositoryInterface $tagRepository;
public function __construct(
EntityRepositoryInterface $productRepository,
EntityRepositoryInterface $tagRepository
) {
$this->productRepository = $productRepository;
$this->tagRepository = $tagRepository;
}
public static function getSubscribedEvents(): array
{
// Return the events to listen to as array like this: <event to listen to> => <method to execute>
return [
#ProductEvents::PRODUCT_LOADED_EVENT => 'onProductsLoaded',
ProductPageCriteriaEvent::class => 'onProductPageCriteriaEvent',
ProductListingCriteriaEvent::class => 'onProductListingCriteriaEvent',
ProductSuggestCriteriaEvent::class => 'onProductSuggestCriteriaEvent',
ProductEvents::PRODUCT_SEARCH_CRITERIA => 'onProductSearchCriteriaEvent',
ProductSearchCriteriaEvent::class => 'onProductSearchCriteriaEvent',
];
}
public function onProductListingCriteriaEvent(ProductListingCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('madProductRoleBlacklist');
$customer = $event->getSalesChannelContext()->getCustomer();
if ($customer === null || $customer->getTagIds() === null) {
return;
}
$this->addBlacklistedTagsFilter($customer, $criteria);
}
public function onProductPageCriteriaEvent(ProductPageCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('madProductRoleBlacklist');
$customer = $event->getSalesChannelContext()->getCustomer();
if ($customer === null || $customer->getTagIds() === null) {
return;
}
$this->addBlacklistedTagsFilter($customer, $criteria);
}
public function onProductSearchCriteriaEvent(ProductSearchCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('madProductRoleBlacklist');
$customer = $event->getSalesChannelContext()->getCustomer();
if ($customer === null || $customer->getTagIds() === null) {
return;
}
$this->addBlacklistedTagsFilter($customer, $criteria);
}
public function onProductSuggestCriteriaEvent(ProductListingCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('madProductRoleBlacklist');
$customer = $event->getSalesChannelContext()->getCustomer();
if ($customer === null || $customer->getTagIds() === null) {
return;
}
$this->addBlacklistedTagsFilter($customer, $criteria);
}
private function addBlacklistedTagsFilter(CustomerEntity $customer, Criteria $criteria): void
{
$customerTags = $customer->getTagIds();
$blacklistedTags = [];
foreach ($customerTags as $customerTagId) {
$blacklistedTags[] = new EqualsFilter('madProductRoleBlacklist.id', $customerTagId);
}
$criteria->addFilter(
new NorFilter(
$blacklistedTags
)
);
}
public function onProductsLoaded(EntityLoadedEvent $event): void
{
return;
}
}