362fe14ad97709f3ad1b372604000bb611f12d9c
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / Core / Parser / SyntaxTree / ViewHelperNode.php
1 <?php
2 namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
3
4 /* *
5 * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License, either version 3 *
9 * of the License, or (at your option) any later version. *
10 * *
11 * The TYPO3 project - inspiring people to share! *
12 * */
13
14 /**
15 * Node which will call a ViewHelper associated with this node.
16 */
17 class ViewHelperNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode {
18
19 /**
20 * Class name of view helper
21 *
22 * @var string
23 */
24 protected $viewHelperClassName;
25
26 /**
27 * Arguments of view helper - References to RootNodes.
28 *
29 * @var array
30 */
31 protected $arguments = array();
32
33 /**
34 * The ViewHelper associated with this node
35 *
36 * @var \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
37 */
38 protected $uninitializedViewHelper = NULL;
39
40 /**
41 * A mapping RenderingContext -> ViewHelper to only re-initialize ViewHelpers
42 * when a context change occurs.
43 *
44 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage
45 */
46 protected $viewHelpersByContext = NULL;
47
48 /**
49 * Constructor.
50 *
51 * @param \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper $viewHelper The view helper
52 * @param array $arguments Arguments of view helper - each value is a RootNode.
53 */
54 public function __construct(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper $viewHelper, array $arguments) {
55 $this->uninitializedViewHelper = $viewHelper;
56 $this->viewHelpersByContext = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\ObjectStorage::class);
57 $this->arguments = $arguments;
58 $this->viewHelperClassName = get_class($this->uninitializedViewHelper);
59 }
60
61 /**
62 * Returns the attached (but still uninitialized) ViewHelper for this ViewHelperNode.
63 * We need this method because sometimes Interceptors need to ask some information from the ViewHelper.
64 *
65 * @return \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper the attached ViewHelper, if it is initialized
66 */
67 public function getUninitializedViewHelper() {
68 return $this->uninitializedViewHelper;
69 }
70
71 /**
72 * Get class name of view helper
73 *
74 * @return string Class Name of associated view helper
75 */
76 public function getViewHelperClassName() {
77 return $this->viewHelperClassName;
78 }
79
80 /**
81 * INTERNAL - only needed for compiling templates
82 *
83 * @return array
84 * @internal
85 */
86 public function getArguments() {
87 return $this->arguments;
88 }
89
90 /**
91 * Call the view helper associated with this object.
92 *
93 * First, it evaluates the arguments of the view helper.
94 *
95 * If the view helper implements \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface,
96 * it calls setChildNodes(array childNodes) on the view helper.
97 *
98 * Afterwards, checks that the view helper did not leave a variable lying around.
99 *
100 * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
101 * @return object evaluated node after the view helper has been called.
102 */
103 public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
104 if ($this->viewHelpersByContext->contains($renderingContext)) {
105 $viewHelper = $this->viewHelpersByContext[$renderingContext];
106 $viewHelper->resetState();
107 } else {
108 $viewHelper = clone $this->uninitializedViewHelper;
109 $this->viewHelpersByContext->attach($renderingContext, $viewHelper);
110 }
111
112 $evaluatedArguments = array();
113 if (count($viewHelper->prepareArguments())) {
114 foreach ($viewHelper->prepareArguments() as $argumentName => $argumentDefinition) {
115 if (isset($this->arguments[$argumentName])) {
116 $argumentValue = $this->arguments[$argumentName];
117 $evaluatedArguments[$argumentName] = $argumentValue->evaluate($renderingContext);
118 } else {
119 $evaluatedArguments[$argumentName] = $argumentDefinition->getDefaultValue();
120 }
121 }
122 }
123
124 $viewHelper->setArguments($evaluatedArguments);
125 $viewHelper->setViewHelperNode($this);
126 $viewHelper->setRenderingContext($renderingContext);
127
128 if ($viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface) {
129 $viewHelper->setChildNodes($this->childNodes);
130 }
131
132 $output = $viewHelper->initializeArgumentsAndRender();
133
134 return $output;
135 }
136
137 /**
138 * Clean up for serializing.
139 *
140 * @return array
141 */
142 public function __sleep() {
143 return array('viewHelperClassName', 'arguments', 'childNodes');
144 }
145
146 }