<?php declare(strict_types=1);
namespace Maxia\MaxiaListingVariants6\Subscriber;
use Doctrine\DBAL\Connection;
use Maxia\MaxiaListingVariants6\Service\CachedProductConfiguratorLoader;
use Maxia\MaxiaListingVariants6\Service\CachedVariantMappingLoader;
use Shopware\Core\Content\Product\Events\ProductChangedEventInterface;
use Shopware\Core\Content\Product\Events\ProductIndexerEvent;
use Shopware\Core\Content\Product\ProductDefinition;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
use Shopware\Core\Framework\Uuid\Uuid;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\Adapter\Cache\CacheInvalidator;
class CacheInvalidationSubscriber implements EventSubscriberInterface
{
private Connection $connection;
private CacheInvalidator $cacheInvalidator;
public function __construct(
CacheInvalidator $cacheInvalidator,
Connection $connection
) {
$this->cacheInvalidator = $cacheInvalidator;
$this->connection = $connection;
}
public static function getSubscribedEvents()
{
return [
ProductIndexerEvent::class => [
['invalidateOnProductIndex', 2000],
],
EntityWrittenContainerEvent::class => [
['invalidateOnEntityWritten', 2000]
],
];
}
public function invalidateOnEntityWritten(EntityWrittenContainerEvent $event): void
{
// invalidate table after product change
$productIds = $event->getPrimaryKeys(ProductDefinition::ENTITY_NAME);
if (empty($productIds)) {
return;
}
$parentIds = $this->connection->fetchFirstColumn(
'SELECT DISTINCT LOWER(HEX(parent_id))
FROM product
WHERE id IN (:productIds) AND parent_id IS NOT NULL AND version_id = :version',
['productIds' => Uuid::fromHexToBytesList($productIds), 'version' => Uuid::fromHexToBytes(Defaults::LIVE_VERSION)],
['productIds' => Connection::PARAM_STR_ARRAY]
);
$parentIds = array_unique($parentIds);
if ($parentIds) {
$this->cacheInvalidator->invalidate(
array_merge(
array_map([CachedVariantMappingLoader::class, 'buildName'], $productIds),
array_map([CachedProductConfiguratorLoader::class, 'buildName'], $parentIds)
)
);
}
}
public function invalidateOnProductIndex(ProductChangedEventInterface $event): void
{
$productIds = $event->getIds();
$parentIds = $this->connection->fetchFirstColumn(
'SELECT DISTINCT LOWER(HEX(COALESCE(parent_id, id)))
FROM product
WHERE id in (:productIds) AND version_id = :version',
['productIds' => $productIds, 'version' => Uuid::fromHexToBytes(Defaults::LIVE_VERSION)],
['productIds' => Connection::PARAM_STR_ARRAY]
);
$parentIds = array_unique($parentIds);
if ($parentIds) {
$this->cacheInvalidator->invalidate(
array_merge(
array_map([CachedVariantMappingLoader::class, 'buildName'], $productIds),
array_map([CachedProductConfiguratorLoader::class, 'buildName'], $parentIds)
)
);
}
}
}