vendor/pimcore/pimcore/lib/Templating/PhpEngine.php line 276

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;
  15. use Pimcore\Config\Config;
  16. use Pimcore\Model\Document;
  17. use Pimcore\Model\Document\Tag;
  18. use Pimcore\Templating\Helper\Cache;
  19. use Pimcore\Templating\Helper\Glossary;
  20. use Pimcore\Templating\Helper\HeadLink;
  21. use Pimcore\Templating\Helper\HeadMeta;
  22. use Pimcore\Templating\Helper\HeadScript;
  23. use Pimcore\Templating\Helper\HeadStyle;
  24. use Pimcore\Templating\Helper\HeadTitle;
  25. use Pimcore\Templating\Helper\InlineScript;
  26. use Pimcore\Templating\Helper\Navigation;
  27. use Pimcore\Templating\Helper\Placeholder\Container;
  28. use Pimcore\Templating\Helper\WebLink;
  29. use Pimcore\Templating\HelperBroker\HelperBrokerInterface;
  30. use Pimcore\Templating\Model\ViewModel;
  31. use Pimcore\Templating\Model\ViewModelInterface;
  32. use Pimcore\Tool\DeviceDetector;
  33. use Symfony\Bundle\FrameworkBundle\Templating\Helper\ActionsHelper;
  34. use Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper;
  35. use Symfony\Bundle\FrameworkBundle\Templating\Helper\CodeHelper;
  36. use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper;
  37. use Symfony\Bundle\FrameworkBundle\Templating\Helper\RequestHelper;
  38. use Symfony\Bundle\FrameworkBundle\Templating\Helper\RouterHelper;
  39. use Symfony\Bundle\FrameworkBundle\Templating\Helper\SessionHelper;
  40. use Symfony\Bundle\FrameworkBundle\Templating\Helper\StopwatchHelper;
  41. use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper;
  42. use Symfony\Bundle\FrameworkBundle\Templating\PhpEngine as BasePhpEngine;
  43. use Symfony\Bundle\SecurityBundle\Templating\Helper\SecurityHelper;
  44. use Symfony\Component\HttpFoundation\Request;
  45. use Symfony\Component\Templating\Helper\SlotsHelper;
  46. use Symfony\Component\Templating\Storage\Storage;
  47. /**
  48.  * Symfony PHP engine with pimcore additions:
  49.  *
  50.  *  - property access - $this->variable and $this->helper()
  51.  *  - helper brokers integrate other view helpers (ZF) on __call
  52.  *  - tag integration
  53.  *
  54.  * Defined in \Pimcore\Templating\HelperBroker\HelperShortcuts
  55.  *
  56.  * @method string getLocale()
  57.  * @method Request getRequest()
  58.  * @method SlotsHelper slots()
  59.  * @method string path($name, $parameters = array(), $relative = false)
  60.  * @method string url($name, $parameters = array(), $schemeRelative = false)
  61.  * @method string t($key, $parameters = [], $domain = null, $locale = null)
  62.  *
  63.  * Symfony core helpers
  64.  * @method ActionsHelper actions()
  65.  * @method AssetsHelper assets()
  66.  * @method CodeHelper code()
  67.  * @method FormHelper form()
  68.  * @method RequestHelper request()
  69.  * @method RouterHelper router()
  70.  * @method SecurityHelper security()
  71.  * @method SessionHelper session()
  72.  * @method StopwatchHelper stopwatch()
  73.  * @method TranslatorHelper translator()
  74.  *
  75.  * Pimcore helpers
  76.  * @method string action($action, $controller, $module, array $params = [])
  77.  * @method Cache cache($name, $lifetime = null, $force = false)
  78.  * @method DeviceDetector device($default = null)
  79.  * @method array getAllParams()
  80.  * @method array breachAttackRandomContent()
  81.  * @method mixed getParam($key, $default = null)
  82.  * @method Glossary glossary()
  83.  * @method Container placeholder($placeholderName)
  84.  * @method HeadLink headLink(array $attributes = null, $placement = Container::APPEND)
  85.  * @method HeadMeta headMeta($content = null, $keyValue = null, $keyType = 'name', $modifiers = array(), $placement = Container::APPEND)
  86.  * @method HeadScript headScript($mode = HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript')
  87.  * @method HeadStyle headStyle($content = null, $placement = 'APPEND', $attributes = array())
  88.  * @method HeadTitle headTitle($title = null, $setType = null)
  89.  * @method string inc($include, array $params = [], $cacheEnabled = true, $editmode = null)
  90.  * @method InlineScript inlineScript($mode = HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript')
  91.  * @method WebLink webLink()
  92.  * @method Navigation navigation()
  93.  * @method Config|mixed websiteConfig($key = null, $default = null)
  94.  * @method string pimcoreUrl(array $urlOptions = [], $name = null, $reset = false, $encode = true, $relative = false)
  95.  * @method string translate($key, $parameters = [], $domain = null, $locale = null)
  96.  *
  97.  * Pimcore editables
  98.  * @method Tag\Area area($name, $options = [])
  99.  * @method Tag\Areablock areablock($name, $options = [])
  100.  * @method Tag\Block block($name, $options = [])
  101.  * @method Tag\Checkbox checkbox($name, $options = [])
  102.  * @method Tag\Date date($name, $options = [])
  103.  * @method Tag\Embed embed($name, $options = [])
  104.  * @method Tag\Relation relation($name, $options = [])
  105.  * @method Tag\Image image($name, $options = [])
  106.  * @method Tag\Input input($name, $options = [])
  107.  * @method Tag\Link link($name, $options = [])
  108.  * @method Tag\Relations relations($name, $options = [])
  109.  * @method Tag\Multiselect multiselect($name, $options = [])
  110.  * @method Tag\Numeric numeric($name, $options = [])
  111.  * @method Tag\Pdf pdf($name, $options = [])
  112.  * @method Tag\Renderlet renderlet($name, $options = [])
  113.  * @method Tag\Select select($name, $options = [])
  114.  * @method Tag\Snippet snippet($name, $options = [])
  115.  * @method Tag\Table table($name, $options = [])
  116.  * @method Tag\Textarea textarea($name, $options = [])
  117.  * @method Tag\Video video($name, $options = [])
  118.  * @method Tag\Wysiwyg wysiwyg($name, $options = [])
  119.  * @method Tag\Scheduledblock scheduledblock($name, $options = [])
  120.  *
  121.  * @property Document $document
  122.  * @property bool $editmode
  123.  * @property GlobalVariables $app
  124.  */
  125. class PhpEngine extends BasePhpEngine
  126. {
  127.     const PARAM_NO_PARENT '_no_parent';
  128.     /**
  129.      * @var HelperBrokerInterface[]
  130.      */
  131.     protected $helperBrokers = [];
  132.     /**
  133.      * @var ViewModelInterface[]
  134.      */
  135.     protected $viewModels = [];
  136.     /**
  137.      * @param HelperBrokerInterface $helperBroker
  138.      */
  139.     public function addHelperBroker(HelperBrokerInterface $helperBroker)
  140.     {
  141.         $this->helperBrokers[] = $helperBroker;
  142.     }
  143.     /**
  144.      * In addition to the core method, this keeps parameters in a ViewModel instance which is accessible from
  145.      * view helpers and via $this->$variable.
  146.      *
  147.      * {@inheritdoc}
  148.      */
  149.     protected function evaluate(Storage $template, array $parameters = [])
  150.     {
  151.         // disable parent with "magic" _no_parent parameter
  152.         $disableParent false;
  153.         if (isset($parameters[static::PARAM_NO_PARENT])) {
  154.             $disableParent = (bool)($parameters[static::PARAM_NO_PARENT]);
  155.             unset($parameters[static::PARAM_NO_PARENT]);
  156.         }
  157.         // create view model and push it onto the model stack
  158.         $this->viewModels[] = new ViewModel($parameters);
  159.         // render the template
  160.         $result parent::evaluate($template$parameters);
  161.         // remove current view model from stack and destroy it
  162.         $viewModel array_pop($this->viewModels);
  163.         unset($viewModel);
  164.         if ($disableParent) {
  165.             $this->parents[$this->current] = null;
  166.         }
  167.         return $result;
  168.     }
  169.     /**
  170.      * Renders template with current parameters
  171.      *
  172.      * @param string $name
  173.      * @param array $parameters
  174.      *
  175.      * @return string
  176.      */
  177.     public function template($name, array $parameters = [])
  178.     {
  179.         if ($viewModel $this->getViewModel()) {
  180.             // attach current variables
  181.             $parameters array_replace($viewModel->getParameters()->all(), $parameters);
  182.         }
  183.         return $this->render($name$parameters);
  184.     }
  185.     /**
  186.      * Get the current view model
  187.      *
  188.      * @return ViewModelInterface|null
  189.      */
  190.     public function getViewModel()
  191.     {
  192.         $count count($this->viewModels);
  193.         if ($count 0) {
  194.             return $this->viewModels[$count 1];
  195.         }
  196.         return null;
  197.     }
  198.     /**
  199.      * Get a view model parameter
  200.      *
  201.      * @param string $name
  202.      * @param mixed|null $default
  203.      *
  204.      * @return mixed|null
  205.      */
  206.     public function getViewParameter($name$default null)
  207.     {
  208.         $viewModel $this->getViewModel();
  209.         if (null !== $viewModel) {
  210.             return $viewModel->getParameters()->get($name$default);
  211.         }
  212.         return $default;
  213.     }
  214.     /**
  215.      * Magic getter reads variable from ViewModel
  216.      *
  217.      * @inheritDoc
  218.      */
  219.     public function __get($name)
  220.     {
  221.         return $this->getViewParameter($name);
  222.     }
  223.     /**
  224.      * Magic isset checks variable from ViewModel
  225.      *
  226.      * @inheritDoc
  227.      */
  228.     public function __isset($name)
  229.     {
  230.         return $this->getViewParameter($name) !== null;
  231.     }
  232.     /**
  233.      * @param string $name
  234.      * @param mixed $value
  235.      */
  236.     public function __set($name$value)
  237.     {
  238.         $viewModel $this->getViewModel();
  239.         if ($viewModel) {
  240.             $viewModel->getParameters()->set($name$value);
  241.         } else {
  242.             throw new \RuntimeException(sprintf('Can\'t set variable %s as there is no active view model'$name));
  243.         }
  244.     }
  245.     /**
  246.      * @inheritDoc
  247.      */
  248.     public function __call($method$arguments)
  249.     {
  250.         // try to run helper from helper broker (native helper, document tag, zend view, ...)
  251.         foreach ($this->helperBrokers as $helperBroker) {
  252.             if ($helperBroker->supports($this$method)) {
  253.                 return $helperBroker->helper($this$method$arguments);
  254.             }
  255.         }
  256.         throw new \InvalidArgumentException('Call to undefined method ' $method);
  257.     }
  258. }