[TASK] Optimize invocation of cObj::checkIf
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / ContentObject / FluidTemplateContentObject.php
1 <?php
2 namespace TYPO3\CMS\Frontend\ContentObject;
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 /**
18 * Contains TEMPLATE class object.
19 *
20 * @author Xavier Perseguers <typo3@perseguers.ch>
21 * @author Steffen Kamper <steffen@typo3.org>
22 * @author Bastian Waidelich <bastian@typo3.org>
23 * @author Steffen Ritter <info@steffen-ritter.net>
24 * @author Benjamin Mack <benni@typo3.org>
25 */
26 class FluidTemplateContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject {
27
28 /**
29 * @var \TYPO3\CMS\Fluid\View\StandaloneView
30 */
31 protected $view = NULL;
32
33 /**
34 * Constructor
35 */
36 public function __construct(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObjectRenderer) {
37 parent::__construct($contentObjectRenderer);
38 }
39
40 /**
41 * Rendering the cObject, FLUIDTEMPLATE
42 *
43 * Configuration properties:
44 * - file string+stdWrap The FLUID template file
45 * - layoutRootPath filepath+stdWrap Root path to layouts
46 * - partialRootPath filepath+stdWrap Root path to partial
47 * - variable array of cObjects, the keys are the variable names in fluid
48 * - extbase.pluginName
49 * - extbase.controllerExtensionName
50 * - extbase.controllerName
51 * - extbase.controllerActionName
52 *
53 * Example:
54 * 10 = FLUIDTEMPLATE
55 * 10.template = FILE
56 * 10.template.file = fileadmin/templates/mytemplate.html
57 * 10.partialRootPath = fileadmin/templates/partial/
58 * 10.variables {
59 * mylabel = TEXT
60 * mylabel.value = Label from TypoScript coming
61 * }
62 *
63 * @param array $conf Array of TypoScript properties
64 * @return string The HTML output
65 */
66 public function render($conf = array()) {
67 $parentView = $this->view;
68 $this->initializeStandaloneViewInstance();
69
70 if (!is_array($conf)) {
71 $conf = array();
72 }
73
74 $this->setTemplate($conf);
75 $this->setLayoutRootPath($conf);
76 $this->setPartialRootPath($conf);
77 $this->setFormat($conf);
78 $this->setExtbaseVariables($conf);
79 $this->assignSettings($conf);
80 $this->assignContentObjectVariables($conf);
81 $this->assignContentObjectDataAndCurrent($conf);
82
83 $content = $this->renderFluidView();
84 $content = $this->applyStandardWrapToRenderedContent($content, $conf);
85
86 $this->view = $parentView;
87 return $content;
88 }
89
90 /**
91 * Creating standalone view instance must not be done in construct() as
92 * it can lead to a nasty cache issue since content object instances
93 * are not always re-created by the content object rendered for every
94 * usage, but can be re-used. Thus, we need a fresh instance of
95 * StandaloneView every time render() is called.
96 *
97 * @return void
98 */
99 protected function initializeStandaloneViewInstance() {
100 $this->view = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Fluid\\View\\StandaloneView');
101 }
102
103 /**
104 * Set template
105 *
106 * @param array $conf With possibly set file resource
107 * @return void
108 * @throws \InvalidArgumentException
109 */
110 protected function setTemplate(array $conf) {
111 // Fetch the Fluid template
112 if (!empty($conf['template']) && !empty($conf['template.'])) {
113 $templateSource = $this->cObj->cObjGetSingle($conf['template'], $conf['template.']);
114 $this->view->setTemplateSource($templateSource);
115 } else {
116 $file = isset($conf['file.']) ? $this->cObj->stdWrap($conf['file'], $conf['file.']) : $conf['file'];
117 /** @var $templateService \TYPO3\CMS\Core\TypoScript\TemplateService */
118 $templateService = $GLOBALS['TSFE']->tmpl;
119 $templatePathAndFilename = $templateService->getFileName($file);
120 $this->view->setTemplatePathAndFilename($templatePathAndFilename);
121 }
122 }
123
124 /**
125 * Set layout root path if given in configuration
126 *
127 * @param array $conf Configuration array
128 * @return void
129 */
130 protected function setLayoutRootPath(array $conf) {
131 // Override the default layout path via typoscript
132 $layoutRootPath = isset($conf['layoutRootPath.']) ? $this->cObj->stdWrap($conf['layoutRootPath'], $conf['layoutRootPath.']) : $conf['layoutRootPath'];
133 if ($layoutRootPath) {
134 $layoutRootPath = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($layoutRootPath);
135 $this->view->setLayoutRootPath($layoutRootPath);
136 }
137 }
138
139 /**
140 * Set partial root path if given in configuration
141 *
142 * @param array $conf Configuration array
143 * @return void
144 */
145 protected function setPartialRootPath(array $conf) {
146 $partialRootPath = isset($conf['partialRootPath.']) ? $this->cObj->stdWrap($conf['partialRootPath'], $conf['partialRootPath.']) : $conf['partialRootPath'];
147 if ($partialRootPath) {
148 $partialRootPath = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($partialRootPath);
149 $this->view->setPartialRootPath($partialRootPath);
150 }
151 }
152
153 /**
154 * Set different format if given in configuration
155 *
156 * @param array $conf Configuration array
157 * @return void
158 */
159 protected function setFormat(array $conf) {
160 $format = isset($conf['format.']) ? $this->cObj->stdWrap($conf['format'], $conf['format.']) : $conf['format'];
161 if ($format) {
162 $this->view->setFormat($format);
163 }
164 }
165
166 /**
167 * Set some extbase variables if given
168 *
169 * @param array $conf Configuration array
170 * @return void
171 */
172 protected function setExtbaseVariables(array $conf) {
173 /** @var $request \TYPO3\CMS\Extbase\Mvc\Request */
174 $requestPluginName = isset($conf['extbase.']['pluginName.']) ? $this->cObj->stdWrap($conf['extbase.']['pluginName'], $conf['extbase.']['pluginName.']) : $conf['extbase.']['pluginName'];
175 if ($requestPluginName) {
176 $this->view->getRequest()->setPluginName($requestPluginName);
177 }
178 $requestControllerExtensionName = isset($conf['extbase.']['controllerExtensionName.']) ? $this->cObj->stdWrap($conf['extbase.']['controllerExtensionName'], $conf['extbase.']['controllerExtensionName.']) : $conf['extbase.']['controllerExtensionName'];
179 if ($requestControllerExtensionName) {
180 $this->view->getRequest()->setControllerExtensionName($requestControllerExtensionName);
181 }
182 $requestControllerName = isset($conf['extbase.']['controllerName.']) ? $this->cObj->stdWrap($conf['extbase.']['controllerName'], $conf['extbase.']['controllerName.']) : $conf['extbase.']['controllerName'];
183 if ($requestControllerName) {
184 $this->view->getRequest()->setControllerName($requestControllerName);
185 }
186 $requestControllerActionName = isset($conf['extbase.']['controllerActionName.']) ? $this->cObj->stdWrap($conf['extbase.']['controllerActionName'], $conf['extbase.']['controllerActionName.']) : $conf['extbase.']['controllerActionName'];
187 if ($requestControllerActionName) {
188 $this->view->getRequest()->setControllerActionName($requestControllerActionName);
189 }
190 }
191
192 /**
193 * Assign rendered content objects in variables array to view
194 *
195 * @param array $conf Configuration array
196 * @return void
197 * @throws \InvalidArgumentException
198 */
199 protected function assignContentObjectVariables(array $conf) {
200 $reservedVariables = array('data', 'current');
201 // Accumulate the variables to be replaced and loop them through cObjGetSingle
202 $variables = (array)$conf['variables.'];
203 foreach ($variables as $variableName => $cObjType) {
204 if (is_array($cObjType)) {
205 continue;
206 }
207 if (!in_array($variableName, $reservedVariables)) {
208 $this->view->assign(
209 $variableName,
210 $this->cObj->cObjGetSingle($cObjType, $variables[$variableName . '.'])
211 );
212 } else {
213 throw new \InvalidArgumentException(
214 'Cannot use reserved name "' . $variableName . '" as variable name in FLUIDTEMPLATE.',
215 1288095720
216 );
217 }
218 }
219 }
220
221 /**
222 * Set any TypoScript settings to the view. This is similar to a
223 * default MVC action controller in extbase.
224 *
225 * @param array $conf Configuration
226 * @return void
227 */
228 protected function assignSettings(array $conf) {
229 if (array_key_exists('settings.', $conf)) {
230 /** @var $typoScriptService \TYPO3\CMS\Extbase\Service\TypoScriptService */
231 $typoScriptService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Service\\TypoScriptService');
232 $settings = $typoScriptService->convertTypoScriptArrayToPlainArray($conf['settings.']);
233 $this->view->assign('settings', $settings);
234 }
235 }
236
237 /**
238 * Assign content object renderer data and current to view
239 *
240 * @param array $conf Configuration
241 * @return void
242 */
243 protected function assignContentObjectDataAndCurrent(array $conf) {
244 $this->view->assign('data', $this->cObj->data);
245 $this->view->assign('current', $this->cObj->data[$this->cObj->currentValKey]);
246 }
247
248 /**
249 * Render fluid standalone view
250 *
251 * @return string
252 */
253 protected function renderFluidView() {
254 return $this->view->render();
255 }
256
257 /**
258 * Apply standard wrap to content
259 *
260 * @param string $content Rendered HTML content
261 * @param array $conf Configuration array
262 * @return string Standard wrapped content
263 */
264 protected function applyStandardWrapToRenderedContent($content, array $conf) {
265 if (isset($conf['stdWrap.'])) {
266 $content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
267 }
268 return $content;
269 }
270
271 }