<?php declare(strict_types=1);
namespace Acris\CustomerGroupAvailableProduct\Storefront\Subscriber;
use Acris\CustomerGroupAvailableProduct\Components\DisplayAllowedProductService;
use Shopware\Core\Content\Product\Events\ProductCrossSellingIdsCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductCrossSellingStreamCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductSearchCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductSuggestCriteriaEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductListingFeaturesSubscriber implements EventSubscriberInterface
{
/**
* @var DisplayAllowedProductService
*/
private $displayProductService;
/**
* @var SystemConfigService
*/
private $configService;
public function __construct(DisplayAllowedProductService $displayProductService, SystemConfigService $configService)
{
$this->displayProductService = $displayProductService;
$this->configService = $configService;
}
public static function getSubscribedEvents()
{
return [
ProductListingCriteriaEvent::class => [
['handleListingRequest', 200]
],
ProductSuggestCriteriaEvent::class => [
['handleSearchRequest', 200]
],
ProductSearchCriteriaEvent::class => [
['handleSearchRequest', 200]
],
ProductCrossSellingIdsCriteriaEvent::class => [
['handleCrossSellingProductListingRequest', 200]
],
ProductCrossSellingStreamCriteriaEvent::class => [
['handleCrossSellingProductStreamRequest', 200]
]
];
}
public function handleCrossSellingProductStreamRequest(ProductCrossSellingStreamCriteriaEvent $event): void
{
$this->addDisplayProductIdsForCriteria($event->getCriteria(), $event->getSalesChannelContext());
}
public function handleCrossSellingProductListingRequest(ProductCrossSellingIdsCriteriaEvent $event): void
{
$this->addDisplayProductIdsForCriteria($event->getCriteria(), $event->getSalesChannelContext());
}
public function handleListingRequest(ProductListingCriteriaEvent $event): void
{
$this->addDisplayProductIdsForCriteria($event->getCriteria(), $event->getSalesChannelContext());
}
public function handleSearchRequest(ProductListingCriteriaEvent $event): void
{
$this->addDisplayProductIdsForCriteria($event->getCriteria(), $event->getSalesChannelContext());
}
private function addDisplayProductIdsForCriteria(Criteria $criteria, SalesChannelContext $salesChannelContext)
{
$displayProductIds = $this->displayProductService->getDisplayProductIdsForCustomerGroupId($salesChannelContext->getCurrentCustomerGroup()->getId(), $salesChannelContext->getContext());
if(empty($displayProductIds) === true) {
if($this->configService->get('AcrisCustomerGroupAvailableProductCS.config.releaseProductsIfNoCustomerGroupAssigned', $salesChannelContext->getSalesChannel()->getId()) === DisplayAllowedProductService::DEFAULT_PLUGIN_CONFIG_RELEASE_PRODUCT_IF_NO_CUSTOMER_GROUPS_ASSIGNED) {
$criteria->addAssociation('product.customerGroup');
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
new EqualsFilter('id', Uuid::randomHex()),
new EqualsFilter('product.customerGroup.id', null),
]));
return;
}
$criteria->addFilter(new EqualsFilter('id', Uuid::randomHex()));
} else {
$criteria->addFilter(new EqualsAnyFilter('id', $displayProductIds));
}
}
}