From a5fccf8879b6507d5e94a67a73566ce8a3430506 Mon Sep 17 00:00:00 2001 From: Hannes Lau <office@hanneslau.de> Date: Sun, 16 Jul 2017 13:51:58 +0200 Subject: [PATCH] [TASK] Allow to override RTE config presets via PageTS Reorder the steps to load the RTE configuration, so that presets can be overridden by additional PageTS configuration. Resolves: #81882 Releases: master, 8.7 Change-Id: I0189822f8a4a0cf3b8293d6651eac4f8b5159566 Reviewed-on: https://review.typo3.org/53531 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Frans Saris <franssaris@gmail.com> Reviewed-by: Andreas Fernandez <typo3@scripting-base.de> Tested-by: Andreas Fernandez <typo3@scripting-base.de> --- .../core/Classes/Configuration/Richtext.php | 113 ++++++++++-------- .../Tests/Unit/Configuration/RichtextTest.php | 53 ++++++++ 2 files changed, 114 insertions(+), 52 deletions(-) diff --git a/typo3/sysext/core/Classes/Configuration/Richtext.php b/typo3/sysext/core/Classes/Configuration/Richtext.php index 8634fc9f0585..77bd51346c33 100644 --- a/typo3/sysext/core/Classes/Configuration/Richtext.php +++ b/typo3/sysext/core/Classes/Configuration/Richtext.php @@ -55,60 +55,19 @@ class Richtext // together with pageTS, this way it can be overridden and understood in RteHtmlParser. // However, all other parts of the core will depend on the non-dotted syntax (coming from Yaml directly) - if (!isset($tcaFieldConf['richtextConfiguration'])) { - $tcaFieldConf['richtextConfiguration'] = 'default'; - } - $usePreset = $tcaFieldConf['richtextConfiguration']; - $configuration = $this->loadConfigurationFromPreset($tcaFieldConf['richtextConfiguration']); + $pageTs = $this->getPageTsConfiguration($table, $field, $pid, $recordType); - // Overload with PageTSconfig configuration - // First use RTE.* - // Then overload with RTE.default - // Then overload with RTE.config.tt_content.bodytext - // Then overload with RTE.config.tt_content.bodytext.types.textmedia - $fullPageTsConfig = $this->getRtePageTsConfigOfPid($pid); - $fullPageTsConfig = !empty($fullPageTsConfig['properties']) ? $fullPageTsConfig['properties'] : []; - $defaultPageTsConfigOverrides = isset($fullPageTsConfig['default.']) ? $fullPageTsConfig['default.'] : null; - $fieldSpecificPageTsConfigOverrides = isset($fullPageTsConfig['config.'][$table . '.'][$field . '.']) ? $fullPageTsConfig['config.'][$table . '.'][$field . '.'] : null; - unset($fullPageTsConfig['default.'], $fullPageTsConfig['config.']); - // RTE.* (used for RTE.classesAnchor or similar in RTEHtmlArea) - if (!empty($fullPageTsConfig)) { - ArrayUtility::mergeRecursiveWithOverrule( - $configuration, - $this->cleanDotsFromEditorConfigKeys($fullPageTsConfig) - ); - } - // RTE.default.* - if (is_array($defaultPageTsConfigOverrides)) { - ArrayUtility::mergeRecursiveWithOverrule( - $configuration, - $this->cleanDotsFromEditorConfigKeys($defaultPageTsConfigOverrides) - ); - } - // RTE.config.tt_content.bodytext and based on type as well - if (is_array($fieldSpecificPageTsConfigOverrides)) { - $fieldSpecificPageTsConfigOverridesWithoutType = $fieldSpecificPageTsConfigOverrides; - unset($fieldSpecificPageTsConfigOverridesWithoutType['types.']); - ArrayUtility::mergeRecursiveWithOverrule( - $configuration, - $this->cleanDotsFromEditorConfigKeys($fieldSpecificPageTsConfigOverridesWithoutType) - ); - if ($recordType - && isset($fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.']) - && is_array($fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.'])) { - ArrayUtility::mergeRecursiveWithOverrule( - $configuration, - $this->cleanDotsFromEditorConfigKeys($fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.']) - ); - } - } + // determine which preset to use + $usePreset = $pageTs['preset'] ?? $tcaFieldConf['richtextConfiguration'] ?? 'default'; - // Reload the base configuration, if overridden via PageTS "RTE.default.preset = Minimal" for instance - // However, if a preset is chosen via TSconfig, then it is not possible to override anything else again - // via TSconfig (endless loop). - if (isset($configuration['preset']) && $usePreset !== $configuration['preset']) { - $configuration = $this->loadConfigurationFromPreset($configuration['preset']); - } + // load configuration from preset + $configuration = $this->loadConfigurationFromPreset($usePreset); + + // overlay preset configuration with pageTs + ArrayUtility::mergeRecursiveWithOverrule( + $configuration, + $this->cleanDotsFromEditorConfigKeys($pageTs) + ); // Handle "mode" / "transformation" config when overridden if (!isset($configuration['proc.']['mode']) && !isset($configuration['proc.']['overruleMode'])) { @@ -201,4 +160,54 @@ class Richtext return $typoScriptArray; } + + /** + * Load PageTS configuration for the RTE + * + * Return RTE section of page TS, taking into account overloading via table, field and record type + * + * @param string $table The table the field is in + * @param string $field Field name + * @param int $pid Real page id + * @param string $recordType Record type value + * @return array + */ + protected function getPageTsConfiguration(string $table, string $field, int $pid, string $recordType) : array + { + // Load PageTSconfig configuration + $fullPageTsConfig = $this->getRtePageTsConfigOfPid($pid); + $fullPageTsConfig = !empty($fullPageTsConfig['properties']) ? $fullPageTsConfig['properties'] : []; + $defaultPageTsConfigOverrides = isset($fullPageTsConfig['default.']) ? $fullPageTsConfig['default.'] : null; + $fieldSpecificPageTsConfigOverrides = isset($fullPageTsConfig['config.'][$table . '.'][$field . '.']) ? $fullPageTsConfig['config.'][$table . '.'][$field . '.'] : null; + unset($fullPageTsConfig['default.'], $fullPageTsConfig['config.']); + + // First use RTE.* + $rtePageTsConfiguration = $fullPageTsConfig; + + // Then overload with RTE.default.* + if (is_array($defaultPageTsConfigOverrides)) { + ArrayUtility::mergeRecursiveWithOverrule($rtePageTsConfiguration, $defaultPageTsConfigOverrides); + } + + // Then overload with RTE.config.tt_content.bodytext + if (is_array($fieldSpecificPageTsConfigOverrides)) { + $fieldSpecificPageTsConfigOverridesWithoutType = $fieldSpecificPageTsConfigOverrides; + unset($fieldSpecificPageTsConfigOverridesWithoutType['types.']); + ArrayUtility::mergeRecursiveWithOverrule($rtePageTsConfiguration, $fieldSpecificPageTsConfigOverridesWithoutType); + + // Then overload with RTE.config.tt_content.bodytext.types.textmedia + if ( + $recordType + && isset($fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.']) + && is_array($fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.']) + ) { + ArrayUtility::mergeRecursiveWithOverrule( + $rtePageTsConfiguration, + $fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.'] + ); + } + } + + return $rtePageTsConfiguration; + } } diff --git a/typo3/sysext/core/Tests/Unit/Configuration/RichtextTest.php b/typo3/sysext/core/Tests/Unit/Configuration/RichtextTest.php index 4ddd30b19ad7..6f05c11c18e7 100644 --- a/typo3/sysext/core/Tests/Unit/Configuration/RichtextTest.php +++ b/typo3/sysext/core/Tests/Unit/Configuration/RichtextTest.php @@ -324,4 +324,57 @@ class RichtextTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase $output = $subject->getConfiguration('aTable', 'aField', 42, 'textmedia', $fieldConfig); $this->assertSame($expected, $output); } + + /** + * @test + */ + public function getConfigurationPageTsOverridesPreset() + { + $pageId = 42; + $presetKey = 'default'; + + $preset = [ + 'editor' => [ + 'config' => [ + 'width' => 100 + ], + ], + ]; + + $pageTsConfigArray = [ + 'properties' => [ + 'preset' => $presetKey, + 'editor.' => [ + 'config.' => [ + 'width' => 200 + ], + ], + ], + ]; + + $subject = $this->getAccessibleMock(Richtext::class, + ['loadConfigurationFromPreset', 'getRtePageTsConfigOfPid'], + [], + '', + false + ); + $subject->expects($this->once())->method('loadConfigurationFromPreset')->with($presetKey)->willReturn($preset); + $subject->expects($this->once())->method('getRtePageTsConfigOfPid')->with($pageId)->willReturn($pageTsConfigArray); + + $output = $subject->getConfiguration('tt_content', 'bodytext', $pageId, 'textmedia', $pageTsConfigArray); + + $expected = [ + 'editor' => [ + 'config' => [ + 'width' => 200 + ], + ], + 'preset' => 'default', + 'proc.' => [ + 'overruleMode' => 'default', + ], + ]; + + $this->assertSame($expected, $output); + } } -- GitLab