vendor/sulu/sulu/src/Sulu/Bundle/WebsiteBundle/EventListener/AppendAnalyticsListener.php line 89

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Sulu.
  4.  *
  5.  * (c) Sulu GmbH
  6.  *
  7.  * This source file is subject to the MIT license that is bundled
  8.  * with this source code in the file LICENSE.
  9.  */
  10. namespace Sulu\Bundle\WebsiteBundle\EventListener;
  11. use Sulu\Bundle\WebsiteBundle\Entity\AnalyticsInterface;
  12. use Sulu\Bundle\WebsiteBundle\Entity\AnalyticsRepositoryInterface;
  13. use Sulu\Component\Webspace\Analyzer\RequestAnalyzerInterface;
  14. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  15. use Twig\Environment;
  16. /**
  17.  * Appends analytics scripts into body.
  18.  */
  19. class AppendAnalyticsListener
  20. {
  21.     private static $positions = [
  22.         'head-open' => [
  23.             'regex' => '/(<head [^>]*>|<head>)/',
  24.             'sprintf' => '$1%s',
  25.         ],
  26.         'head-close' => [
  27.             'regex' => '/<\/head>/',
  28.             'sprintf' => '%s</head>',
  29.         ],
  30.         'body-open' => [
  31.             'regex' => '/(<body [^>]*>|<body>)/',
  32.             'sprintf' => '$1%s',
  33.         ],
  34.         'body-close' => [
  35.             'regex' => '/<\/body>/',
  36.             'sprintf' => '%s</body>',
  37.         ],
  38.     ];
  39.     /**
  40.      * @var Environment
  41.      */
  42.     private $engine;
  43.     /**
  44.      * @var RequestAnalyzerInterface
  45.      */
  46.     private $requestAnalyzer;
  47.     /**
  48.      * @var AnalyticsRepositoryInterface
  49.      */
  50.     private $analyticsRepository;
  51.     /**
  52.      * @var string
  53.      */
  54.     private $environment;
  55.     /**
  56.      * @var bool
  57.      */
  58.     private $preview;
  59.     /**
  60.      * @param $environment
  61.      */
  62.     public function __construct(
  63.         Environment $engine,
  64.         RequestAnalyzerInterface $requestAnalyzer,
  65.         AnalyticsRepositoryInterface $analyticsRepository,
  66.         $environment,
  67.         bool $preview false
  68.     ) {
  69.         $this->engine $engine;
  70.         $this->requestAnalyzer $requestAnalyzer;
  71.         $this->analyticsRepository $analyticsRepository;
  72.         $this->environment $environment;
  73.         $this->preview $preview;
  74.     }
  75.     /**
  76.      * Appends analytics scripts into body.
  77.      */
  78.     public function onResponse(ResponseEvent $event)
  79.     {
  80.         if (!$event->isMainRequest()
  81.             || $this->preview
  82.         ) {
  83.             return;
  84.         }
  85.         $response $event->getResponse();
  86.         if (!== \strpos($response->headers->get('Content-Type'), 'text/html')
  87.             || !$response->getContent()
  88.             || null === $this->requestAnalyzer->getPortalInformation()
  89.         ) {
  90.             return;
  91.         }
  92.         $portalUrl $this->requestAnalyzer->getAttribute('urlExpression');
  93.         if (!$portalUrl) {
  94.             return;
  95.         }
  96.         $analyticsArray $this->analyticsRepository->findByUrl(
  97.             $portalUrl,
  98.             $this->requestAnalyzer->getPortalInformation()->getWebspaceKey(),
  99.             $this->environment
  100.         );
  101.         $analyticsContent = [];
  102.         foreach ($analyticsArray as $analytics) {
  103.             $analyticsContent $this->generateAnalyticsContent($analyticsContent$analytics);
  104.         }
  105.         $response $event->getResponse();
  106.         $response->setContent($this->setAnalyticsContent($response->getContent(), $analyticsContent));
  107.     }
  108.     /**
  109.      * Generate content for each possible position.
  110.      *
  111.      * @return array
  112.      */
  113.     protected function generateAnalyticsContent(array $analyticsContentAnalyticsInterface $analytics)
  114.     {
  115.         foreach (\array_keys(self::$positions) as $position) {
  116.             $template '@SuluWebsite/Analytics/' $analytics->getType() . '/' $position '.html.twig';
  117.             if (!$this->engine->getLoader()->exists($template)) {
  118.                 continue;
  119.             }
  120.             $content $this->engine->render($template, ['analytics' => $analytics]);
  121.             if (!$content) {
  122.                 continue;
  123.             }
  124.             if (!\array_key_exists($position$analyticsContent)) {
  125.                 $analyticsContent[$position] = '';
  126.             }
  127.             $analyticsContent[$position] .= $content;
  128.         }
  129.         return $analyticsContent;
  130.     }
  131.     /**
  132.      * Set the generated content for each position.
  133.      *
  134.      * @param string $responseContent
  135.      *
  136.      * @return string
  137.      */
  138.     protected function setAnalyticsContent($responseContent, array $analyticsContent)
  139.     {
  140.         foreach ($analyticsContent as $id => $content) {
  141.             if (!$content) {
  142.                 continue;
  143.             }
  144.             $responseContent \preg_replace(
  145.                 self::$positions[$id]['regex'],
  146.                 \sprintf(self::$positions[$id]['sprintf'], $content),
  147.                 $responseContent
  148.             );
  149.         }
  150.         return $responseContent;
  151.     }
  152. }