<?php declare(strict_types=1);
namespace EsmComputer\Storefront\Subscriber;
use EsmComputer\Core\Content\Product\OutOfStockService;
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\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class HideOutOfStockProductsSubscriber implements EventSubscriberInterface
{
protected OutOfStockService $outOfStockService;
public function __construct(
OutOfStockService $outOfStockService
)
{
$this->outOfStockService = $outOfStockService;
}
public static function getSubscribedEvents(): array
{
return [
ProductListingCriteriaEvent::class => [
['handleListingRequest', 200]
],
ProductSuggestCriteriaEvent::class => [
['handleSearchRequest', 200]
],
ProductSearchCriteriaEvent::class => [
['handleSearchRequest', 200]
],
ProductCrossSellingIdsCriteriaEvent::class => [
['handleCrossSellingProductListingRequest', 200]
],
ProductCrossSellingStreamCriteriaEvent::class => [
['handleCrossSellingProductStreamRequest', 200]
],
ProductPageLoadedEvent::class => [
['onProductLoaded', 50]
]
];
}
public function handleCrossSellingProductStreamRequest(ProductCrossSellingStreamCriteriaEvent $event): void
{
$this->outOfStockService->addAvailableCriteria($event->getCriteria());
}
public function handleCrossSellingProductListingRequest(ProductCrossSellingIdsCriteriaEvent $event): void
{
$this->outOfStockService->addAvailableCriteria($event->getCriteria());
}
public function handleListingRequest(ProductListingCriteriaEvent $event): void
{
// Not needed, out of stock products are not visible anyway
// $this->outOfStockService->addAvailableCriteria($event->getCriteria());
}
public function handleSearchRequest(ProductListingCriteriaEvent $event): void
{
$this->outOfStockService->addAvailableCriteria($event->getCriteria());
}
public function onProductLoaded(ProductPageLoadedEvent $event): void
{
$product = $event->getPage()->getProduct();
if(empty($product->getId())) {
return;
}
if($this->outOfStockService->isOutOfStock($product, $event->getSalesChannelContext())) {
throw new NotFoundHttpException();
}
}
}