<?php declare(strict_types=1);
namespace DvdwDirectory\Framework\Cache;
use DvdwDirectory\Content\Product\Service\ProductCountService;
use Shopware\Core\PlatformRequest;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Framework\Routing\MaintenanceModeResolver;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class CacheResponseSubscriber implements EventSubscriberInterface
{
public const COOKIE_NAME = 'pagesOrder';
private bool $httpCacheEnabled;
private MaintenanceModeResolver $maintenanceResolver;
private ProductCountService $productCountService;
private SystemConfigService $systemConfigService;
public function __construct(
bool $httpCacheEnabled,
MaintenanceModeResolver $maintenanceModeResolver,
ProductCountService $productCountService,
SystemConfigService $systemConfigService
)
{
$this->httpCacheEnabled = $httpCacheEnabled;
$this->maintenanceResolver = $maintenanceModeResolver;
$this->productCountService = $productCountService;
$this->systemConfigService = $systemConfigService;
}
public static function getSubscribedEvents(): iterable
{
return [KernelEvents::RESPONSE => [
['setPagesOrderCookie', -1400],
]];
}
public function setPagesOrderCookie(ResponseEvent $event): void
{
if (!$this->httpCacheEnabled) {
return;
}
$response = $event->getResponse();
$request = $event->getRequest();
if ($request->cookies->has(self::COOKIE_NAME)) {
return;
}
if ($this->maintenanceResolver->isMaintenanceRequest($request)) {
return;
}
$context = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
if (!$context instanceof SalesChannelContext) {
return;
}
$pagesArray = range(1, $this->getTotalPages($request, $context));
shuffle($pagesArray);
$cookie = Cookie::create(
self::COOKIE_NAME,
json_encode($pagesArray),
0,
'/',
null,
null,
false,
true
);
$cookie->setSecureDefault($request->isSecure());
$response->headers->setCookie($cookie);
}
private function getTotalPages(Request $request, SalesChannelContext $context): int
{
$limit = $this->systemConfigService->getInt('core.listing.productsPerPage');
if ($limit <= 0) {
$limit = 24;
}
$total = $this->productCountService->getTotal($request, $context);
if ($total <= 0) {
$total = 1;
}
return (int) ceil($total / $limit);
}
}