2 declare(strict_types = 1);
38 'renderType' =>
'tcaDescription',
48 'localizationStateSelector' => [
49 'renderType' =>
'localizationStateSelector',
51 'otherLanguageContent' => [
52 'renderType' =>
'otherLanguageContent',
54 'localizationStateSelector'
57 'defaultLanguageDifferences' => [
58 'renderType' =>
'defaultLanguageDifferences',
60 'otherLanguageContent',
79 public function render(): array
82 $parameterArray = $this->data[
'parameterArray'];
83 $config = $parameterArray[
'fieldConf'][
'config'];
86 $itemFormElementName = $this->data[
'parameterArray'][
'itemFormElName'];
88 $value = $this->data[
'parameterArray'][
'itemFormElValue'] ??
'';
91 $fieldInformationHtml = $fieldInformationResult[
'html'];
95 $fieldControlHtml = $fieldControlResult[
'html'];
99 $fieldWizardHtml = $fieldWizardResult[
'html'];
103 'style' =>
'display:none',
106 'name' => htmlspecialchars($itemFormElementName),
110 $html[] =
'<div class="formengine-field-item t3js-formengine-field-item">';
111 $html[] = $fieldInformationHtml;
112 $html[] =
'<div class="form-control-wrap">';
113 $html[] =
'<div class="form-wizards-wrap">';
114 $html[] =
'<div class="form-wizards-element">';
115 $html[] =
'<textarea ' . GeneralUtility::implodeAttributes($attributes,
true) .
'>';
116 $html[] = htmlspecialchars($value);
117 $html[] =
'</textarea>';
119 if (!empty($fieldControlHtml)) {
120 $html[] =
'<div class="form-wizards-items-aside">';
121 $html[] =
'<div class="btn-group">';
122 $html[] = $fieldControlHtml;
126 if (!empty($fieldWizardHtml)) {
127 $html[] =
'<div class="form-wizards-items-bottom">';
128 $html[] = $fieldWizardHtml;
135 $resultArray[
'html'] = implode(LF, $html);
137 $this->rteConfiguration = $config[
'richtextConfiguration'][
'editor'];
138 $resultArray[
'requireJsModules'][] = [
152 $currentLanguageUid = $this->data[
'databaseRow'][
'sys_language_uid'];
153 if (is_array($currentLanguageUid)) {
154 $currentLanguageUid = $currentLanguageUid[0];
156 $contentLanguageUid = (int)max($currentLanguageUid, 0);
157 if ($contentLanguageUid) {
158 $contentLanguage = $this->data[
'systemLanguageRows'][$currentLanguageUid][
'iso'];
160 $contentLanguage = $this->rteConfiguration[
'config'][
'defaultContentLanguage'] ??
'en_US';
161 $languageCodeParts = explode(
'_', $contentLanguage);
162 $contentLanguage = strtolower($languageCodeParts[0]) . ($languageCodeParts[1] ?
'_' . strtoupper($languageCodeParts[1]) :
'');
164 $locales = GeneralUtility::makeInstance(Locales::class);
166 if (!in_array($contentLanguage,
$locales->getLocales(),
true)) {
167 $contentLanguage =
'en';
170 return $contentLanguage;
184 $externalPlugins =
'';
185 foreach ($this->
getExtraPlugins() as $extraPluginName => $extraPluginConfig) {
186 $configName = $extraPluginConfig[
'configName'] ?? $extraPluginName;
187 if (!empty($extraPluginConfig[
'config']) && is_array($extraPluginConfig[
'config'])) {
188 if (empty($configuration[$configName])) {
189 $configuration[$configName] = $extraPluginConfig[
'config'];
190 } elseif (is_array($configuration[$configName])) {
191 $configuration[$configName] = array_replace_recursive($extraPluginConfig[
'config'], $configuration[$configName]);
194 $configuration[
'extraPlugins'] .=
',' . $extraPluginName;
196 $externalPlugins .=
'CKEDITOR.plugins.addExternal(';
197 $externalPlugins .= GeneralUtility::quoteJSvalue($extraPluginName) .
',';
198 $externalPlugins .= GeneralUtility::quoteJSvalue($extraPluginConfig[
'resource']) .
',';
199 $externalPlugins .=
'\'\
');';
202 $jsonConfiguration = json_encode($configuration);
206 $configurationHash = GeneralUtility::shortMD5($jsonConfiguration);
208 return 'function(CKEDITOR) {
209 CKEDITOR.timestamp += "-' . $configurationHash .
'";
210 ' . $externalPlugins .
'
211 require([\'jquery\', \'TYPO3/CMS/Backend/FormEngine\'], function($, FormEngine) {
213 var escapedFieldSelector = \'#\' + $.escapeSelector(\'' . $fieldId .
'\');
214 CKEDITOR.replace(
"' . $fieldId . '",
' . $jsonConfiguration . ');
215 CKEDITOR.instances[
"' . $fieldId . '"].on(\
'change\', function(e) {
216 var commands = e.sender.commands;
217 CKEDITOR.instances["' . $fieldId .
'"].updateElement();
218 FormEngine.Validation.validate();
219 FormEngine.Validation.markFieldAsChanged($(escapedFieldSelector));
221 // remember changes done in maximized state and mark field as changed, once minimized again
222 if (typeof commands.maximize !== \'undefined\' && commands.maximize.state === 1) {
223 CKEDITOR.instances["' . $fieldId .
'"].on(\'maximize\', function(e) {
224 $(this).off(\'maximize\');
225 FormEngine.Validation.markFieldAsChanged($(escapedFieldSelector));
229 CKEDITOR.instances["' . $fieldId .
'"].on(\'mode\', function() {
230 // detect field changes in source mode
231 if (this.mode === \'source\') {
232 var sourceArea = CKEDITOR.instances["' . $fieldId .
'"].editable();
233 sourceArea.attachListener(sourceArea, \'change\', function() {
234 FormEngine.Validation.markFieldAsChanged($(escapedFieldSelector));
238 $(document).on(\'inline:sorting-changed\', function() {
239 CKEDITOR.instances["' . $fieldId .
'"].destroy();
240 CKEDITOR.replace("' . $fieldId .
'", ' . $jsonConfiguration .
');
242 $(document).on(\'flexform:sorting-changed\', function() {
243 CKEDITOR.instances["' . $fieldId .
'"].destroy();
244 CKEDITOR.replace("' . $fieldId .
'", ' . $jsonConfiguration .
');
260 'table' => $this->data[
'tableName'],
261 'uid' => $this->data[
'databaseRow'][
'uid'],
262 'fieldName' => $this->data[
'fieldName'],
263 'recordType' => $this->data[
'recordTypeValue'],
264 'pid' => $this->data[
'effectivePid'],
265 'richtextConfigurationName' => $this->data[
'parameterArray'][
'fieldConf'][
'config'][
'richtextConfigurationName']
269 $pluginConfiguration = [];
270 if (isset($this->rteConfiguration[
'externalPlugins']) && is_array($this->rteConfiguration[
'externalPlugins'])) {
271 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
272 foreach ($this->rteConfiguration[
'externalPlugins'] as $pluginName => $configuration) {
273 $pluginConfiguration[$pluginName] = [
274 'configName' => $configuration[
'configName'] ?? $pluginName,
277 unset($configuration[
'configName'], $configuration[
'resource']);
279 if ($configuration[
'route']) {
280 $configuration[
'routeUrl'] = (string)$uriBuilder->buildUriFromRoute($configuration[
'route'], $urlParameters);
283 $pluginConfiguration[$pluginName][
'config'] = $configuration;
286 return $pluginConfiguration;
297 foreach ($configuration as $key => $value) {
298 if (is_array($value)) {
300 } elseif (is_string($value) && stripos($value,
'LLL:') === 0) {
304 return $configuration;
315 foreach ($configuration as $key => $value) {
316 if (is_array($value)) {
318 } elseif (is_string($value) && stripos($value,
'EXT:') === 0) {
322 return $configuration;
333 $value = GeneralUtility::getFileAbsFileName($value);
348 'customConfig' =>
'',
351 if (is_array($this->rteConfiguration[
'config'])) {
352 $configuration = array_replace_recursive($configuration, $this->rteConfiguration[
'config']);
355 if (empty($configuration[
'language'])) {
366 if (is_array($configuration[
'extraPlugins'])) {
367 $configuration[
'extraPlugins'] = implode(
',', $configuration[
'extraPlugins']);
369 if (is_array($configuration[
'removePlugins'])) {
370 $configuration[
'removePlugins'] = implode(
',', $configuration[
'removePlugins']);
372 if (is_array($configuration[
'removeButtons'])) {
373 $configuration[
'removeButtons'] = implode(
',', $configuration[
'removeButtons']);
376 return $configuration;
385 $fieldId = preg_replace(
'/[^a-zA-Z0-9_:.-]/',
'_', $itemFormElementName);
386 return htmlspecialchars(preg_replace(
'/^[^a-zA-Z]/',
'x', $fieldId));