ca68d4353982461889b0fa2660011f96c92abfbb
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / Core / Rendering / RenderingContext.php
1 <?php
2 namespace TYPO3\CMS\Fluid\Core\Rendering;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Cache\CacheManager;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Extbase\Object\ObjectManager;
20 use TYPO3\CMS\Fluid\Core\Cache\FluidTemplateCache;
21 use TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface;
22 use TYPO3\CMS\Fluid\Core\Parser\PreProcessor\XmlnsNamespaceTemplatePreProcessor;
23 use TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\Expression\LegacyNamespaceExpressionNode;
24 use TYPO3\CMS\Fluid\Core\Variables\CmsVariableProvider;
25 use TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperResolver;
26 use TYPO3\CMS\Fluid\View\TemplatePaths;
27 use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
28 use TYPO3Fluid\Fluid\Core\Parser\Configuration;
29 use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\Expression\CastingExpressionNode;
30 use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\Expression\MathExpressionNode;
31 use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\Expression\TernaryExpressionNode;
32 use TYPO3Fluid\Fluid\Core\Parser\TemplateParser;
33 use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperInvoker;
34 use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer;
35 use TYPO3Fluid\Fluid\View\ViewInterface;
36
37 /**
38 * Class RenderingContext
39 */
40 class RenderingContext extends \TYPO3Fluid\Fluid\Core\Rendering\RenderingContext
41 {
42 /**
43 * Template Variable Container. Contains all variables available through object accessors in the template
44 *
45 * @var \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer
46 */
47 protected $templateVariableContainer;
48
49 /**
50 * Object manager which is bubbled through. The ViewHelperNode cannot get an ObjectManager injected because
51 * the whole syntax tree should be cacheable
52 *
53 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
54 */
55 protected $objectManager;
56
57 /**
58 * Controller context being passed to the ViewHelper
59 *
60 * @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext
61 */
62 protected $controllerContext;
63
64 /**
65 * ViewHelper Variable Container
66 *
67 * @var \TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer
68 */
69 protected $viewHelperVariableContainer;
70
71 /**
72 * Use legacy behavior? Can be overridden using setLegacyMode().
73 *
74 * @var bool
75 */
76 protected $legacyMode = false;
77
78 /**
79 * List of class names implementing ExpressionNodeInterface
80 * which will be consulted when an expression does not match
81 * any built-in parser expression types.
82 *
83 * @var string
84 */
85 protected $expressionNodeTypes = [
86 LegacyNamespaceExpressionNode::class,
87 CastingExpressionNode::class,
88 MathExpressionNode::class,
89 TernaryExpressionNode::class
90 ];
91
92 /**
93 * Alternative ExpressionNodeInterface implementers for use
94 * when put into legacy mode.
95 *
96 * @var string
97 */
98 protected $legacyExpressionNodeTypes = [
99 LegacyNamespaceExpressionNode::class
100 ];
101
102 /**
103 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
104 */
105 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
106 {
107 $this->objectManager = $objectManager;
108 }
109
110 /**
111 * @param \TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer $viewHelperVariableContainer
112 */
113 public function injectViewHelperVariableContainer(\TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer $viewHelperVariableContainer)
114 {
115 $this->viewHelperVariableContainer = $viewHelperVariableContainer;
116 }
117
118 /**
119 * @param ViewInterface $view
120 */
121 public function __construct(ViewInterface $view = null)
122 {
123 if ($view !== null) {
124 // Note: if $view is received here this indicates internal framework instancing
125 // and it is safe to call the parent constructor. Custom, non-view-providing
126 // usages will only perform the initialisation below (which is sufficient mind you!)
127 parent::__construct($view);
128 } else {
129 // Reproduced partial initialisation from parent::__construct; minus the custom
130 // implementations we attach below.
131 $this->setTemplateParser(new TemplateParser());
132 $this->setTemplateCompiler(new TemplateCompiler());
133 $this->setViewHelperInvoker(new ViewHelperInvoker());
134 $this->setViewHelperVariableContainer(new ViewHelperVariableContainer());
135 }
136
137 $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
138 $this->setTemplatePaths($objectManager->get(TemplatePaths::class));
139 $this->setViewHelperResolver($objectManager->get(ViewHelperResolver::class));
140 $this->setVariableProvider($objectManager->get(CmsVariableProvider::class));
141 $this->setTemplateProcessors(
142 array_merge(
143 parent::getTemplateProcessors(),
144 [
145 $objectManager->get(XmlnsNamespaceTemplatePreProcessor::class),
146 ]
147 )
148 );
149 /** @var FluidTemplateCache $cache */
150 $cache = $objectManager->get(CacheManager::class)->getCache('fluid_template');
151 if (is_a($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['fluid_template']['frontend'], FluidTemplateCache::class, true)) {
152 $this->setCache($cache);
153 }
154 }
155
156 /**
157 * Build parser configuration
158 *
159 * @return Configuration
160 * @throws \InvalidArgumentException if a class not implementing InterceptorInterface was registered
161 */
162 public function buildParserConfiguration()
163 {
164 $parserConfiguration = parent::buildParserConfiguration();
165 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'])) {
166 foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'] as $className) {
167 $interceptor = GeneralUtility::makeInstance($className);
168 if (!$interceptor instanceof InterceptorInterface) {
169 throw new \InvalidArgumentException('Interceptor "' . $className . '" needs to implement ' . InterceptorInterface::class . '.', 1462869795);
170 }
171 $parserConfiguration->addInterceptor($interceptor);
172 }
173 }
174
175 return $parserConfiguration;
176 }
177
178 /**
179 * Set legacy compatibility mode on/off by boolean.
180 * If set to FALSE, the ViewHelperResolver will only load a limited sub-set of ExpressionNodes,
181 * making Fluid behave like the legacy version of the CMS core extension.
182 *
183 * @param bool $legacyMode
184 * @return void
185 */
186 public function setLegacyMode($legacyMode)
187 {
188 $this->legacyMode = $legacyMode;
189 }
190
191 /**
192 * @return string
193 */
194 public function getExpressionNodeTypes()
195 {
196 return $this->legacyMode ? $this->legacyExpressionNodeTypes : $this->expressionNodeTypes;
197 }
198
199 /**
200 * Returns the object manager. Only the ViewHelperNode should do this.
201 *
202 * @return \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
203 */
204 public function getObjectManager()
205 {
206 return $this->objectManager;
207 }
208
209 /**
210 * Get the template variable container (DEPRECATED; use getVariableProvider instead)
211 *
212 * @deprecated since TYPO3 CMS 8, will be removed in TYPO3 CMS 9 - use getVariableProvider instead
213 * @see getVariableProvider
214 * @return \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer The Template Variable Container
215 */
216 public function getTemplateVariableContainer()
217 {
218 GeneralUtility::deprecationLog(
219 'getTemplateVariableContainer is deprecated since TYPO3 CMS 8, will be removed in TYPO3 CMS 9' .
220 ' - use getVariableProvider instead'
221 );
222 return $this->variableProvider;
223 }
224
225 /**
226 * Get the controller context which will be passed to the ViewHelper
227 *
228 * @return \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext The controller context to set
229 */
230 public function getControllerContext()
231 {
232 return $this->controllerContext;
233 }
234
235 /**
236 * @param string $action
237 * @return void
238 */
239 public function setControllerAction($action)
240 {
241 $dotPosition = strpos($action, '.');
242 if ($dotPosition !== false) {
243 $action = substr($action, 0, $dotPosition);
244 }
245 parent::setControllerAction($action);
246 $this->controllerContext->getRequest()->setControllerActionName(lcfirst($action));
247 }
248
249 /**
250 * @param string $controllerName
251 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException
252 */
253 public function setControllerName($controllerName)
254 {
255 parent::setControllerName($controllerName);
256 $this->controllerContext->getRequest()->setControllerName($controllerName);
257 }
258
259 /**
260 * Set the controller context which will be passed to the ViewHelper
261 *
262 * @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext The controller context to set
263 */
264 public function setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
265 {
266 $request = $controllerContext->getRequest();
267 $this->controllerContext = $controllerContext;
268 $this->setControllerAction($request->getControllerActionName());
269 // Check if Request is using a sub-package key; in which case we translate this
270 // for our RenderingContext as an emulated plain old sub-namespace controller.
271 $controllerName = $request->getControllerName();
272 if ($request->getControllerSubpackageKey() && !strpos($controllerName, '\\')) {
273 $this->setControllerName($request->getControllerSubpackageKey() . '\\' . $controllerName);
274 } else {
275 $this->setControllerName($controllerName);
276 }
277 }
278
279 /**
280 * Get the ViewHelperVariableContainer
281 *
282 * @return \TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer
283 */
284 public function getViewHelperVariableContainer()
285 {
286 return $this->viewHelperVariableContainer;
287 }
288 }