<?php
declare(strict_types=1);
namespace FourtwosixThemeCustomization\Subscriber;
use Doctrine\DBAL\Connection;
use Shopware\Core\Content\Product\ProductEntity;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Framework\Api\Context\AdminApiSource;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\Uuid\Uuid;
class ProductSoldOutSubscriber implements EventSubscriberInterface
{
private Connection $connection;
public function __construct(
Connection $connection,
) {
$this->connection = $connection;
}
public static function getSubscribedEvents(): array
{
return [
ProductEvents::PRODUCT_LOADED_EVENT => 'onProductsLoaded',
];
}
public function onProductsLoaded(EntityLoadedEvent $event): void
{
if ($event->getContext()->getSource() instanceof AdminApiSource) {
return;
}
$products = $event->getEntities();
/** @var ProductEntity $product */
foreach ($products as $product) {
$soldOutPDP = $product->getAvailableStock() <= 0 && $product->getIsCloseout();
$soldOutPLP = $soldOutPDP;
$parentId = null;
if ($product->getChildCount()) {
$parentId = $product->getId();
} elseif ($product->getParentId()) {
$parentId = $product->getParentId();
}
if ($parentId) {
$variants = $this->getVariants($parentId);
foreach ($variants as $variant) {
if ($variant['is_closeout'] === null) {
$variant['is_closeout'] = $variant['parent_is_closeout'];
}
$soldOutPLP = $variant['available_stock'] <= 0 && $variant['is_closeout'] > 0;
if (!$soldOutPLP) {
break;
}
}
}
$this->setSoldOut($product, $soldOutPLP, $soldOutPDP);
}
}
private function getVariants(string $parentId): array
{
$query = "SELECT p.available_stock, p.is_closeout, pp.is_closeout as 'parent_is_closeout'
FROM `product` p
INNER JOIN `product` pp ON p.parent_id = pp.id
WHERE p.parent_id = ?";
return $this->connection->executeQuery($query, [Uuid::fromHexToBytes($parentId)])->fetchAllAssociative();
}
private function setSoldOut(ProductEntity $product, bool $soldOutPLP, bool $soldOutPDP): void
{
$extensions = $product->getExtensions();
$extensions['isSoldOutPLP'] = $soldOutPLP;
$extensions['isSoldOutPDP'] = $soldOutPDP;
$product->setExtensions($extensions);
}
}