custom/plugins/AcrisCookieConsentCS/src/Subscriber/ResponseSubscriber.php line 156

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Acris\CookieConsent\Subscriber;
  3. use Acris\CookieConsent\Components\CookiesAcceptService;
  4. use Acris\CookieConsent\Components\CookieService;
  5. use Acris\CookieConsent\Components\RegisteredCookiesService;
  6. use Acris\CookieConsent\Custom\CookieEntity;
  7. use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
  8. use Shopware\Core\PlatformRequest;
  9. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  10. use Shopware\Core\System\SystemConfig\SystemConfigService;
  11. use Shopware\Storefront\Framework\Cache\CacheResponseSubscriber;
  12. use Shopware\Storefront\Framework\Cookie\CookieProviderInterface;
  13. use Symfony\Component\DependencyInjection\ContainerInterface;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\Cookie;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpFoundation\Session\Session;
  19. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  20. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  21. use Symfony\Component\HttpKernel\KernelEvents;
  22. class ResponseSubscriber implements EventSubscriberInterface
  23. {
  24.     const EXPECTED_COOKIES = [
  25.         'sf_redirect',
  26.         'googtrans',
  27.         'language',
  28.         'PHPSESSID'
  29.     ];
  30.     /**
  31.      * @var CookiesAcceptService
  32.      */
  33.     private $cookiesAcceptService;
  34.     /**
  35.      * @var ContainerInterface
  36.      */
  37.     private $container;
  38.     /**
  39.      * @var CookieService
  40.      */
  41.     private $cookieService;
  42.     /**
  43.      * @var SystemConfigService
  44.      */
  45.     private $systemConfigService;
  46.     /**
  47.      * @var RegisteredCookiesService
  48.      */
  49.     private $registeredCookiesService;
  50.     public function __construct(ContainerInterface $containerCookieService $cookieServiceCookiesAcceptService $cookiesAcceptServiceSystemConfigService $systemConfigServiceRegisteredCookiesService $registeredCookiesService)
  51.     {
  52.         $this->cookiesAcceptService $cookiesAcceptService;
  53.         $this->container $container;
  54.         $this->cookieService $cookieService;
  55.         $this->systemConfigService $systemConfigService;
  56.         $this->registeredCookiesService $registeredCookiesService;
  57.     }
  58.     public static function getSubscribedEvents()
  59.     {
  60.         return [
  61.             KernelEvents::RESPONSE => [
  62.                 ['checkResponseCookies'90000],
  63.                 ['setResponseCache', -1800]
  64.             ]
  65.         ];
  66.     }
  67.     public function checkResponseCookies(ResponseEvent $responseEvent): void
  68.     {
  69.         $request $responseEvent->getRequest();
  70.         /** @var SalesChannelContext $salesChannelContext */
  71.         $salesChannelContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  72.         if (!$salesChannelContext instanceof SalesChannelContext) return;
  73.         if(!$this->systemConfigService->get('AcrisCookieConsentCS.config.active'$salesChannelContext->getSalesChannel()->getId())) return;
  74.         $response $responseEvent->getResponse();
  75.         $session $this->container->get('session');
  76.         $cookiesAccepted $this->cookiesAcceptService->getCookiesAccepted($session$request);
  77.         $deniedCookieGroups $session->get("acrisCookieGroupsDenied", []);
  78.         $deniedCookies $session->get("acrisCookiesDenied", []);
  79.         $availableCookies $this->cookieService->getAllCookies($salesChannelContext);
  80.         $this->registeredCookiesService->getKnownShopCookies($salesChannelContext$availableCookies);
  81.         foreach($request->cookies->all() as $cookieName => $cookieValue) {
  82.             if(in_array($cookieNameself::EXPECTED_COOKIES)) continue;
  83.             /** @var CookieEntity $availableCookie */
  84.             foreach ($availableCookies->getElements() as $availableCookie) {
  85.                 // check if cookie is known
  86.                 try {
  87.                     if($cookieName === $availableCookie->getCookieId() || preg_match("#^(" $availableCookie->getCookieId() . ")$#"$cookieName)) {
  88.                         if(!$availableCookie->isDefault() && ($availableCookie->getCookieGroup() === null || !$availableCookie->getCookieGroup()->isDefault())) {
  89.                             // check if cookies are accepted by user
  90.                             if(!$cookiesAccepted || !$availableCookie->isActive()) {
  91.                                 $this->clearCookie($response$cookieName);
  92.                             } elseif(!empty($deniedCookieGroups) || !empty($deniedCookies)) {
  93.                                 // check if cookie group is denied by user
  94.                                 if(in_array($availableCookie->getCookieGroupId(), $deniedCookieGroups)) {
  95.                                     $this->clearCookie($response$cookieName);
  96.                                     break;
  97.                                 }
  98.                                 // check if cookie is denied by user
  99.                                 if(in_array($availableCookie->getId(), $deniedCookies)) {
  100.                                     $this->clearCookie($response$cookieName);
  101.                                     break;
  102.                                 }
  103.                             }
  104.                         }
  105.                         continue 2;
  106.                     }
  107.                 } catch (\Throwable $e) { }
  108.             }
  109.             // is new cookie which is not known - so clear it and add it to the database
  110.             $this->clearCookie($response$cookieName);
  111.         }
  112.         $this->insertResponseCookieIfNotKnown($response$salesChannelContext$availableCookies);
  113.     }
  114.     /**
  115.      * @param Response $response
  116.      * @param string $cookieName
  117.      */
  118.     public function clearCookie($response$cookieName): void
  119.     {
  120.         unset($_COOKIE[$cookieName]);
  121.         if($response->headers) {
  122.             $response->headers->clearCookie($cookieName);
  123.         }
  124.     }
  125.     /**
  126.      * @param Response $response
  127.      * @param SalesChannelContext $salesChannelContext
  128.      */
  129.     private function insertResponseCookieIfNotKnown(Response $responseSalesChannelContext $salesChannelContextEntityCollection $availableCookies): void
  130.     {
  131.         if($response->headers) {
  132.             foreach ($response->headers->getCookies() as $cookie) {
  133.                 if($cookie->getValue() !== NULL) {
  134.                     $this->cookieService->insertCookieIfNotKnown($salesChannelContext$cookie->getName(), false$availableCookies);
  135.                 }
  136.             }
  137.         }
  138.     }
  139.     public function setResponseCache(ResponseEvent $event)
  140.     {
  141.         $response $event->getResponse();
  142.         $request $event->getRequest();
  143.         if($request->isXmlHttpRequest()) {
  144.             $this->cookiesAcceptService->updateCookieFromSessionData($this->container->get('session'), $request$response);
  145.             return;
  146.         }
  147.         $this->cookiesAcceptService->updateCacheCookie($request);
  148.     }
  149. }