TYPO3 CMS  TYPO3_7-6
AbstractTemplateView.php
Go to the documentation of this file.
1 <?php
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 
20 {
24  const RENDERING_TEMPLATE = 1;
25  const RENDERING_PARTIAL = 2;
26  const RENDERING_LAYOUT = 3;
27 
31  protected $controllerContext;
32 
37  protected $objectManager;
38 
43  protected $templateParser;
44 
48  protected $templateCompiler;
49 
58 
65  protected $renderingStack = [];
66 
74  protected $partialIdentifierCache = [];
75 
81  {
82  $this->templateCompiler = $templateCompiler;
83  $this->templateCompiler->setTemplateCache(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('fluid_template'));
84  }
85 
92  public function setRenderingContext(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)
93  {
94  $this->baseRenderingContext = $renderingContext;
95  $this->baseRenderingContext->getViewHelperVariableContainer()->setView($this);
96  $this->controllerContext = $renderingContext->getControllerContext();
97  }
98 
106  public function setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
107  {
108  $this->controllerContext = $controllerContext;
109  }
110 
111  public function initializeView()
112  {
113  }
114  // Here, the backporter can insert the initializeView method, which is needed for Fluid v4.
115 
124  public function assign($key, $value)
125  {
126  $templateVariableContainer = $this->baseRenderingContext->getTemplateVariableContainer();
127  if ($templateVariableContainer->exists($key)) {
128  $templateVariableContainer->remove($key);
129  }
130  $templateVariableContainer->add($key, $value);
131  return $this;
132  }
133 
142  public function assignMultiple(array $values)
143  {
144  $templateVariableContainer = $this->baseRenderingContext->getTemplateVariableContainer();
145  foreach ($values as $key => $value) {
146  if ($templateVariableContainer->exists($key)) {
147  $templateVariableContainer->remove($key);
148  }
149  $templateVariableContainer->add($key, $value);
150  }
151  return $this;
152  }
153 
162  public function render($actionName = null)
163  {
164  $this->baseRenderingContext->setControllerContext($this->controllerContext);
165  $this->templateParser->setConfiguration($this->buildParserConfiguration());
166 
167  $templateIdentifier = $this->getTemplateIdentifier($actionName);
168  if ($this->templateCompiler->has($templateIdentifier)) {
169  $parsedTemplate = $this->templateCompiler->get($templateIdentifier);
170  } else {
171  $parsedTemplate = $this->templateParser->parse($this->getTemplateSource($actionName));
172  if ($parsedTemplate->isCompilable()) {
173  $this->templateCompiler->store($templateIdentifier, $parsedTemplate);
174  }
175  }
176 
177  if ($parsedTemplate->hasLayout()) {
178  $layoutName = $parsedTemplate->getLayoutName($this->baseRenderingContext);
179  $layoutIdentifier = $this->getLayoutIdentifier($layoutName);
180  if ($this->templateCompiler->has($layoutIdentifier)) {
181  $parsedLayout = $this->templateCompiler->get($layoutIdentifier);
182  } else {
183  $parsedLayout = $this->templateParser->parse($this->getLayoutSource($layoutName));
184  if ($parsedLayout->isCompilable()) {
185  $this->templateCompiler->store($layoutIdentifier, $parsedLayout);
186  }
187  }
188  $this->startRendering(self::RENDERING_LAYOUT, $parsedTemplate, $this->baseRenderingContext);
189  $output = $parsedLayout->render($this->baseRenderingContext);
190  $this->stopRendering();
191  } else {
192  $this->startRendering(self::RENDERING_TEMPLATE, $parsedTemplate, $this->baseRenderingContext);
193  $output = $parsedTemplate->render($this->baseRenderingContext);
194  $this->stopRendering();
195  }
196 
197  return $output;
198  }
199 
209  public function renderSection($sectionName, array $variables, $ignoreUnknown = false)
210  {
211  $renderingContext = $this->getCurrentRenderingContext();
212  if ($this->getCurrentRenderingType() === self::RENDERING_LAYOUT) {
213  // in case we render a layout right now, we will render a section inside a TEMPLATE.
214  $renderingTypeOnNextLevel = self::RENDERING_TEMPLATE;
215  } else {
216  $variableContainer = $this->objectManager->get(\TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer::class, $variables);
217  $renderingContext = clone $renderingContext;
218  $renderingContext->injectTemplateVariableContainer($variableContainer);
219  $renderingTypeOnNextLevel = $this->getCurrentRenderingType();
220  }
221 
222  $parsedTemplate = $this->getCurrentParsedTemplate();
223 
224  if ($parsedTemplate->isCompiled()) {
225  $methodNameOfSection = 'section_' . sha1($sectionName);
226  if ($ignoreUnknown && !method_exists($parsedTemplate, $methodNameOfSection)) {
227  return '';
228  }
229  $this->startRendering($renderingTypeOnNextLevel, $parsedTemplate, $renderingContext);
230  $output = $parsedTemplate->{$methodNameOfSection}($renderingContext);
231  $this->stopRendering();
232  } else {
233  $sections = $parsedTemplate->getVariableContainer()->get('sections');
234  if (!array_key_exists($sectionName, $sections)) {
235  $controllerObjectName = $this->controllerContext->getRequest()->getControllerObjectName();
236  if ($ignoreUnknown) {
237  return '';
238  } else {
239  throw new \TYPO3\CMS\Fluid\View\Exception\InvalidSectionException(sprintf('Could not render unknown section "%s" in %s used by %s.', $sectionName, get_class($this), $controllerObjectName), 1227108982);
240  }
241  }
242  $section = $sections[$sectionName];
243 
244  $renderingContext->getViewHelperVariableContainer()->add(\TYPO3\CMS\Fluid\ViewHelpers\SectionViewHelper::class, 'isCurrentlyRenderingSection', 'TRUE');
245 
246  $this->startRendering($renderingTypeOnNextLevel, $parsedTemplate, $renderingContext);
247  $output = $section->evaluate($renderingContext);
248  $this->stopRendering();
249  }
250 
251  return $output;
252  }
253 
263  public function renderPartial($partialName, $sectionName, array $variables)
264  {
265  $partialNameWithFormat = $partialName . '.' . $this->controllerContext->getRequest()->getFormat();
266  if (!isset($this->partialIdentifierCache[$partialNameWithFormat])) {
267  $this->partialIdentifierCache[$partialNameWithFormat] = $this->getPartialIdentifier($partialName);
268  }
269  $partialIdentifier = $this->partialIdentifierCache[$partialNameWithFormat];
270 
271  if ($this->templateCompiler->has($partialIdentifier)) {
272  $parsedPartial = $this->templateCompiler->get($partialIdentifier);
273  } else {
274  $parsedPartial = $this->templateParser->parse($this->getPartialSource($partialName));
275  if ($parsedPartial->isCompilable()) {
276  $this->templateCompiler->store($partialIdentifier, $parsedPartial);
277  }
278  }
279 
280  $variableContainer = $this->objectManager->get(\TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer::class, $variables);
281  $renderingContext = clone $this->getCurrentRenderingContext();
282  $renderingContext->injectTemplateVariableContainer($variableContainer);
283 
284  $this->startRendering(self::RENDERING_PARTIAL, $parsedPartial, $renderingContext);
285  if ($sectionName !== null) {
286  $output = $this->renderSection($sectionName, $variables);
287  } else {
288  $output = $parsedPartial->render($renderingContext);
289  }
290  $this->stopRendering();
291 
292  return $output;
293  }
294 
301  protected function ucFileNameInPath($templatePath)
302  {
303  if (strpos($templatePath, '/') > 0) {
304  $pathParts = explode('/', $templatePath);
305  $index = count($pathParts) - 1;
306  $pathParts[$index] = ucfirst($pathParts[$index]);
307 
308  $upperCasedTemplateName = implode('/', $pathParts);
309  } else {
310  $upperCasedTemplateName = ucfirst($templatePath);
311  }
312  return $upperCasedTemplateName;
313  }
314 
321  protected function testFileExistence($filePath)
322  {
323  return is_file($filePath);
324  }
325 
333  abstract protected function getTemplateIdentifier($actionName = null);
334 
343  abstract protected function getTemplateSource($actionName = null);
344 
352  abstract protected function getLayoutIdentifier($layoutName = 'Default');
353 
366  abstract protected function getLayoutSource($layoutName = 'Default');
367 
375  abstract protected function getPartialIdentifier($partialName);
376 
384  abstract protected function getPartialSource($partialName);
385 
391  protected function buildParserConfiguration()
392  {
393  $parserConfiguration = $this->objectManager->get(\TYPO3\CMS\Fluid\Core\Parser\Configuration::class);
394  if ($this->controllerContext->getRequest()->getFormat() === 'html') {
395  $parserConfiguration->addInterceptor($this->objectManager->get(\TYPO3\CMS\Fluid\Core\Parser\Interceptor\Escape::class));
396  }
397  return $parserConfiguration;
398  }
399 
408  protected function startRendering($type, \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface $parsedTemplate, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)
409  {
410  array_push($this->renderingStack, ['type' => $type, 'parsedTemplate' => $parsedTemplate, 'renderingContext' => $renderingContext]);
411  }
412 
419  protected function stopRendering()
420  {
421  array_pop($this->renderingStack);
422  }
423 
429  protected function getCurrentRenderingType()
430  {
431  $currentRendering = end($this->renderingStack);
432  return $currentRendering['type'];
433  }
434 
440  protected function getCurrentParsedTemplate()
441  {
442  $currentRendering = end($this->renderingStack);
443  return $currentRendering['parsedTemplate'];
444  }
445 
451  protected function getCurrentRenderingContext()
452  {
453  $currentRendering = end($this->renderingStack);
454  return $currentRendering['renderingContext'];
455  }
456 
467  public function canRender(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
468  {
469  return true;
470  }
471 }
canRender(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
getLayoutSource($layoutName='Default')
renderSection($sectionName, array $variables, $ignoreUnknown=false)
setRenderingContext(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)
renderPartial($partialName, $sectionName, array $variables)
getLayoutIdentifier($layoutName='Default')
setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
injectTemplateCompiler(\TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler)
startRendering($type, \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface $parsedTemplate, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)