Merge "[TASK] Increase version number"
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / ViewHelpers / CObjectViewHelper.php
1 <?php
2
3 /* *
4 * This script is part of the TYPO3 project - inspiring people to share! *
5 * *
6 * TYPO3 is free software; you can redistribute it and/or modify it under *
7 * the terms of the GNU General Public License version 2 as published by *
8 * the Free Software Foundation. *
9 * *
10 * This script is distributed in the hope that it will be useful, but *
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
12 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
13 * Public License for more details. *
14 * */
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 */
43 class Tx_Fluid_ViewHelpers_CObjectViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
44
45 /**
46 * Disable the escaping interceptor because otherwise the child nodes would be escaped before this view helper
47 * can decode the text's entities.
48 *
49 * @var boolean
50 */
51 protected $escapingInterceptorEnabled = FALSE;
52
53 /**
54 * @var array
55 */
56 protected $typoScriptSetup;
57
58 /**
59 * @var t3lib_fe contains a backup of the current $GLOBALS['TSFE'] if used in BE mode
60 */
61 protected $tsfeBackup;
62
63 /**
64 * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
65 */
66 protected $configurationManager;
67
68 /**
69 * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
70 * @return void
71 */
72 public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
73 $this->configurationManager = $configurationManager;
74 $this->typoScriptSetup = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
75 }
76
77 /**
78 * Renders the TypoScript object in the given TypoScript setup path.
79 *
80 * @param string $typoscriptObjectPath the TypoScript setup path of the TypoScript object to render
81 * @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
82 * @param string $currentValueKey
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
90 if ($data === NULL) {
91 $data = $this->renderChildren();
92 }
93 $currentValue = NULL;
94 if (is_object($data)) {
95 $data = Tx_Extbase_Reflection_ObjectAccess::getGettableProperties($data);
96 } elseif (is_string($data) || is_numeric($data)) {
97 $currentValue = (string) $data;
98 $data = array($data);
99 }
100 $contentObject = t3lib_div::makeInstance('tslib_cObj');
101 $contentObject->start($data);
102 if ($currentValue !== NULL) {
103 $contentObject->setCurrentVal($currentValue);
104 } elseif ($currentValueKey !== NULL && isset($data[$currentValueKey])) {
105 $contentObject->setCurrentVal($data[$currentValueKey]);
106 }
107
108 $pathSegments = t3lib_div::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 Tx_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
119 if (TYPO3_MODE === 'BE') {
120 $this->resetFrontendEnvironment();
121 }
122
123 return $content;
124 }
125
126 /**
127 * Sets the $TSFE->cObjectDepthCounter in Backend mode
128 * This somewhat hacky work around is currently needed because the cObjGetSingle() function of tslib_cObj relies on this setting
129 *
130 * @return void
131 */
132 protected function simulateFrontendEnvironment() {
133 $this->tsfeBackup = isset($GLOBALS['TSFE']) ? $GLOBALS['TSFE'] : NULL;
134 $GLOBALS['TSFE'] = new stdClass();
135 $GLOBALS['TSFE']->cObjectDepthCounter = 100;
136 }
137
138 /**
139 * Resets $GLOBALS['TSFE'] if it was previously changed by simulateFrontendEnvironment()
140 *
141 * @return void
142 * @see simulateFrontendEnvironment()
143 */
144 protected function resetFrontendEnvironment() {
145 $GLOBALS['TSFE'] = $this->tsfeBackup;
146 }
147 }
148
149 ?>