‪TYPO3CMS  ‪main
Richtext.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 TYPO3\CMS\Backend\Utility\BackendUtility;
26 
34 {
45  public function ‪getConfiguration(string $table, string $field, int $pid, string $recordType, array $tcaFieldConf): array
46  {
47  // create instance of NodeFactory, ask for "text" element
48  //
49  // As soon as the Data handler starts using FormDataProviders, this class can vanish again, and the hack to
50  // test for specific rich text instances can be dropped: Split the "TcaText" data provider into multiple parts, each
51  // RTE should register and own data provider that does the transformation / configuration providing. This way,
52  // the explicit check for different RTE classes is removed from core and "hooked in" by the RTE's.
53 
54  // The main problem here is that all parameters that the processing needs is handed over to as TSconfig
55  // "dotted array" syntax. We convert at least the processing information available under "processing"
56  // together with pageTS, this way it can be overridden and understood in RteHtmlParser.
57  // However, all other parts of the core will depend on the non-dotted syntax (coming from YAML directly)
58 
59  $pageTs = $this->‪getPageTsConfiguration($table, $field, $pid, $recordType);
60 
61  // determine which preset to use
62  $pageTs['preset'] = $pageTs['fieldSpecificPreset'] ?? $tcaFieldConf['richtextConfiguration'] ?? $pageTs['generalPreset'] ?? 'default';
63  unset($pageTs['fieldSpecificPreset']);
64  unset($pageTs['generalPreset']);
65 
66  // load configuration from preset
67  $configuration = $this->‪loadConfigurationFromPreset($pageTs['preset']);
68 
69  // overlay preset configuration with pageTs
70  ArrayUtility::mergeRecursiveWithOverrule(
71  $configuration,
72  $this->‪addFlattenedPageTsConfig($pageTs)
73  );
74 
75  // Handle "mode" / "transformation" config when overridden
76  if (!isset($configuration['proc.']['mode']) && !isset($configuration['proc.']['overruleMode'])) {
77  $configuration['proc.']['overruleMode'] = 'default';
78  }
79 
80  return GeneralUtility::makeInstance(
81  CKEditor5Migrator::class,
82  $configuration
83  )->get();
84  }
85 
92  protected function ‪loadConfigurationFromPreset(string $presetName = ''): array
93  {
94  $configuration = [];
95  if (!empty($presetName) && isset(‪$GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets'][$presetName])) {
96  $runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('runtime');
97  ‪$identifier = 'richtext_' . $presetName;
98  $configuration = $runtimeCache->get(‪$identifier);
99 
100  if ($configuration === false) {
101  $fileLoader = GeneralUtility::makeInstance(YamlFileLoader::class);
102  $configuration = $fileLoader->load(‪$GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets'][$presetName]);
103  // For future versions, you should however rely on the "processing" key and not the "proc" key.
104  if (is_array($configuration['processing'] ?? null)) {
105  $configuration['proc.'] = $this->‪convertPlainArrayToTypoScriptArray($configuration['processing']);
106  }
107  $runtimeCache->set(‪$identifier, $configuration);
108  }
109  }
110  return $configuration;
111  }
112 
119  protected function ‪getRtePageTsConfigOfPid(int $pid): array
120  {
121  return BackendUtility::getPagesTSconfig($pid)['RTE.'] ?? [];
122  }
123 
132  protected function ‪convertPlainArrayToTypoScriptArray(array $plainArray)
133  {
134  $typoScriptArray = [];
135  foreach ($plainArray as $key => $value) {
136  if (is_array($value)) {
137  if (!isset($typoScriptArray[$key])) {
138  $typoScriptArray[$key] = 1;
139  }
140  $typoScriptArray[$key . '.'] = $this->‪convertPlainArrayToTypoScriptArray($value);
141  } else {
142  $typoScriptArray[$key] = $value ?? '';
143  }
144  }
145  return $typoScriptArray;
146  }
147 
156  protected function ‪addFlattenedPageTsConfig(array $typoScriptArray): array
157  {
158  foreach ($typoScriptArray as $key => $data) {
159  if (!str_ends_with($key, '.')) {
160  continue;
161  }
162  $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
163  $typoScriptArray[substr($key, 0, -1)] = $typoScriptService->convertTypoScriptArrayToPlainArray($typoScriptArray[$key]);
164  }
165 
166  return $typoScriptArray;
167  }
168 
179  protected function ‪getPageTsConfiguration(string $table, string $field, int $pid, string $recordType): array
180  {
181  // Load page TSconfig configuration
182  $fullPageTsConfig = $this->‪getRtePageTsConfigOfPid($pid);
183  $defaultPageTsConfigOverrides = $fullPageTsConfig['default.'] ?? null;
184 
185  $defaultPageTsConfigOverrides['generalPreset'] = $fullPageTsConfig['default.']['preset'] ?? null;
186 
187  $fieldSpecificPageTsConfigOverrides = $fullPageTsConfig['config.'][$table . '.'][$field . '.'] ?? null;
188  unset($fullPageTsConfig['default.'], $fullPageTsConfig['config.']);
189 
190  // First use RTE.*
191  $rtePageTsConfiguration = $fullPageTsConfig;
192 
193  // Then overload with RTE.default.*
194  if (is_array($defaultPageTsConfigOverrides)) {
195  ArrayUtility::mergeRecursiveWithOverrule($rtePageTsConfiguration, $defaultPageTsConfigOverrides);
196  }
197 
198  $rtePageTsConfiguration['fieldSpecificPreset'] = $fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.']['preset'] ??
199  $fieldSpecificPageTsConfigOverrides['preset'] ?? null;
200 
201  // Then overload with RTE.config.tt_content.bodytext
202  if (is_array($fieldSpecificPageTsConfigOverrides)) {
203  $fieldSpecificPageTsConfigOverridesWithoutType = $fieldSpecificPageTsConfigOverrides;
204  unset($fieldSpecificPageTsConfigOverridesWithoutType['types.']);
205  ArrayUtility::mergeRecursiveWithOverrule($rtePageTsConfiguration, $fieldSpecificPageTsConfigOverridesWithoutType);
206 
207  // Then overload with RTE.config.tt_content.bodytext.types.textmedia
208  if (
209  $recordType
210  && isset($fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.'])
211  && is_array($fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.'])
212  ) {
213  ArrayUtility::mergeRecursiveWithOverrule(
214  $rtePageTsConfiguration,
215  $fieldSpecificPageTsConfigOverrides['types.'][$recordType . '.']
216  );
217  }
218  }
219 
220  unset($rtePageTsConfiguration['preset']);
221 
222  return $rtePageTsConfiguration;
223  }
224 }
‪TYPO3\CMS\Core\Configuration\Richtext\addFlattenedPageTsConfig
‪array addFlattenedPageTsConfig(array $typoScriptArray)
Definition: Richtext.php:156
‪TYPO3\CMS\Core\Configuration\Richtext\getPageTsConfiguration
‪getPageTsConfiguration(string $table, string $field, int $pid, string $recordType)
Definition: Richtext.php:179
‪TYPO3\CMS\Core\Configuration\Richtext\getRtePageTsConfigOfPid
‪array getRtePageTsConfigOfPid(int $pid)
Definition: Richtext.php:119
‪TYPO3\CMS\Core\Configuration\Richtext\convertPlainArrayToTypoScriptArray
‪array convertPlainArrayToTypoScriptArray(array $plainArray)
Definition: Richtext.php:132
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\Configuration\Richtext\getConfiguration
‪getConfiguration(string $table, string $field, int $pid, string $recordType, array $tcaFieldConf)
Definition: Richtext.php:45
‪TYPO3\CMS\Core\TypoScript\TypoScriptService
Definition: TypoScriptService.php:27
‪TYPO3\CMS\Core\Configuration\Loader\YamlFileLoader
Definition: YamlFileLoader.php:47
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:26
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Configuration
Definition: CKEditor5Migrator.php:18
‪TYPO3\CMS\Core\Configuration\Richtext\loadConfigurationFromPreset
‪array loadConfigurationFromPreset(string $presetName='')
Definition: Richtext.php:92
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Configuration\Richtext
Definition: Richtext.php:34
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37