<?php
declare(strict_types=1);
namespace Bodymed\Webshop\Core\Subscriber;
use Bodymed\Webshop\Constants;
use Bodymed\Webshop\Core\Content\CustomerProductFeature\CustomerProductFeatureEntity;
use Bodymed\Webshop\Core\Content\Product\SalesChannel\Product\CustomerProductVisibilityFilter;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Content\Product\Events\ProductCrossSellingCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductCrossSellingStreamCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductGatewayCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\Events\ProductSearchCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductSearchResultEvent;
use Shopware\Core\Content\Product\Events\ProductSuggestCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductSuggestResultEvent;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
use Shopware\Storefront\Page\Product\QuickView\MinimalQuickViewPageCriteriaEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* @see https://madcode.atlassian.net/browse/BODYMED-297
*/
class ProductVisibilitySubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
/*ProductListingResultEvent::class => 'onProductListingResult',
ProductSearchResultEvent::class => 'onProductSearchResult',
ProductSuggestResultEvent::class => 'onProductSuggestResult',*/
ProductListingCriteriaEvent::class => 'onProductListingCriteria',
ProductSearchCriteriaEvent::class => 'onProductSearchCriteria',
ProductSuggestCriteriaEvent::class => 'onProductSuggestCriteria',
ProductCrossSellingCriteriaEvent::class => 'onProductCrossSellingCriteria',
ProductCrossSellingStreamCriteriaEvent::class => 'onProductCrossSellingStreamCriteria',
ProductGatewayCriteriaEvent::class => 'onProductGatewayCriteria',
ProductPageCriteriaEvent::class => 'onProductPageCriteria',
MinimalQuickViewPageCriteriaEvent::class => 'onMinimalQuickViewPageCriteria',
];
}
public function onProductListingResult(ProductListingResultEvent $event): void
{
#$this->hideInvisibleProducts($event);
}
public function onProductSearchResult(ProductSearchResultEvent $event): void
{
#$this->hideInvisibleProducts($event);
}
public function onProductSuggestResult(ProductSuggestResultEvent $event): void
{
#$this->hideInvisibleProducts($event);
}
private function hideInvisibleProducts(ProductListingResultEvent $event): void
{
/* @var $product ProductEntity */
foreach ($event->getResult() as $product) {
if ($product->hasExtension(Constants::CUSTOMER_PRODUCT_FEATURE_EXTENSION_KEY)) {
/* @var $customerProductFeature CustomerProductFeatureEntity */
$customerProductFeature = $product->getExtension(Constants::CUSTOMER_PRODUCT_FEATURE_EXTENSION_KEY);
if ($customerProductFeature instanceof CustomerProductFeatureEntity
&& $customerProductFeature->getVisible() === false
) {
$event->getResult()->remove($customerProductFeature->getProductId());
}
}
}
}
public function onMinimalQuickViewPageCriteria(MinimalQuickViewPageCriteriaEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer() !== null) {
$this->addCustomerProductFeatureCriteria(
$event->getCriteria(),
$event->getSalesChannelContext()->getCustomer()
);
}
}
public function onProductCrossSellingCriteria(ProductCrossSellingCriteriaEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer() !== null) {
$this->addCustomerProductFeatureCriteria(
$event->getCriteria(),
$event->getSalesChannelContext()->getCustomer()
);
}
}
public function onProductCrossSellingStreamCriteria(ProductCrossSellingStreamCriteriaEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer() !== null) {
$this->addCustomerProductFeatureCriteria(
$event->getCriteria(),
$event->getSalesChannelContext()->getCustomer()
);
}
}
public function onProductGatewayCriteria(ProductGatewayCriteriaEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer() !== null) {
$this->addCustomerProductFeatureCriteria(
$event->getCriteria(),
$event->getSalesChannelContext()->getCustomer()
);
}
}
public function onProductListingCriteria(ProductListingCriteriaEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer() !== null) {
$this->addCustomerProductFeatureCriteria(
$event->getCriteria(),
$event->getSalesChannelContext()->getCustomer()
);
}
}
public function onProductSearchCriteria(ProductSearchCriteriaEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer() !== null) {
$this->addCustomerProductFeatureCriteria(
$event->getCriteria(),
$event->getSalesChannelContext()->getCustomer()
);
}
}
public function onProductSuggestCriteria(ProductSuggestCriteriaEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer() !== null) {
$this->addCustomerProductFeatureCriteria(
$event->getCriteria(),
$event->getSalesChannelContext()->getCustomer()
);
}
}
public function onProductPageCriteria(ProductPageCriteriaEvent $event): void
{
if ($event->getSalesChannelContext()->getCustomer() !== null) {
$this->addCustomerProductFeatureCriteria(
$event->getCriteria(),
$event->getSalesChannelContext()->getCustomer()
);
}
}
private function addCustomerProductFeatureCriteria(Criteria $criteria, CustomerEntity $customer): void
{
$customerId = $customer->getId();
$criteria->addAssociation(Constants::CUSTOMER_PRODUCT_FEATURE_EXTENSION_KEY);
$criteria->addFilter(new CustomerProductVisibilityFilter($customerId));
}
}