HtmlViewHelper.php 4.97 KB
Newer Older
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
1
<?php
Thomas Maroschik's avatar
Thomas Maroschik committed
2
3
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;

4
5
6
7
8
9
10
11
12
13
14
15
/*                                                                        *
 * This script is part of the TYPO3 project - inspiring people to share!  *
 *                                                                        *
 * TYPO3 is free software; you can redistribute it and/or modify it under *
 * the terms of the GNU General Public License version 2 as published by  *
 * the Free Software Foundation.                                          *
 *                                                                        *
 * This script is distributed in the hope that it will be useful, but     *
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
 * Public License for more details.                                       *
 *                                                                        */
16
17
18
19
20
21
22
23
24

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Object\ObjectManager;

Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
25
26
27
28
/**
 * Renders a string by passing it to a TYPO3 parseFunc.
 * You can either specify a path to the TypoScript setting or set the parseFunc options directly.
 * By default lib.parseFunc_RTE is used to parse the string.
Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
29
 *
30
 * == Examples ==
Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
31
 *
32
 * <code title="Default parameters">
33
 * <f:format.html>foo <b>bar</b>. Some <LINK 1>link</LINK>.</f:format.html>
34
35
 * </code>
 * <output>
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
36
37
 * <p class="bodytext">foo <b>bar</b>. Some <a href="index.php?id=1" >link</a>.</p>
 * (depending on your TYPO3 setup)
38
 * </output>
Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
39
 *
40
 * <code title="Custom parseFunc">
41
 * <f:format.html parseFuncTSPath="lib.parseFunc">foo <b>bar</b>. Some <LINK 1>link</LINK>.</f:format.html>
42
43
44
45
 * </code>
 * <output>
 * foo <b>bar</b>. Some <a href="index.php?id=1" >link</a>.
 * </output>
Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
46
 *
47
48
49
50
 * <code title="Inline notation">
 * {someText -> f:format.html(parseFuncTSPath: 'lib.parseFunc')}
 * </code>
 * <output>
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
51
 * foo <b>bar</b>. Some <a href="index.php?id=1" >link</a>.
52
 * </output>
Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
53
 *
54
 * @see https://docs.typo3.org/typo3cms/TyposcriptReference/Functions/Parsefunc/
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
55
 */
56
class HtmlViewHelper extends AbstractViewHelper implements CompilableInterface {
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
57

58
	/**
59
	 * @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController contains a backup of the current $GLOBALS['TSFE'] if used in BE mode
60
	 */
61
	static protected $tsfeBackup;
62

Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
63
	/**
64
	 * If the escaping interceptor should be disabled inside this ViewHelper, then set this value to FALSE.
Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
65
66
	 * This is internal and NO part of the API. It is very likely to change.
	 *
67
	 * @var bool
Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
68
69
	 * @internal
	 */
70
	protected $escapingInterceptorEnabled = FALSE;
Sebastian Kurfürst's avatar
Fluid:    
Sebastian Kurfürst committed
71

Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
72
	/**
73
74
	 * @param string $parseFuncTSPath path to TypoScript parseFunc setup.
	 * @return string the parsed string.
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
75
	 */
76
	public function render($parseFuncTSPath = 'lib.parseFunc_RTE') {
77
		return static::renderStatic(
78
79
80
81
82
83
			array(
				'parseFuncTSPath' => $parseFuncTSPath,
			),
			$this->buildRenderChildrenClosure(),
			$this->renderingContext
		);
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
84
85
86
	}

	/**
87
88
89
90
91
	 * @param array $arguments
	 * @param callable $renderChildrenClosure
	 * @param RenderingContextInterface $renderingContext
	 *
	 * @return string
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
92
	 */
93
94
	static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
		$parseFuncTSPath = $arguments['parseFuncTSPath'];
95
		if (TYPO3_MODE === 'BE') {
96
			self::simulateFrontendEnvironment();
97
		}
98
99
100
		$value = $renderChildrenClosure();
		$contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
		$content = $contentObject->parseFunc($value, array(), '< ' . $parseFuncTSPath);
101
		if (TYPO3_MODE === 'BE') {
102
			self::resetFrontendEnvironment();
103
104
105
106
107
108
		}
		return $content;
	}

	/**
	 * Copies the specified parseFunc configuration to $GLOBALS['TSFE']->tmpl->setup in Backend mode
109
	 * This somewhat hacky work around is currently needed because the parseFunc() function of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer relies on those variables to be set
110
111
112
	 *
	 * @return void
	 */
113
114
	static protected function simulateFrontendEnvironment() {
		self::$tsfeBackup = isset($GLOBALS['TSFE']) ? $GLOBALS['TSFE'] : NULL;
Thomas Maroschik's avatar
Thomas Maroschik committed
115
		$GLOBALS['TSFE'] = new \stdClass();
116
		$GLOBALS['TSFE']->tmpl = new \stdClass();
117
118
119
		$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		$configurationManager = $objectManager->get(ConfigurationManagerInterface::class);
		$GLOBALS['TSFE']->tmpl->setup = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
120
121
122
123
124
125
126
127
	}

	/**
	 * Resets $GLOBALS['TSFE'] if it was previously changed by simulateFrontendEnvironment()
	 *
	 * @return void
	 * @see simulateFrontendEnvironment()
	 */
128
129
	static protected function resetFrontendEnvironment() {
		$GLOBALS['TSFE'] = self::$tsfeBackup;
Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
130
	}
131

Bastian Waidelich's avatar
Fluid:  
Bastian Waidelich committed
132
}