[TASK] Remove closing PHP tags
[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 * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
83 * @return string the content of the rendered TypoScript object
84 */
85 public function render($typoscriptObjectPath, $data = NULL, $currentValueKey = NULL) {
86 if (TYPO3_MODE === 'BE') {
87 $this->simulateFrontendEnvironment();
88 }
89 if ($data === NULL) {
90 $data = $this->renderChildren();
91 }
92 $currentValue = NULL;
93 if (is_object($data)) {
94 $data = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettableProperties($data);
95 } elseif (is_string($data) || is_numeric($data)) {
96 $currentValue = (string) $data;
97 $data = array($data);
98 }
99 $contentObject = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
100 $contentObject->start($data);
101 if ($currentValue !== NULL) {
102 $contentObject->setCurrentVal($currentValue);
103 } elseif ($currentValueKey !== NULL && isset($data[$currentValueKey])) {
104 $contentObject->setCurrentVal($data[$currentValueKey]);
105 }
106 $pathSegments = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('.', $typoscriptObjectPath);
107 $lastSegment = array_pop($pathSegments);
108 $setup = $this->typoScriptSetup;
109 foreach ($pathSegments as $segment) {
110 if (!array_key_exists(($segment . '.'), $setup)) {
111 throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('TypoScript object path "' . htmlspecialchars($typoscriptObjectPath) . '" does not exist', 1253191023);
112 }
113 $setup = $setup[$segment . '.'];
114 }
115 $content = $contentObject->cObjGetSingle($setup[$lastSegment], $setup[$lastSegment . '.']);
116 if (TYPO3_MODE === 'BE') {
117 $this->resetFrontendEnvironment();
118 }
119 return $content;
120 }
121
122 /**
123 * Sets the $TSFE->cObjectDepthCounter in Backend mode
124 * This somewhat hacky work around is currently needed because the cObjGetSingle() function of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer relies on this setting
125 *
126 * @return void
127 */
128 protected function simulateFrontendEnvironment() {
129 $this->tsfeBackup = isset($GLOBALS['TSFE']) ? $GLOBALS['TSFE'] : NULL;
130 $GLOBALS['TSFE'] = new \stdClass();
131 $GLOBALS['TSFE']->cObjectDepthCounter = 100;
132 }
133
134 /**
135 * Resets $GLOBALS['TSFE'] if it was previously changed by simulateFrontendEnvironment()
136 *
137 * @return void
138 * @see simulateFrontendEnvironment()
139 */
140 protected function resetFrontendEnvironment() {
141 $GLOBALS['TSFE'] = $this->tsfeBackup;
142 }
143 }