custom/plugins/AcrisCookieConsentCS/src/Storefront/Page/GenericPageLoader.php line 74

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Acris\CookieConsent\Storefront\Page;
  3. use Acris\CookieConsent\Components\CookiesAcceptService;
  4. use Acris\CookieConsent\Components\CookieService;
  5. use Shopware\Core\Content\Cms\CmsPageEntity;
  6. use Shopware\Core\Framework\Context;
  7. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  9. use Shopware\Core\Framework\Struct\ArrayEntity;
  10. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  11. use Shopware\Core\System\SystemConfig\SystemConfigService;
  12. use Shopware\Storefront\Page\GenericPageLoaderInterface;
  13. use Shopware\Storefront\Page\Page;
  14. use Symfony\Component\DependencyInjection\ContainerInterface;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Session\Session;
  17. use DOMDocument;
  18. class GenericPageLoader extends \Shopware\Storefront\Page\GenericPageLoader
  19. {
  20.     const COOKIE_STRING_SEPERATOR "_||_";
  21.     /**
  22.      * @var GenericPageLoaderInterface
  23.      */
  24.     private $genericPageLoader;
  25.     /**
  26.      * @var ContainerInterface
  27.      */
  28.     private $container;
  29.     /**
  30.      * @var CookieService
  31.      */
  32.     private $cookieService;
  33.     /**
  34.      * @var CookiesAcceptService
  35.      */
  36.     private $cookiesAcceptService;
  37.     /**
  38.      * @var SystemConfigService
  39.      */
  40.     private $systemConfigService;
  41.     /**
  42.      * @var EntityRepositoryInterface
  43.      */
  44.     private $cmsPageRepository;
  45.     public function __construct(
  46.         GenericPageLoaderInterface $genericPageLoader,
  47.         ContainerInterface $container,
  48.         CookieService $cookieService,
  49.         CookiesAcceptService $cookiesAcceptService,
  50.         SystemConfigService $systemConfigService,
  51.         EntityRepositoryInterface $cmsPageRepository
  52.     ) {
  53.         $this->genericPageLoader $genericPageLoader;
  54.         $this->container $container;
  55.         $this->cookieService $cookieService;
  56.         $this->cookiesAcceptService $cookiesAcceptService;
  57.         $this->systemConfigService $systemConfigService;
  58.         $this->cmsPageRepository $cmsPageRepository;
  59.     }
  60.     public function load(Request $requestSalesChannelContext $salesChannelContext): Page
  61.     {
  62.         if ($request->isXmlHttpRequest()) {
  63.             return $this->genericPageLoader->load($request$salesChannelContext);
  64.         }
  65.         $salesChannelId $salesChannelContext->getSalesChannel()->getId();
  66.         $session $this->container->get('session');
  67.         $hasAccepted $this->cookiesAcceptService->getCookiesAccepted($session$request);
  68.         $knownCookieIds $this->cookieService->getAllKnownCookieIds($salesChannelContext->getContext(), $salesChannelId);
  69.         $cookieGroups $this->cookieService->getAvailableCookieGroups($salesChannelContext->getContext(), $salesChannelId);
  70.         $deniedCookieGroups $session->get('acrisCookieGroupsDenied', []);
  71.         $deniedCookies $session->get('acrisCookiesDenied', []);
  72.         $cookieGroups $this->convertAndGetCookieGroups($session$cookieGroups$deniedCookieGroups$deniedCookies$hasAccepted$salesChannelId);
  73.         if(!$hasAccepted) {
  74.             $acceptedCookies $this->replaceRegexSigns($this->convertCookieGroupsToAcceptedString($cookieGroupstrue));
  75.         } else {
  76.             $acceptedCookies $this->replaceRegexSigns($this->convertCookieGroupsToAcceptedString($cookieGroupsfalse$deniedCookieGroups$deniedCookies));
  77.         }
  78.         $acceptedCookies $this->addExpectedCookies($acceptedCookies$this->cookieService::EXPECTED_COOKIES);
  79.         $page $this->genericPageLoader->load($request$salesChannelContext);
  80.         $page->addExtension('acrisCookieConsent', new ArrayEntity([
  81.             'hasAccepted' => $hasAccepted,
  82.             'cookieGroups' => $cookieGroups,
  83.             'acceptedCookies' => $acceptedCookies,
  84.             'knownCookies' => $this->replaceRegexSigns(implode(self::COOKIE_STRING_SEPERATOR$knownCookieIds)),
  85.             'cookieStringSeparator' => self::COOKIE_STRING_SEPERATOR,
  86.             'footerPages' => $this->loadFooterPageData($salesChannelContext)
  87.         ]));
  88.         return $page;
  89.     }
  90.     /**
  91.      * @param array $cookieGroups
  92.      * @param bool $onlyDefault
  93.      * @param array $deniedCookieGroups
  94.      * @param array $deniedCookies
  95.      * @return string
  96.      */
  97.     private function convertCookieGroupsToAcceptedString($cookieGroups$onlyDefault true$deniedCookieGroups = [], $deniedCookies = [])
  98.     {
  99.         $cookieArray = [];
  100.         foreach ($cookieGroups as $key => $cookieGroup) {
  101.             foreach ($cookieGroup['cookies'] as $cookie) {
  102.                 if(!in_array($cookieGroup['id'], $deniedCookieGroups) && !in_array($cookie['id'], $deniedCookies)) {
  103.                     if(($onlyDefault === true && ($cookieGroup['isDefault'] || $cookie['isDefault'])) || ($onlyDefault === false && $cookie['active'])) {
  104.                         $cookieArray[] = $cookie['cookieId'];
  105.                     }
  106.                 }
  107.             }
  108.         }
  109.         return implode(self::COOKIE_STRING_SEPERATOR$cookieArray);
  110.     }
  111.     /**
  112.      * @param Session $session
  113.      * @param array $cookieGroups
  114.      * @param array $deniedCookieGroups
  115.      * @param array $deniedCookies
  116.      * @param boolean $hasAccepted
  117.      * @return array
  118.      */
  119.     private function convertAndGetCookieGroups($session$cookieGroups$deniedCookieGroups$deniedCookies$hasAccepted$salesChannelId): array
  120.     {
  121.         if(!$hasAccepted$deniedCookieGroups $this->cookiesAcceptService->checkDenyNonFunctionalCookiesForDefault($session$cookieGroups$deniedCookieGroups$salesChannelId);
  122.         if($deniedCookieGroups || $deniedCookies) {
  123.             foreach ($cookieGroups as $key => $cookieGroup) {
  124.                 $groupDenied in_array($cookieGroup['id'], $deniedCookieGroups);
  125.                 $cookieGroups[$key]['denied'] = $groupDenied;
  126.                 foreach ($cookieGroup['cookies'] as $j => $cookie) {
  127.                     if(($deniedCookies !== null && in_array($cookie['id'], $deniedCookies) === true) || $groupDenied === true) {
  128.                         $cookieGroups[$key]['cookies'][$j]['denied'] = true;
  129.                     }
  130.                 }
  131.             }
  132.         }
  133.         foreach ($cookieGroups as $key => $cookieGroup) {
  134.             foreach ($cookieGroup['cookies'] as $j => $cookie) {
  135.                 if($cookie['translated']['script']) {
  136.                     if(array_key_exists('denied'$cookie)) {
  137.                         $cookieGroups[$key]['cookies'][$j]['translated']['script'] = $this->convertCookieScript($cookie['translated']['script'], $cookie['cookieId'], $cookie['denied']);
  138.                     }else{
  139.                         $cookieGroups[$key]['cookies'][$j]['translated']['script'] = $this->convertCookieScript($cookie['translated']['script'], $cookie['cookieId']);
  140.                     }
  141.                 }
  142.             }
  143.         }
  144.         return $cookieGroups;
  145.     }
  146.     /**
  147.      * @param string $script
  148.      * @param string $cookieId
  149.      */
  150.     private function convertCookieScript($script$cookieId$cookieStateDenied false) {
  151.         if(strpos(trim($script), "<script") !== false) {
  152.             return $this->changeScript($script$cookieId$cookieStateDenied);
  153.         } else {
  154.             if($cookieStateDenied) {
  155.                 return '<script type="text/plain" data-acriscookie="true" data-acriscookieid="' $cookieId '">' $script '</script>';
  156.             }else{
  157.                 return '<script type="text/javascript" data-acriscookie="true" data-acriscookieid="' $cookieId '">' $script '</script>';
  158.             }
  159.         }
  160.     }
  161.     private function replaceRegexSigns($string)
  162.     {
  163.         return str_replace('\\''\\\\'$string);
  164.     }
  165.     private function addExpectedCookies($acceptedCookiesString, array $expectedCookies): string
  166.     {
  167.         $expectedCookiesString implode(self::COOKIE_STRING_SEPERATOR$expectedCookies);
  168.         if($acceptedCookiesString) {
  169.             return $acceptedCookiesString self::COOKIE_STRING_SEPERATOR $expectedCookiesString;
  170.         } else {
  171.             return $expectedCookiesString;
  172.         }
  173.     }
  174.     private function loadFooterPageData(SalesChannelContext $salesChannelContext)
  175.     {
  176.         return [
  177.             'footerPageOne' => $this->loadPageDataById($this->systemConfigService->get('AcrisCookieConsentCS.config.privacyLinkFooterOne'$salesChannelContext->getSalesChannel()->getId()), $salesChannelContext->getContext()),
  178.             'footerPageTwo' => $this->loadPageDataById($this->systemConfigService->get('AcrisCookieConsentCS.config.privacyLinkFooterTwo'$salesChannelContext->getSalesChannel()->getId()), $salesChannelContext->getContext()),
  179.             'footerPageThree' => $this->loadPageDataById($this->systemConfigService->get('AcrisCookieConsentCS.config.privacyLinkFooterThree'$salesChannelContext->getSalesChannel()->getId()), $salesChannelContext->getContext())
  180.         ];
  181.     }
  182.     private function loadPageDataById($cmsPageIdContext $context): ?CmsPageEntity
  183.     {
  184.         if(empty($cmsPageId) === true) {
  185.             return null;
  186.         }
  187.         return $this->cmsPageRepository->search(new Criteria([$cmsPageId]), $context)->first();
  188.     }
  189.     private function changeScript($html$cookieId$cookieStateDenied false) {
  190.         $dom = new DOMDocument;
  191.         $dom->loadHTML($html);
  192.         $scripts $dom->getElementsByTagName('script');
  193.         $noScripts $dom->getElementsByTagName('noscript');
  194.         if (isset($scripts[0])) {
  195.             foreach ($scripts as $script) {
  196.                 if($cookieStateDenied) {
  197.                     $script->setAttribute('type''text/plain');
  198.                 }else{
  199.                     $script->setAttribute('type''text/javascript');
  200.                 }
  201.                 $script->setAttribute('data-acriscookie''true');
  202.                 $script->setAttribute('data-acriscookieid'$cookieId);
  203.                 $dom->saveHTML($script);
  204.             }
  205.             foreach ($noScripts as $noScript) {
  206.                 $dom->saveHTML($noScript);
  207.             }
  208.             $head $dom->getElementsByTagName('head')->item(0);
  209.             $headContent '';
  210.             foreach ($head->childNodes as $node) {
  211.                 $headContent .= $dom->saveHTML($node);
  212.             }
  213.             return $headContent;
  214.         } else {
  215.             return '';
  216.         }
  217.     }
  218. }