Revert "[CLEANUP] Rework/simplify copyright header and remove @package"
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / ViewHelpers / CObjectViewHelper.php
1 <?php
2 namespace TYPO3\CMS\Fluid\ViewHelpers;
3
4 /* *
5 * This script is part of the TYPO3 project - inspiring people to share! *
6 * *
7 * TYPO3 is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU General Public License version 2 as published by *
9 * the Free Software Foundation. *
10 * *
11 * This script is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
13 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
14 * Public License for more details. *
15 * */
16 /**
17 * This ViewHelper renders CObjects from the global TypoScript configuration.
18 *
19 * = Examples =
20 *
21 * <code title="Render lib object">
22 * <f:cObject typoscriptObjectPath="lib.someLibObject" />
23 * </code>
24 * <output>
25 * rendered lib.someLibObject
26 * </output>
27 *
28 * <code title="Specify cObject data & current value">
29 * <f:cObject typoscriptObjectPath="lib.customHeader" data="{article}" current="{article.title}" />
30 * </code>
31 * <output>
32 * rendered lib.customHeader. data and current value will be available in TypoScript
33 * </output>
34 *
35 * <code title="inline notation">
36 * {article -> f:cObject(typoscriptObjectPath: 'lib.customHeader')}
37 * </code>
38 * <output>
39 * rendered lib.customHeader. data will be available in TypoScript
40 * </output>
41 */
42 class CObjectViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
43
44 /**
45 * Disable the escaping interceptor because otherwise the child nodes would be escaped before this view helper
46 * can decode the text's entities.
47 *
48 * @var boolean
49 */
50 protected $escapingInterceptorEnabled = FALSE;
51
52 /**
53 * @var array
54 */
55 protected $typoScriptSetup;
56
57 /**
58 * @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController contains a backup of the current $GLOBALS['TSFE'] if used in BE mode
59 */
60 protected $tsfeBackup;
61
62 /**
63 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
64 */
65 protected $configurationManager;
66
67 /**
68 * @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
69 * @return void
70 */
71 public function injectConfigurationManager(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager) {
72 $this->configurationManager = $configurationManager;
73 $this->typoScriptSetup = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
74 }
75
76 /**
77 * Renders the TypoScript object in the given TypoScript setup path.
78 *
79 * @param string $typoscriptObjectPath the TypoScript setup path of the TypoScript object to render
80 * @param mixed $data the data to be used for rendering the cObject. Can be an object, array or string. If this argument is not set, child nodes will be used
81 * @param string $currentValueKey
82 * @param string $table
83 * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
84 * @return string the content of the rendered TypoScript object
85 */
86 public function render($typoscriptObjectPath, $data = NULL, $currentValueKey = NULL, $table = '') {
87 if (TYPO3_MODE === 'BE') {
88 $this->simulateFrontendEnvironment();
89 }
90 if ($data === NULL) {
91 $data = $this->renderChildren();
92 }
93 $currentValue = NULL;
94 if (is_object($data)) {
95 $data = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettableProperties($data);
96 } elseif (is_string($data) || is_numeric($data)) {
97 $currentValue = (string) $data;
98 $data = array($data);
99 }
100 /** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject */
101 $contentObject = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
102 $contentObject->start($data, $table);
103 if ($currentValue !== NULL) {
104 $contentObject->setCurrentVal($currentValue);
105 } elseif ($currentValueKey !== NULL && isset($data[$currentValueKey])) {
106 $contentObject->setCurrentVal($data[$currentValueKey]);
107 }
108 $pathSegments = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('.', $typoscriptObjectPath);
109 $lastSegment = array_pop($pathSegments);
110 $setup = $this->typoScriptSetup;
111 foreach ($pathSegments as $segment) {
112 if (!array_key_exists(($segment . '.'), $setup)) {
113 throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('TypoScript object path "' . htmlspecialchars($typoscriptObjectPath) . '" does not exist', 1253191023);
114 }
115 $setup = $setup[$segment . '.'];
116 }
117 $content = $contentObject->cObjGetSingle($setup[$lastSegment], $setup[$lastSegment . '.']);
118 if (TYPO3_MODE === 'BE') {
119 $this->resetFrontendEnvironment();
120 }
121 return $content;
122 }
123
124 /**
125 * Sets the $TSFE->cObjectDepthCounter in Backend mode
126 * This somewhat hacky work around is currently needed because the cObjGetSingle() function of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer relies on this setting
127 *
128 * @return void
129 */
130 protected function simulateFrontendEnvironment() {
131 $this->tsfeBackup = isset($GLOBALS['TSFE']) ? $GLOBALS['TSFE'] : NULL;
132 $GLOBALS['TSFE'] = new \stdClass();
133 $GLOBALS['TSFE']->cObjectDepthCounter = 100;
134 }
135
136 /**
137 * Resets $GLOBALS['TSFE'] if it was previously changed by simulateFrontendEnvironment()
138 *
139 * @return void
140 * @see simulateFrontendEnvironment()
141 */
142 protected function resetFrontendEnvironment() {
143 $GLOBALS['TSFE'] = $this->tsfeBackup;
144 }
145 }