[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 file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * This ViewHelper renders CObjects from the global TypoScript configuration.
19 *
20 * = Examples =
21 *
22 * <code title="Render lib object">
23 * <f:cObject typoscriptObjectPath="lib.someLibObject" />
24 * </code>
25 * <output>
26 * rendered lib.someLibObject
27 * </output>
28 *
29 * <code title="Specify cObject data & current value">
30 * <f:cObject typoscriptObjectPath="lib.customHeader" data="{article}" current="{article.title}" />
31 * </code>
32 * <output>
33 * rendered lib.customHeader. data and current value will be available in TypoScript
34 * </output>
35 *
36 * <code title="inline notation">
37 * {article -> f:cObject(typoscriptObjectPath: 'lib.customHeader')}
38 * </code>
39 * <output>
40 * rendered lib.customHeader. data will be available in TypoScript
41 * </output>
42 */
43 class CObjectViewHelper extends \TYPO3\CMS\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 \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController contains a backup of the current $GLOBALS['TSFE'] if used in BE mode
60 */
61 protected $tsfeBackup;
62
63 /**
64 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
65 */
66 protected $configurationManager;
67
68 /**
69 * @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
70 * @return void
71 */
72 public function injectConfigurationManager(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager) {
73 $this->configurationManager = $configurationManager;
74 $this->typoScriptSetup = $this->configurationManager->getConfiguration(\TYPO3\CMS\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 * @param string $table
84 * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
85 * @return string the content of the rendered TypoScript object
86 */
87 public function render($typoscriptObjectPath, $data = NULL, $currentValueKey = NULL, $table = '') {
88 if (TYPO3_MODE === 'BE') {
89 $this->simulateFrontendEnvironment();
90 }
91 if ($data === NULL) {
92 $data = $this->renderChildren();
93 }
94 $currentValue = NULL;
95 if (is_object($data)) {
96 $data = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettableProperties($data);
97 } elseif (is_string($data) || is_numeric($data)) {
98 $currentValue = (string) $data;
99 $data = array($data);
100 }
101 /** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject */
102 $contentObject = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
103 $contentObject->start($data, $table);
104 if ($currentValue !== NULL) {
105 $contentObject->setCurrentVal($currentValue);
106 } elseif ($currentValueKey !== NULL && isset($data[$currentValueKey])) {
107 $contentObject->setCurrentVal($data[$currentValueKey]);
108 }
109 $pathSegments = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('.', $typoscriptObjectPath);
110 $lastSegment = array_pop($pathSegments);
111 $setup = $this->typoScriptSetup;
112 foreach ($pathSegments as $segment) {
113 if (!array_key_exists(($segment . '.'), $setup)) {
114 throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('TypoScript object path "' . htmlspecialchars($typoscriptObjectPath) . '" does not exist', 1253191023);
115 }
116 $setup = $setup[$segment . '.'];
117 }
118 $content = $contentObject->cObjGetSingle($setup[$lastSegment], $setup[$lastSegment . '.']);
119 if (TYPO3_MODE === 'BE') {
120 $this->resetFrontendEnvironment();
121 }
122 return $content;
123 }
124
125 /**
126 * Sets the $TSFE->cObjectDepthCounter in Backend mode
127 * This somewhat hacky work around is currently needed because the cObjGetSingle() function of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer relies on this setting
128 *
129 * @return void
130 */
131 protected function simulateFrontendEnvironment() {
132 $this->tsfeBackup = isset($GLOBALS['TSFE']) ? $GLOBALS['TSFE'] : NULL;
133 $GLOBALS['TSFE'] = new \stdClass();
134 $GLOBALS['TSFE']->cObjectDepthCounter = 100;
135 }
136
137 /**
138 * Resets $GLOBALS['TSFE'] if it was previously changed by simulateFrontendEnvironment()
139 *
140 * @return void
141 * @see simulateFrontendEnvironment()
142 */
143 protected function resetFrontendEnvironment() {
144 $GLOBALS['TSFE'] = $this->tsfeBackup;
145 }
146 }