| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- <?php
- namespace Opentalent\OtTemplating\ViewHelpers;
- use TYPO3\CMS\Core\Utility\GeneralUtility;
- use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
- use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
- use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
- use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
- /**
- * This view helper is a wrapper for the Fluid/CObjectViewhelper class
- * that allow to override the TS setup of the object by given variables
- *
- * It accepts the same arguments as \TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper,
- * and an additional argument 'settings'
- *
- * @see https://docs.typo3.org/p/georgringer/news/master/en-us/Introduction/Index.html
- *
- * example:
- *
- * {namespace ot=Opentalent\OtTemplating\ViewHelpers}
- *
- * <ot:cObject typoscriptObjectPath="lib.tx_ottemplating.widgets.news_list"
- * settings="{'settings.defaultPageUid': 1}" />
- *
- *
- * @package Opentalent\OtTemplating\ViewHelpers
- */
- class CObjectViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper {
- /**
- * Initialize arguments.
- *
- * @throws Exception
- */
- public function initializeArguments()
- {
- parent::initializeArguments();
- $this->registerArgument(
- 'settings',
- 'array',
- 'For each key in this array, the setup entry will be replaced by the corresponding value',
- false,
- []
- );
- }
- /**
- * <!> This is a copy/paste of the parent method, slighly modified
- * to override the $setup variable with the 'settings' argument
- *
- * Renders the TypoScript object in the given TypoScript setup path.
- *
- * @param array $arguments
- * @param \Closure $renderChildrenClosure
- * @param RenderingContextInterface $renderingContext
- * @return mixed
- * @throws Exception
- */
- public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
- {
- $data = $renderChildrenClosure();
- $typoscriptObjectPath = $arguments['typoscriptObjectPath'];
- $currentValueKey = $arguments['currentValueKey'];
- $table = $arguments['table'];
- $contentObjectRenderer = static::getContentObjectRenderer();
- if (!isset($GLOBALS['TSFE']) || !($GLOBALS['TSFE'] instanceof TypoScriptFrontendController)) {
- static::simulateFrontendEnvironment();
- }
- $currentValue = null;
- if (is_object($data)) {
- $data = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettableProperties($data);
- } elseif (is_string($data) || is_numeric($data)) {
- $currentValue = (string)$data;
- $data = [$data];
- }
- $contentObjectRenderer->start($data, $table);
- if ($currentValue !== null) {
- $contentObjectRenderer->setCurrentVal($currentValue);
- } elseif ($currentValueKey !== null && isset($data[$currentValueKey])) {
- $contentObjectRenderer->setCurrentVal($data[$currentValueKey]);
- }
- $pathSegments = GeneralUtility::trimExplode('.', $typoscriptObjectPath);
- $lastSegment = array_pop($pathSegments);
- $setup = static::getConfigurationManager()->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
- foreach ($pathSegments as $segment) {
- if (!array_key_exists($segment . '.', $setup)) {
- throw new Exception(
- 'TypoScript object path "' . $typoscriptObjectPath . '" does not exist',
- 1253191023
- );
- }
- $setup = $setup[$segment . '.'];
- }
- if (!isset($setup[$lastSegment])) {
- throw new Exception(
- 'No Content Object definition found at TypoScript object path "' . $typoscriptObjectPath . '"',
- 1540246570
- );
- }
- // <---- Added by Opentalent to override the TS setup
- $setup = self::evalConfiguration($setup, $lastSegment, $arguments['settings']);
- // ----->
- $content = self::renderContentObject($contentObjectRenderer, $setup, $typoscriptObjectPath, $lastSegment);
- if (!isset($GLOBALS['TSFE']) || !($GLOBALS['TSFE'] instanceof TypoScriptFrontendController)) {
- static::resetFrontendEnvironment();
- }
- return $content;
- }
- /**
- * Recursively replace any {$var} value in the given configuration
- * if 'var' is a key in the 'overrideSetup' array
- *
- * @param array $setup
- * @param string $entry_name
- * @param array $override_settings
- * @return array
- */
- private static function evalConfiguration(array $setup, string $entry_name, array $override_settings) {
- $entry_setup = $setup[$entry_name . '.'];
- foreach ($override_settings as $key => $val) {
- $override = [];
- $path = explode('.', $key);
- foreach (array_reverse($path) as $i => $segment) {
- if ($i == 0) {
- $override[$segment] = $val;
- } else {
- $override = [$segment . '.' => $override];
- }
- }
- $entry_setup = self::merge($entry_setup, $override);
- }
- $setup[$entry_name . '.'] = $entry_setup;
- return $setup;
- }
- /**
- * Similar to array_merge_recursive, except that the end nodes of the
- * base array is replaced and not merged.
- *
- * @param $base_array
- * @param $override
- * @return mixed
- */
- private static function merge($base_array, $override) {
- foreach ($base_array as $key => $val) {
- if (!isset($override[$key])) {
- continue;
- }
- if (is_array($val)) {
- $base_array[$key] = self::merge($val, $override[$key]);
- } else {
- $base_array[$key] = $override[$key];
- }
- }
- return $base_array;
- }
- }
|