‪TYPO3CMS  ‪main
CObjectViewHelper.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ServerRequestInterface;
28 use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
29 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
30 use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
31 use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithContentArgumentAndRenderStatic;
32 
86 final class ‪CObjectViewHelper extends AbstractViewHelper
87 {
88  use CompileWithContentArgumentAndRenderStatic;
89 
95  protected ‪$escapeChildren = false;
96 
102  protected ‪$escapeOutput = false;
103 
104  public function ‪initializeArguments(): void
105  {
106  $this->registerArgument('data', 'mixed', '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');
107  $this->registerArgument('typoscriptObjectPath', 'string', 'the TypoScript setup path of the TypoScript object to render', true);
108  $this->registerArgument('currentValueKey', 'string', 'currentValueKey');
109  $this->registerArgument('table', 'string', 'the table name associated with "data" argument. Typically tt_content or one of your custom tables. This argument should be set if rendering a FILES cObject where file references are used, or if the data argument is a database record.', false, '');
110  }
111 
117  public static function ‪renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext): string
118  {
119  $data = $renderChildrenClosure();
120  $typoscriptObjectPath = (string)$arguments['typoscriptObjectPath'];
121  $currentValueKey = $arguments['currentValueKey'];
122  $table = $arguments['table'];
124  $request = $renderingContext->getRequest();
125  $contentObjectRenderer = ‪self::getContentObjectRenderer($request);
126  $contentObjectRenderer->setRequest($request);
127  $tsfeBackup = null;
128  if (!isset(‪$GLOBALS['TSFE']) || !(‪$GLOBALS['TSFE'] instanceof ‪TypoScriptFrontendController)) {
129  $tsfeBackup = ‪self::simulateFrontendEnvironment();
130  }
131  $currentValue = null;
132  if (is_object($data)) {
133  $data = ObjectAccess::getGettableProperties($data);
134  } elseif (is_string($data) || is_numeric($data)) {
135  $currentValue = (string)$data;
136  $data = [$data];
137  }
138  $contentObjectRenderer->start($data, $table);
139  if ($currentValue !== null) {
140  $contentObjectRenderer->setCurrentVal($currentValue);
141  } elseif ($currentValueKey !== null && isset($data[$currentValueKey])) {
142  $contentObjectRenderer->setCurrentVal($data[$currentValueKey]);
143  }
144  $pathSegments = ‪GeneralUtility::trimExplode('.', $typoscriptObjectPath);
145  $lastSegment = (string)array_pop($pathSegments);
147  foreach ($pathSegments as $segment) {
148  if (!array_key_exists($segment . '.', $setup)) {
149  throw new Exception(
150  'TypoScript object path "' . $typoscriptObjectPath . '" does not exist',
151  1253191023
152  );
153  }
154  $setup = $setup[$segment . '.'];
155  }
156  if (!isset($setup[$lastSegment])) {
157  throw new Exception(
158  'No Content Object definition found at TypoScript object path "' . $typoscriptObjectPath . '"',
159  1540246570
160  );
161  }
162  $content = ‪self::renderContentObject($contentObjectRenderer, $setup, $typoscriptObjectPath, $lastSegment);
163  if (!isset(‪$GLOBALS['TSFE']) || !(‪$GLOBALS['TSFE'] instanceof ‪TypoScriptFrontendController)) {
165  }
166  return $content;
167  }
168 
172  protected static function ‪renderContentObject(‪ContentObjectRenderer $contentObjectRenderer, array $setup, string $typoscriptObjectPath, string $lastSegment): string
173  {
174  $timeTracker = GeneralUtility::makeInstance(TimeTracker::class);
175  if ($timeTracker->LR) {
176  $timeTracker->push('/f:cObject/', '<' . $typoscriptObjectPath);
177  }
178  $timeTracker->incStackPointer();
179  $content = $contentObjectRenderer->‪cObjGetSingle($setup[$lastSegment], $setup[$lastSegment . '.'] ?? [], $typoscriptObjectPath);
180  $timeTracker->decStackPointer();
181  if ($timeTracker->LR) {
182  $timeTracker->pull($content);
183  }
184  return $content;
185  }
186 
188  {
189  // @todo: this should be replaced by DI once Fluid can handle DI properly
190  return GeneralUtility::getContainer()->get(ConfigurationManagerInterface::class);
191  }
192 
193  protected static function ‪getContentObjectRenderer(ServerRequestInterface $request): ‪ContentObjectRenderer
194  {
195  if ((‪$GLOBALS['TSFE'] ?? null) instanceof ‪TypoScriptFrontendController) {
196  $tsfe = ‪$GLOBALS['TSFE'];
197  } else {
198  $tsfe = GeneralUtility::makeInstance(TypoScriptFrontendController::class);
199  $tsfe->initializePageRenderer($request);
200  $tsfe->initializeLanguageService($request);
201  }
202  $contentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class, $tsfe);
203  $parent = $request->getAttribute('currentContentObject');
204  if ($parent instanceof ContentObjectRenderer) {
205  $contentObjectRenderer->‪setParent($parent->data, $parent->currentRecord);
206  }
207  return $contentObjectRenderer;
208  }
209 
213  protected static function ‪simulateFrontendEnvironment(): ?TypoScriptFrontendController
214  {
215  $tsfeBackup = ‪$GLOBALS['TSFE'] ?? null;
216  ‪$GLOBALS['TSFE'] = new \stdClass();
217  ‪$GLOBALS['TSFE']->cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
218  return $tsfeBackup;
219  }
220 
224  protected static function ‪resetFrontendEnvironment(?TypoScriptFrontendController $tsfeBackup): void
225  {
226  ‪$GLOBALS['TSFE'] = $tsfeBackup;
227  }
228 
232  public function ‪resolveContentArgumentName(): string
233  {
234  return 'data';
235  }
236 }
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\resetFrontendEnvironment
‪static resetFrontendEnvironment(?TypoScriptFrontendController $tsfeBackup)
Definition: CObjectViewHelper.php:221
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer\setParent
‪setParent($data, $currentRecord)
Definition: ContentObjectRenderer.php:468
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\getConfigurationManager
‪static getConfigurationManager()
Definition: CObjectViewHelper.php:184
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
Definition: ConfigurationManagerInterface.php:28
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\getContentObjectRenderer
‪static getContentObjectRenderer(ServerRequestInterface $request)
Definition: CObjectViewHelper.php:190
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\resolveContentArgumentName
‪resolveContentArgumentName()
Definition: CObjectViewHelper.php:229
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\renderStatic
‪static renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
Definition: CObjectViewHelper.php:114
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer\cObjGetSingle
‪string cObjGetSingle(string $name, $conf, $TSkey='__')
Definition: ContentObjectRenderer.php:554
‪TYPO3\CMS\Extbase\Reflection\ObjectAccess
Definition: ObjectAccess.php:39
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper
Definition: CObjectViewHelper.php:87
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\initializeArguments
‪initializeArguments()
Definition: CObjectViewHelper.php:101
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\$escapeOutput
‪bool $escapeOutput
Definition: CObjectViewHelper.php:99
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\simulateFrontendEnvironment
‪static simulateFrontendEnvironment()
Definition: CObjectViewHelper.php:210
‪TYPO3\CMS\Fluid\ViewHelpers
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface\CONFIGURATION_TYPE_FULL_TYPOSCRIPT
‪const CONFIGURATION_TYPE_FULL_TYPOSCRIPT
Definition: ConfigurationManagerInterface.php:31
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\renderContentObject
‪static renderContentObject(ContentObjectRenderer $contentObjectRenderer, array $setup, string $typoscriptObjectPath, string $lastSegment)
Definition: CObjectViewHelper.php:169
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
Definition: TypoScriptFrontendController.php:58
‪TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper\$escapeChildren
‪bool $escapeChildren
Definition: CObjectViewHelper.php:93
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
Definition: ContentObjectRenderer.php:102
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Fluid\Core\Rendering\RenderingContext
Definition: RenderingContext.php:35
‪TYPO3\CMS\Core\TimeTracker\TimeTracker
Definition: TimeTracker.php:34
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822