vendor/pimcore/pimcore/lib/Templating/Renderer/IncludeRenderer.php line 134

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\Templating\Renderer;
  15. use Pimcore\Cache;
  16. use Pimcore\Model;
  17. use Pimcore\Model\Document\PageSnippet;
  18. use Pimcore\Model\Document\Targeting\TargetingDocumentInterface;
  19. use Pimcore\Model\Element;
  20. use Pimcore\Targeting\Document\DocumentTargetingConfigurator;
  21. use Pimcore\Tool\DeviceDetector;
  22. use Pimcore\Tool\Frontend;
  23. class IncludeRenderer
  24. {
  25.     /**
  26.      * @var ActionRenderer
  27.      */
  28.     protected $actionRenderer;
  29.     /**
  30.      * @var DocumentTargetingConfigurator
  31.      */
  32.     private $targetingConfigurator;
  33.     public function __construct(
  34.         ActionRenderer $actionRenderer,
  35.         DocumentTargetingConfigurator $targetingConfigurator
  36.     ) {
  37.         $this->actionRenderer $actionRenderer;
  38.         $this->targetingConfigurator $targetingConfigurator;
  39.     }
  40.     /**
  41.      * Renders a document include
  42.      *
  43.      * @param mixed $include
  44.      * @param array $params
  45.      * @param bool $editmode
  46.      * @param bool $cacheEnabled
  47.      *
  48.      * @return string
  49.      */
  50.     public function render($include, array $params = [], $editmode false$cacheEnabled true)
  51.     {
  52.         if (!is_array($params)) {
  53.             $params = [];
  54.         }
  55.         $originalInclude $include;
  56.         // this is if $this->inc is called eg. with $this->relation() as argument
  57.         if (!$include instanceof PageSnippet && is_object($include) && method_exists($include'__toString')) {
  58.             $include = (string)$include;
  59.         }
  60.         if (is_numeric($include)) {
  61.             try {
  62.                 $include Model\Document::getById($include);
  63.             } catch (\Exception $e) {
  64.                 $include $originalInclude;
  65.             }
  66.         } elseif (is_string($include)) {
  67.             try {
  68.                 $include Model\Document::getByPath($include);
  69.             } catch (\Exception $e) {
  70.                 $include $originalInclude;
  71.             }
  72.         }
  73.         if ($include instanceof PageSnippet && $include->isPublished()) {
  74.             // apply best matching target group (if any)
  75.             $this->targetingConfigurator->configureTargetGroup($include);
  76.         }
  77.         // check if output-cache is enabled, if so, we're also using the cache here
  78.         $cacheKey null;
  79.         $cacheConfig false;
  80.         if ($cacheEnabled) {
  81.             if ($cacheConfig Frontend::isOutputCacheEnabled()) {
  82.                 // cleanup params to avoid serializing Element\ElementInterface objects
  83.                 $cacheParams $params;
  84.                 $cacheParams['~~include-document'] = $originalInclude;
  85.                 array_walk($cacheParams, function (&$value$key) {
  86.                     if ($value instanceof Element\ElementInterface) {
  87.                         $value $value->getId();
  88.                     } elseif (is_object($value) && method_exists($value'__toString')) {
  89.                         $value = (string)$value;
  90.                     }
  91.                 });
  92.                 // TODO is this enough for cache or should we disable caching completely?
  93.                 if ($include instanceof TargetingDocumentInterface && $include->getUseTargetGroup()) {
  94.                     $cacheParams['target_group'] = $include->getUseTargetGroup();
  95.                 }
  96.                 if (Frontend::hasWebpSupport()) {
  97.                     $cacheParams['webp'] = true;
  98.                 }
  99.                 $cacheKey 'tag_inc__' md5(serialize($cacheParams));
  100.                 if ($content Cache::load($cacheKey)) {
  101.                     return $content;
  102.                 }
  103.             }
  104.         }
  105.         // TODO remove dependency on registry setting
  106.         $editmodeBackup false;
  107.         if (\Pimcore\Cache\Runtime::isRegistered('pimcore_editmode')) {
  108.             $editmodeBackup = \Pimcore\Cache\Runtime::get('pimcore_editmode');
  109.         }
  110.         \Pimcore\Cache\Runtime::set('pimcore_editmode'false);
  111.         $params array_merge($params, ['document' => $include]);
  112.         $content '';
  113.         if ($include instanceof PageSnippet && $include->isPublished()) {
  114.             $content $this->renderAction($include$params);
  115.             if ($editmode) {
  116.                 $content $this->modifyEditmodeContent($include$content);
  117.             }
  118.         }
  119.         \Pimcore\Cache\Runtime::set('pimcore_editmode'$editmodeBackup);
  120.         // write contents to the cache, if output-cache is enabled
  121.         if ($cacheConfig && !DeviceDetector::getInstance()->wasUsed()) {
  122.             Cache::save($content$cacheKey, ['output''output_inline'], $cacheConfig['lifetime']);
  123.         }
  124.         return $content;
  125.     }
  126.     /**
  127.      * @param PageSnippet $include
  128.      * @param array $params
  129.      *
  130.      * @return string
  131.      */
  132.     protected function renderAction(PageSnippet $include$params)
  133.     {
  134.         $controller $this->actionRenderer->createDocumentReference($include$params);
  135.         return $this->actionRenderer->render($controller);
  136.     }
  137.     /**
  138.      * in editmode, we need to parse the returned html from the document include
  139.      * add a class and the pimcore id / type so that it can be opened in editmode using the context menu
  140.      * if there's no first level HTML container => add one (wrapper)
  141.      *
  142.      * @param PageSnippet $include
  143.      * @param string $content
  144.      *
  145.      * @return string
  146.      */
  147.     protected function modifyEditmodeContent(PageSnippet $include$content)
  148.     {
  149.         $editmodeClass ' pimcore_editable pimcore_tag_inc ';
  150.         // this is if the content that is included does already contain markup/html
  151.         // this is needed by the editmode to highlight included documents
  152.         if ($html str_get_html($content)) {
  153.             $childs $html->find('*');
  154.             if (is_array($childs)) {
  155.                 foreach ($childs as $child) {
  156.                     $child->class $child->class $editmodeClass;
  157.                     $child->pimcore_type $include->getType();
  158.                     $child->pimcore_id $include->getId();
  159.                 }
  160.             }
  161.             $content $html->save();
  162.             $html->clear();
  163.             unset($html);
  164.         } else {
  165.             // add a div container if the include doesn't contain markup/html
  166.             $content '<div class="' $editmodeClass '" pimcore_id="' $include->getId() . '" pimcore_type="' $include->getType() . '">' $content '</div>';
  167.         }
  168.         return $content;
  169.     }
  170. }