|
|
@@ -0,0 +1,165 @@
|
|
|
+<?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;
|
|
|
+ }
|
|
|
+}
|