custom/plugins/WbmTagManagerEcomm/src/Subscriber/KernelEventsSubscriber.php line 84

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Wbm\TagManagerEcomm\Subscriber;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\Routing\KernelListenerPriorities;
  5. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  8. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  9. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  10. use Symfony\Component\HttpKernel\KernelEvents;
  11. use Wbm\TagManagerEcomm\Services\DataLayerModulesInterface;
  12. use Wbm\TagManagerEcomm\Services\DataLayerRendererInterface;
  13. use Wbm\TagManagerEcomm\Utility\SessionUtility;
  14. class KernelEventsSubscriber implements EventSubscriberInterface
  15. {
  16.     /**
  17.      * @var DataLayerModulesInterface
  18.      */
  19.     private $modules;
  20.     /**
  21.      * @var DataLayerRendererInterface
  22.      */
  23.     private $dataLayerRenderer;
  24.     /**
  25.      * @var SessionInterface
  26.      */
  27.     private $session;
  28.     public function __construct(
  29.         DataLayerModulesInterface  $modules,
  30.         DataLayerRendererInterface $dataLayerRender,
  31.         SessionInterface           $session
  32.     )
  33.     {
  34.         $this->modules = $modules;
  35.         $this->dataLayerRenderer = $dataLayerRender;
  36.         $this->session = $session;
  37.     }
  38.     public static function getSubscribedEvents(): array
  39.     {
  40.         return [
  41.             KernelEvents::CONTROLLER => [
  42.                 ['getDataLayerForXmlHttpRequest', KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE_POST],
  43.             ],
  44.             KernelEvents::RESPONSE => [
  45.                 ['prependDataLayerToResponse', -1],
  46.             ],
  47.         ];
  48.     }
  49.     public function getDataLayerForXmlHttpRequest(ControllerEvent $event): void
  50.     {
  51.         $request = $event->getRequest();
  52.         if (!$this->isStorefrontRequest($request)) {
  53.             return;
  54.         }
  55.         $modules = $this->modules->getModules();
  56.         $route = $request->attributes->get('_route');
  57.         if (!array_key_exists($route, $modules)
  58.             || empty($modules[$route])
  59.             || $this->session->has(SessionUtility::ATTRIBUTE_NAME)
  60.         ) {
  61.             return;
  62.         }
  63.         $salesChannelId = $request->get('sw-sales-channel-id');
  64.         $isActive = !empty($this->modules->getContainerId($salesChannelId)) && $this->modules->isActive($salesChannelId);
  65.         if (!$isActive) {
  66.             return;
  67.         }
  68.         $this->dataLayerRenderer->setVariables($route, [])->renderDataLayer($route);
  69.     }
  70.     public function prependDataLayerToResponse(ResponseEvent $event): void
  71.     {
  72.         $response = $event->getResponse();
  73.         $request = $event->getRequest();
  74.         if (!$this->isStorefrontRequest($request)) {
  75.             return;
  76.         }
  77.         $route = $request->attributes->get('_route');
  78.         $dataLayer = $this->dataLayerRenderer->getDataLayer($route);
  79.         if ($dataLayer !== null) {
  80.             $dataLayer = SessionUtility::injectSessionVars($dataLayer, $this->session);
  81.             $dataLayer = json_encode($dataLayer);
  82.         }
  83.         if (!empty($dataLayer) && $response->isRedirect()) {
  84.             $this->session->set(SessionUtility::ATTRIBUTE_NAME, $dataLayer);
  85.             return;
  86.         }
  87.         if (!$request->isXmlHttpRequest()) {
  88.             return;
  89.         }
  90.         $storedDatalayer = $this->session->get(SessionUtility::ATTRIBUTE_NAME);
  91.         $this->session->remove(SessionUtility::ATTRIBUTE_NAME);
  92.         if ($storedDatalayer && in_array($route, $this->modules->getResponseRoutes(), true)) {
  93.             $dataLayer = $storedDatalayer;
  94.         }
  95.         if (empty($dataLayer)) {
  96.             return;
  97.         }
  98.         $dataLayerScriptTag = sprintf(
  99.             '<script id="wbm-data-layer">%s</script>',
  100.             $dataLayer
  101.         );
  102.         $content = $dataLayerScriptTag . PHP_EOL . $response->getContent();
  103.         $response->setContent($content);
  104.         $event->setResponse($response);
  105.     }
  106.     private function isStorefrontRequest(Request $request)
  107.     {
  108.         if ($request->attributes->has('sw-context')
  109.             && $request->attributes->get('sw-context') instanceof Context
  110.             && $request->attributes->get('sw-context')->getScope() === 'user'
  111.         ) {
  112.             return true;
  113.         }
  114.         return false;
  115.     }
  116. }