pimcore/lib/Pimcore/Bundle/CoreBundle/EventListener/Frontend/TagManagerListener.php line 76

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Enterprise License (PEL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  * @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  * @license    http://www.pimcore.org/license     GPLv3 and PEL
  13.  */
  14. namespace Pimcore\Bundle\CoreBundle\EventListener\Frontend;
  15. use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
  16. use Pimcore\Bundle\CoreBundle\EventListener\Traits\ResponseInjectionTrait;
  17. use Pimcore\Http\Request\Resolver\EditmodeResolver;
  18. use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
  19. use Pimcore\Model\Site;
  20. use Pimcore\Model\Tool\Tag;
  21. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  22. class TagManagerListener
  23. {
  24.     use PimcoreContextAwareTrait;
  25.     use ResponseInjectionTrait;
  26.     /**
  27.      * @var EditmodeResolver
  28.      */
  29.     private $editmodeResolver;
  30.     /**
  31.      * @var bool
  32.      */
  33.     protected $enabled true;
  34.     public function __construct(EditmodeResolver $editmodeResolver)
  35.     {
  36.         $this->editmodeResolver $editmodeResolver;
  37.     }
  38.     /**
  39.      * @return bool
  40.      */
  41.     public function disable()
  42.     {
  43.         $this->enabled false;
  44.         return true;
  45.     }
  46.     /**
  47.      * @return bool
  48.      */
  49.     public function enable()
  50.     {
  51.         $this->enabled true;
  52.         return true;
  53.     }
  54.     /**
  55.      * @return bool
  56.      */
  57.     public function isEnabled()
  58.     {
  59.         return $this->enabled;
  60.     }
  61.     /**
  62.      * @param FilterResponseEvent $event
  63.      */
  64.     public function onKernelResponse(FilterResponseEvent $event)
  65.     {
  66.         $request $event->getRequest();
  67.         if (!$event->isMasterRequest()) {
  68.             return;
  69.         }
  70.         if (!$this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_DEFAULT)) {
  71.             return;
  72.         }
  73.         // It's standard industry practice to exclude tracking if the request includes the header 'X-Purpose:preview'
  74.         $serverVars $event->getRequest()->server;
  75.         if ($serverVars->get('HTTP_X_PURPOSE') == 'preview') {
  76.             return;
  77.         }
  78.         $response $event->getResponse();
  79.         if (!$this->isHtmlResponse($response) || !$this->isEnabled()) {
  80.             return;
  81.         }
  82.         $list = new Tag\Config\Listing();
  83.         $tags $list->load();
  84.         if (empty($tags)) {
  85.             return;
  86.         }
  87.         $html null;
  88.         $content $response->getContent();
  89.         $requestParams array_merge($_GET$_POST);
  90.         $editmode $this->editmodeResolver->isEditmode($request);
  91.         /** @var $tag Tag\Config */
  92.         foreach ($tags as $tag) {
  93.             if ($tag->isDisabled()) {
  94.                 continue;
  95.             }
  96.             $method strtolower($tag->getHttpMethod());
  97.             $pattern $tag->getUrlPattern();
  98.             $textPattern $tag->getTextPattern();
  99.             // site check
  100.             if (Site::isSiteRequest() && $tag->getSiteId()) {
  101.                 if (Site::getCurrentSite()->getId() != $tag->getSiteId()) {
  102.                     continue;
  103.                 }
  104.             } elseif (!Site::isSiteRequest() && $tag->getSiteId() && $tag->getSiteId() != 'default') {
  105.                 continue;
  106.             }
  107.             $requestPath rtrim($request->getPathInfo(), '/');
  108.             if (($method == strtolower($request->getMethod()) || empty($method)) &&
  109.                 (empty($pattern) || @preg_match($pattern$requestPath)) &&
  110.                 (empty($textPattern) || strpos($content$textPattern) !== false)
  111.             ) {
  112.                 $paramsValid true;
  113.                 foreach ($tag->getParams() as $param) {
  114.                     if (!empty($param['name'])) {
  115.                         if (!empty($param['value'])) {
  116.                             if (!array_key_exists($param['name'], $requestParams) || $requestParams[$param['name']] != $param['value']) {
  117.                                 $paramsValid false;
  118.                             }
  119.                         } else {
  120.                             if (!array_key_exists($param['name'], $requestParams)) {
  121.                                 $paramsValid false;
  122.                             }
  123.                         }
  124.                     }
  125.                 }
  126.                 if (is_array($tag->getItems()) && $paramsValid) {
  127.                     foreach ($tag->getItems() as $item) {
  128.                         if ($item['disabled']) {
  129.                             continue;
  130.                         }
  131.                         if ($editmode && !$item['enabledInEditmode']) {
  132.                             continue;
  133.                         }
  134.                         if (!empty($item['element']) && !empty($item['code']) && !empty($item['position'])) {
  135.                             if (in_array($item['element'], ['body''head'])) {
  136.                                 // check if the code should be inserted using one of the presets
  137.                                 // because this can be done much faster than using a html parser
  138.                                 if ($html) {
  139.                                     // reset simple_html_dom if set
  140.                                     $html->clear();
  141.                                     unset($html);
  142.                                     $html null;
  143.                                 }
  144.                                 if ($item['position'] == 'end') {
  145.                                     $regEx '@</' $item['element'] . '>@i';
  146.                                     $content preg_replace($regEx"\n\n" $item['code'] . "\n\n</" $item['element'] . '>'$content1);
  147.                                 } else {
  148.                                     $regEx '/<' $item['element'] . '([^a-zA-Z])?( [^>]+)?>/';
  149.                                     $content preg_replace($regEx'<' $item['element'] . "$1$2>\n\n" $item['code'] . "\n\n"$content1);
  150.                                 }
  151.                             } else {
  152.                                 // use simple_html_dom
  153.                                 if (!$html) {
  154.                                     include_once(PIMCORE_PATH '/lib/simple_html_dom.php');
  155.                                     $html str_get_html($content);
  156.                                 }
  157.                                 if ($html) {
  158.                                     $element $html->find($item['element'], 0);
  159.                                     if ($element) {
  160.                                         if ($item['position'] == 'end') {
  161.                                             $element->innertext $element->innertext "\n\n" $item['code'] . "\n\n";
  162.                                         } else {
  163.                                             // beginning
  164.                                             $element->innertext "\n\n" $item['code'] . "\n\n" $element->innertext;
  165.                                         }
  166.                                         // we havve to reinitialize the html object, otherwise it causes problems with nested child selectors
  167.                                         $content $html->save();
  168.                                         $html->clear();
  169.                                         unset($html);
  170.                                         $html null;
  171.                                     }
  172.                                 }
  173.                             }
  174.                         }
  175.                     }
  176.                 }
  177.             }
  178.         }
  179.         if ($html && method_exists($html'clear')) {
  180.             $html->clear();
  181.             unset($html);
  182.         }
  183.         $response->setContent($content);
  184.     }
  185. }