<?php
declare(strict_types=1);
namespace VioCustomerPrice\Subscriber;
use Shopware\Core\Content\Product\SalesChannel\Detail\CachedProductDetailRoute;
use Shopware\Core\Framework\Adapter\Cache\CacheInvalidator;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Bucket\TermsAggregation;
use Shopware\Core\Framework\DataAbstractionLayer\Search\AggregationResult\Bucket\TermsResult;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CacheSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $customerPriceRepository;
private EntityRepositoryInterface $productRepository;
private CacheInvalidator $cacheInvalidator;
public function __construct(
EntityRepositoryInterface $customerPriceRepository,
EntityRepositoryInterface $productRepository,
CacheInvalidator $cacheInvalidator
)
{
$this->customerPriceRepository = $customerPriceRepository;
$this->productRepository = $productRepository;
$this->cacheInvalidator = $cacheInvalidator;
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents(): array
{
return [
'vio_customer_price.written' => 'onCustomerPriceWritten'
];
}
public function onCustomerPriceWritten(EntityWrittenEvent $event): void
{
/** @var TermsResult $productIdsAggregation */
$productIdsAggregation = $this->customerPriceRepository->aggregate(
(new Criteria($event->getIds()))
->addAggregation(
new TermsAggregation(
'productIds',
'productId'
)
),
$event->getContext()
)->get('productIds');
$productIds = array_map(static function($productIdBucket) {
return $productIdBucket->getKey();
}, $productIdsAggregation->getBuckets());
$productIds = array_filter($productIds);
$productIds = array_unique($productIds);
/** @var TermsResult $parentIdsResult */
$parentIdsResult = $this->productRepository
->aggregate(
(new Criteria($productIds))
->addAggregation(
new TermsAggregation(
'parentIds',
'parentId'
)
)
, $event->getContext()
)->get('parentIds');
$parentIds = array_map(static function($productIdBucket) {
return $productIdBucket->getKey();
}, $parentIdsResult->getBuckets());
$parentIds = array_filter($parentIds);
$parentIds = array_unique($parentIds);
$productIds = array_unique(array_merge($productIds, $parentIds));
$tags = array_map([CachedProductDetailRoute::class, 'buildName'], $productIds);
$this->cacheInvalidator->invalidate($tags, true);
}
}