<?php
namespace Maxia\MaxiaListingVariants6\Service;
use Monolog\Logger;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\Framework\Adapter\Cache\AbstractCacheTracer;
use Shopware\Core\Framework\Adapter\Cache\CacheCompressor;
use Shopware\Core\Framework\DataAbstractionLayer\Cache\EntityCacheKeyGenerator;
use Shopware\Core\Framework\DataAbstractionLayer\FieldSerializer\JsonFieldSerializer;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
class CachedVariantMappingLoader implements VariantMappingLoaderInterface {
protected Logger $logger;
protected RequestStack $requestStack;
protected VariantMappingLoaderInterface $variantMappingLoader;
protected TagAwareAdapterInterface $cache;
protected EntityCacheKeyGenerator $generator;
protected AbstractCacheTracer $tracer;
public function __construct(
Logger $logger,
RequestStack $requestStack,
VariantMappingLoaderInterface $variantMappingLoader,
TagAwareAdapterInterface $cache,
EntityCacheKeyGenerator $generator,
AbstractCacheTracer $tracer)
{
$this->logger = $logger;
$this->requestStack = $requestStack;
$this->cache = $cache;
$this->generator = $generator;
$this->tracer = $tracer;
$this->variantMappingLoader = $variantMappingLoader;
}
public function loadAllMappings(ProductEntity $product, SalesChannelContext $context): array
{
$item = $this->cache->getItem(
$this->generateKey($product, $context)
);
try {
if ($item->isHit() && $item->get()) {
return CacheCompressor::uncompress($item);
}
} catch (\Throwable $e) {
$this->logger->error($e->getMessage());
}
$name = static::buildName($product->getId());
$result = $this->tracer->trace($name, function () use ($product, $context) {
return $this->variantMappingLoader->loadAllMappings($product, $context);
});
$item = CacheCompressor::compress($item, $result);
$item->tag($this->generateTags($product->getId(), $context));
$this->cache->save($item);
return $result;
}
public static function buildName(string $productId): string
{
return 'maxia-variant-mappings-' . $productId;
}
protected function generateKey(SalesChannelProductEntity $product, SalesChannelContext $context): string
{
$parts = [
static::buildName($product->getId()),
$this->requestStack->getMainRequest()->query->get('expandOptions', false),
$this->generator->getSalesChannelContextHash($context),
];
return md5(JsonFieldSerializer::encodeJson($parts));
}
private function generateTags(string $productId,
SalesChannelContext $context): array
{
$tags = array_merge(
$this->tracer->get(self::buildName($productId)),
[self::buildName($productId), 'maxia-variant-mappings'],
);
return array_unique($tags);
}
}