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

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.                     $cookieGroups[$key]['cookies'][$j]['translated']['script'] = $this->convertCookieScript($cookie['translated']['script'], $cookie['cookieId']);
  137.                 }
  138.             }
  139.         }
  140.         return $cookieGroups;
  141.     }
  142.     /**
  143.      * @param string $script
  144.      * @param string $cookieId
  145.      */
  146.     private function convertCookieScript($script$cookieId) {
  147.         if(strpos(trim($script), "<script") !== false) {
  148.             return $this->changeScript($script$cookieId);
  149.         } else {
  150.             return '<script type="text/plain" data-acriscookie="true" data-acriscookieid="' $cookieId '">' $script '</script>';
  151.         }
  152.     }
  153.     private function replaceRegexSigns($string)
  154.     {
  155.         return str_replace('\\''\\\\'$string);
  156.     }
  157.     private function addExpectedCookies($acceptedCookiesString, array $expectedCookies): string
  158.     {
  159.         $expectedCookiesString implode(self::COOKIE_STRING_SEPERATOR$expectedCookies);
  160.         if($acceptedCookiesString) {
  161.             return $acceptedCookiesString self::COOKIE_STRING_SEPERATOR $expectedCookiesString;
  162.         } else {
  163.             return $expectedCookiesString;
  164.         }
  165.     }
  166.     private function loadFooterPageData(SalesChannelContext $salesChannelContext)
  167.     {
  168.         return [
  169.             'footerPageOne' => $this->loadPageDataById($this->systemConfigService->get('AcrisCookieConsentCS.config.privacyLinkFooterOne'$salesChannelContext->getSalesChannel()->getId()), $salesChannelContext->getContext()),
  170.             'footerPageTwo' => $this->loadPageDataById($this->systemConfigService->get('AcrisCookieConsentCS.config.privacyLinkFooterTwo'$salesChannelContext->getSalesChannel()->getId()), $salesChannelContext->getContext()),
  171.             'footerPageThree' => $this->loadPageDataById($this->systemConfigService->get('AcrisCookieConsentCS.config.privacyLinkFooterThree'$salesChannelContext->getSalesChannel()->getId()), $salesChannelContext->getContext())
  172.         ];
  173.     }
  174.     private function loadPageDataById($cmsPageIdContext $context): ?CmsPageEntity
  175.     {
  176.         if(empty($cmsPageId) === true) {
  177.             return null;
  178.         }
  179.         return $this->cmsPageRepository->search(new Criteria([$cmsPageId]), $context)->first();
  180.     }
  181.     private function changeScript($html$cookieId) {
  182.         $dom = new DOMDocument;
  183.         $dom->loadHTML($html);
  184.         $scripts $dom->getElementsByTagName('script');
  185.         if (isset($scripts[0])) {
  186.             foreach ($scripts as $script) {
  187.                 $script->setAttribute('type''text/plain');
  188.                 $script->setAttribute('data-acriscookie''true');
  189.                 $script->setAttribute('data-acriscookieid'$cookieId);
  190.                 $dom->saveHTML($script);
  191.             }
  192.             return $dom->saveHTML();
  193.         } else {
  194.             return '';
  195.         }
  196.     }
  197. }