custom/plugins/WbmTagManagerAnalytics/src/Subscriber/KernelEventsSubscriber.php line 109

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Wbm\TagManagerAnalytics\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\TagManagerAnalytics\Services\DataLayerModulesInterface;
  12. use Wbm\TagManagerAnalytics\Services\DataLayerRendererInterface;
  13. use Wbm\TagManagerAnalytics\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. $this->modules = $modules;
  34. $this->dataLayerRenderer = $dataLayerRender;
  35. $this->session = $session;
  36. }
  37. public static function getSubscribedEvents(): array
  38. {
  39. return [
  40. KernelEvents::CONTROLLER => [
  41. ['getDataLayerForXmlHttpRequest', KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE_POST],
  42. ],
  43. KernelEvents::RESPONSE => [
  44. ['prependDataLayerToResponse', -1],
  45. ],
  46. ];
  47. }
  48. public function getDataLayerForXmlHttpRequest(ControllerEvent $event): void
  49. {
  50. $request = $event->getRequest();
  51. if (!$this->isStorefrontRequest($request)) {
  52. return;
  53. }
  54. $modules = $this->modules->getModules();
  55. $route = $request->attributes->get('_route');
  56. if (!array_key_exists($route, $modules)
  57. || empty($modules[$route])
  58. || $this->session->has(SessionUtility::ATTRIBUTE_NAME)
  59. ) {
  60. return;
  61. }
  62. $salesChannelId = $request->get('sw-sales-channel-id');
  63. $isActive = !empty($this->modules->getContainerId($salesChannelId)) && $this->modules->isActive($salesChannelId);
  64. if (!$isActive) {
  65. return;
  66. }
  67. $this->dataLayerRenderer->setVariables($route, [])->renderDataLayer($route);
  68. }
  69. public function prependDataLayerToResponse(ResponseEvent $event): void
  70. {
  71. $response = $event->getResponse();
  72. $request = $event->getRequest();
  73. if (!$this->isStorefrontRequest($request)) {
  74. return;
  75. }
  76. $route = $request->attributes->get('_route');
  77. $dataLayer = $this->dataLayerRenderer->getDataLayer($route);
  78. if ($dataLayer !== null) {
  79. $dataLayer = SessionUtility::injectSessionVars($dataLayer, $this->session);
  80. $dataLayer = json_encode($dataLayer);
  81. }
  82. if (!empty($dataLayer) && $response->isRedirect()) {
  83. $this->session->set(SessionUtility::ATTRIBUTE_NAME, $dataLayer);
  84. return;
  85. }
  86. if (!$request->isXmlHttpRequest()) {
  87. return;
  88. }
  89. $storedDatalayer = $this->session->get(SessionUtility::ATTRIBUTE_NAME);
  90. $this->session->remove(SessionUtility::ATTRIBUTE_NAME);
  91. if ($storedDatalayer && in_array($route, $this->modules->getResponseRoutes(), true)) {
  92. $dataLayer = $storedDatalayer;
  93. }
  94. if (empty($dataLayer)) {
  95. return;
  96. }
  97. $dataLayerScriptTag = sprintf(
  98. '<script id="wbm-data-layer">%s</script>',
  99. $dataLayer
  100. );
  101. $content = $dataLayerScriptTag . PHP_EOL . $response->getContent();
  102. $response->setContent($content);
  103. $event->setResponse($response);
  104. }
  105. private function isStorefrontRequest(Request $request)
  106. {
  107. if ($request->attributes->has('sw-context')
  108. && $request->attributes->get('sw-context') instanceof Context
  109. && $request->attributes->get('sw-context')->getScope() === 'user'
  110. ) {
  111. return true;
  112. }
  113. return false;
  114. }
  115. }