<?php declare(strict_types=1);
namespace Acris\PersistentCart\Subscriber;
use Acris\PersistentCart\Framework\Cookie\PersistentCartCookieProvider;
use Shopware\Core\Framework\Event\BeforeSendResponseEvent;
use Shopware\Core\PlatformRequest;
use Shopware\Core\SalesChannelRequest;
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\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\KernelEvents;
class ResponseSubscriber implements EventSubscriberInterface
{
/**
* @var RequestStack
*/
private $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => [
['setSessionToken', 60]
],
BeforeSendResponseEvent::class => 'setAcrisPersistentCartResponseCookie'
];
}
public function setAcrisPersistentCartResponseCookie(BeforeSendResponseEvent $responseEvent)
{
$request = $responseEvent->getRequest();
$response = $responseEvent->getResponse();
if($response->isCacheable() !== false) {
return;
}
if(strpos($request->getPathInfo(), '/account/logout') !== false) {
$response->headers->clearCookie(PersistentCartCookieProvider::ACRIS_PERSISTENT_CART_TOKEN_COOKIE_NAME);
return;
}
if($request->headers->has(PlatformRequest::HEADER_CONTEXT_TOKEN)) {
if($request->cookies->get(PersistentCartCookieProvider::ACRIS_PERSISTENT_CART_SW_COOKIE_NAME)
|| $request->cookies->get(PersistentCartCookieProvider::ACRIS_PERSISTENT_CART_COOKIE_NAMES_COOKIE_PLUGIN)) {
$response->headers->setCookie(
new Cookie(
PersistentCartCookieProvider::ACRIS_PERSISTENT_CART_TOKEN_COOKIE_NAME,
$request->headers->get(PlatformRequest::HEADER_CONTEXT_TOKEN),
time() + (PersistentCartCookieProvider::ACRIS_PERSISTENT_CART_COOKIE_EXPIRATION * 60 * 60 * 24)
)
);
// override sw cache hash cookie expire date
if($request->cookies->has(CacheResponseSubscriber::CONTEXT_CACHE_COOKIE)) {
$response->headers->setCookie(
new Cookie(
CacheResponseSubscriber::CONTEXT_CACHE_COOKIE,
$request->cookies->get(CacheResponseSubscriber::CONTEXT_CACHE_COOKIE),
time() + (PersistentCartCookieProvider::ACRIS_PERSISTENT_CART_COOKIE_EXPIRATION * 60 * 60 * 24)
)
);
}
} else {
$response->headers->clearCookie(PersistentCartCookieProvider::ACRIS_PERSISTENT_CART_TOKEN_COOKIE_NAME);
}
}
}
public function setSessionToken()
{
$master = $this->requestStack->getMasterRequest();
if (!$master) {
return;
}
if (!$master->attributes->get(SalesChannelRequest::ATTRIBUTE_IS_SALES_CHANNEL_REQUEST)) {
return;
}
if (!$master->hasSession()) {
return;
}
$session = $master->getSession();
$applicationId = $master->attributes->get(PlatformRequest::ATTRIBUTE_OAUTH_CLIENT_ID);
if (!$session->isStarted()) {
$session->setName('session-' . $applicationId);
$session->start();
$session->set('sessionId', $session->getId());
}
$salesChannelId = $master->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
if ($salesChannelId === null) {
/** @var SalesChannelContext|null $salesChannelContext */
$salesChannelContext = $master->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
if ($salesChannelContext !== null) {
$salesChannelId = $salesChannelContext->getSalesChannel()->getId();
}
}
$token = $master->cookies->get(PersistentCartCookieProvider::ACRIS_PERSISTENT_CART_TOKEN_COOKIE_NAME);
if(empty($token) !== true && (!$session->has(PlatformRequest::HEADER_CONTEXT_TOKEN) || $session->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID) !== $salesChannelId)) {
$master->headers->set(PlatformRequest::HEADER_CONTEXT_TOKEN, $token);
$session->set(PlatformRequest::HEADER_CONTEXT_TOKEN, $token);
$session->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID, $salesChannelId);
$master->headers->set(
PlatformRequest::HEADER_CONTEXT_TOKEN,
$session->get(PlatformRequest::HEADER_CONTEXT_TOKEN)
);
}
}
}