<?php declare(strict_types=1);
namespace Acris\CookieConsent\Subscriber;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\PlatformRequest;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Framework\Cache\CacheResponseSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class ResponseCacheSubscriber implements EventSubscriberInterface
{
public const CACHE_HASH_EXTENSION = 'acris_cache_hash';
public static function getSubscribedEvents()
{
return [
KernelEvents::RESPONSE => [
['setResponseCache', -2000]
]
];
}
public function addToCacheHash($value, SalesChannelContext $context)
{
if($context->hasExtension(self::CACHE_HASH_EXTENSION) === true) {
/** @var ArrayStruct $cacheHashExtension */
$cacheHashExtension = $context->getExtension(self::CACHE_HASH_EXTENSION);
} else {
$cacheHashExtension = new ArrayStruct();
}
$context->addExtension(self::CACHE_HASH_EXTENSION, $this->getCacheHashExtension($value, $cacheHashExtension));
}
public function setResponseCache(ResponseEvent $event)
{
$response = $event->getResponse();
$context = $event->getRequest()->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
if (!$context instanceof SalesChannelContext) {
return;
}
if($context->hasExtension(self::CACHE_HASH_EXTENSION) !== true) {
return;
}
/** @var ArrayStruct $acrisCacheHashExtension */
$acrisCacheHashExtension = $context->getExtension(self::CACHE_HASH_EXTENSION);
$acrisCacheHash = $this->generateCacheHashFromExtension($acrisCacheHashExtension);
if ($context->getCustomer()) {
$cacheHash = $this->buildCacheHash($context, $acrisCacheHash);
} else {
$cacheHash = $acrisCacheHash;
}
$response->headers->setCookie(new Cookie(CacheResponseSubscriber::CONTEXT_CACHE_COOKIE, $cacheHash));
}
public function generateCacheHash($value)
{
return $this->generateCacheHashFromExtension($this->getCacheHashExtension($value));
}
private function getCacheHashExtension($value, ?ArrayStruct $cacheHashExtension = null): ArrayStruct
{
if($cacheHashExtension === null) {
$cacheHashExtension = new ArrayStruct();
}
$encodedValue = md5(json_encode($value));
$cacheHashExtension->set($encodedValue, $encodedValue);
return $cacheHashExtension;
}
private function generateCacheHashFromExtension(ArrayStruct $cacheHashExtension): string
{
return md5(json_encode($cacheHashExtension->all()));
}
private function buildCacheHash(SalesChannelContext $context, $acrisCacheHash): string
{
return md5(json_encode([
$context->getRuleIds(),
$context->getContext()->getVersionId(),
$context->getCurrency()->getId(),
$acrisCacheHash
]));
}
}