[TASK] Extract flex form language handling to compatibility6 01/43601/4
authorChristian Kuhn <lolli@schwarzbu.ch>
Sun, 27 Sep 2015 16:21:10 +0000 (18:21 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Wed, 30 Sep 2015 21:08:23 +0000 (23:08 +0200)
Flex form has its own localization handling that exists in parallel
to the record overlay based system. This was introduced together with
the TemplaVoila concept and is almost exclusively used in this context.
For details, the logic is described in the flex form section of
the "localization guide".

With the FormEngine refactoring it is now possible to extract most
parts of this language handling to ext:compatibility6. The patch
moves the current handling classes to compatibility6 and registers
them.

This extraction gives TemplaVoila and maybe other extensions the
opportunity to implement this handling on their own, compatibility6
can be used as a show case how that may be achieved.

As main benefit the classes in FormEngine are significantly
shorter, easier to understand and quite a few options can
be dropped.

Resolves: #70138
Releases: master
Change-Id: Ia2c4b8b329702b895b9183f835423c2d27b7c74a
Reviewed-on: http://review.typo3.org/43601
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
28 files changed:
typo3/sysext/backend/Classes/Form/Container/FlexFormElementContainer.php
typo3/sysext/backend/Classes/Form/Container/FlexFormEntryContainer.php [new file with mode: 0644]
typo3/sysext/backend/Classes/Form/Container/FlexFormLanguageContainer.php [deleted file]
typo3/sysext/backend/Classes/Form/Container/FlexFormNoTabsContainer.php
typo3/sysext/backend/Classes/Form/Container/FlexFormTabsContainer.php
typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php
typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php
typo3/sysext/backend/Classes/Form/NodeFactory.php
typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaFlexProcessTest.php
typo3/sysext/compatibility6/Classes/Configuration/FlexForm/FlexFormTools.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Form/Container/FlexFormElementContainer.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Form/Container/FlexFormEntryContainer.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Form/Container/FlexFormNoTabsContainer.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Form/Container/FlexFormTabsContainer.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Form/FormDataProvider/TcaFlexProcess.php [new file with mode: 0644]
typo3/sysext/compatibility6/Tests/Unit/Form/FormDataProvider/TcaFlexProcessTest.php [new file with mode: 0644]
typo3/sysext/compatibility6/ext_localconf.php
typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php
typo3/sysext/core/Classes/DataHandling/DataHandler.php
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Configuration/Resource/Driver/LocalDriverFlexForm.xml
typo3/sysext/core/Documentation/Changelog/master/Deprecation-70138-FlexFormLanguageHandling.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Functional/Fixtures/Extensions/irre_tutorial/Configuration/FlexForms/tt_content_flexform.xml
typo3/sysext/css_styled_content/flexform_ds.xml
typo3/sysext/felogin/Configuration/FlexForms/Login.xml
typo3/sysext/impexp/Tests/Functional/Fixtures/Extensions/impexp_group_files/Configuration/TCA/tx_impexpgroupfiles_item.php
typo3/sysext/install/Classes/Service/SilentConfigurationUpgradeService.php
typo3/sysext/mediace/Configuration/FlexForms/media.xml

index 829c64d..6a9ee06 100644 (file)
@@ -14,13 +14,10 @@ namespace TYPO3\CMS\Backend\Form\Container;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Lang\LanguageService;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation;
-use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 
 /**
@@ -40,16 +37,12 @@ class FlexFormElementContainer extends AbstractContainer {
         */
        public function render() {
                $table = $this->data['tableName'];
-               $row = $this->data['databaseRow'];
                $flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
                $flexFormRowData = $this->data['flexFormRowData'];
                $flexFormFormPrefix = $this->data['flexFormFormPrefix'];
                $parameterArray = $this->data['parameterArray'];
-               $metaData = $this->data['parameterArray']['fieldConf']['config']['ds']['meta'];
 
                $languageService = $this->getLanguageService();
-               /** @var IconFactory $iconFactory */
-               $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
                $resultArray = $this->initializeResultArray();
                foreach ($flexFormDataStructureArray as $flexFormFieldName => $flexFormFieldArray) {
                        if (
@@ -75,108 +68,77 @@ class FlexFormElementContainer extends AbstractContainer {
 
                                $options = $this->data;
                                $options['flexFormDataStructureArray'] = $flexFormFieldArray['el'];
-                               $options['flexFormRowData'] = is_array($flexFormRowData[$flexFormFieldName]['el']) ? $flexFormRowData[$flexFormFieldName]['el'] : array();
+                               $options['flexFormRowData'] = isset($flexFormRowData[$flexFormFieldName]['el']) ? $flexFormRowData[$flexFormFieldName]['el'] : [];
                                $options['flexFormSectionType'] = $flexFormFieldName;
                                $options['flexFormSectionTitle'] = $sectionTitle;
                                $options['renderType'] = 'flexFormSectionContainer';
                                $sectionContainerResult = $this->nodeFactory->create($options)->render();
                                $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $sectionContainerResult);
                        } else {
-                               if (is_array($metaData) && isset($metaData['langChildren']) && isset($metaData['languagesOnElement'])) {
-                                       $lkeys = $metaData['languagesOnElement'];
-                                       array_walk($lkeys, function (&$value) {
-                                               $value = 'v' . $value;
-                                       });
-                               } else {
-                                       $lkeys = array('vDEF');
-                               }
-                               $html = array();
-                               foreach ($lkeys as $lkey) {
-                                       // Set up options for single element
-                                       $fakeParameterArray = array(
-                                               'fieldConf' => array(
-                                                       'label' => $languageService->sL(trim($flexFormFieldArray['label'])),
-                                                       'config' => $flexFormFieldArray['config'],
-                                                       'defaultExtras' => $flexFormFieldArray['defaultExtras'],
-                                                       'onChange' => $flexFormFieldArray['onChange'],
-                                               ),
-                                       );
-
-                                       $alertMsgOnChange = '';
-                                       if (
-                                               $fakeParameterArray['fieldConf']['onChange'] === 'reload'
-                                               || !empty($GLOBALS['TCA'][$table]['ctrl']['type']) && $GLOBALS['TCA'][$table]['ctrl']['type'] === $flexFormFieldName
-                                               || !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate']) && GeneralUtility::inList($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'], $flexFormFieldName)
-                                       ) {
-                                               if ($this->getBackendUserAuthentication()->jsConfirmation(JsConfirmation::TYPE_CHANGE)) {
-                                                       $alertMsgOnChange = 'top.TYPO3.Modal.confirm(TBE_EDITOR.labels.refreshRequired.title, TBE_EDITOR.labels.refreshRequired.content).on("button.clicked", function(e) { if (e.target.name == "ok" && TBE_EDITOR.checkSubmit(-1)) { TBE_EDITOR.submitForm() } top.TYPO3.Modal.dismiss(); });';
-                                               } else {
-                                                       $alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm();}';
-                                               }
-                                       }
-                                       $fakeParameterArray['fieldChangeFunc'] = $parameterArray['fieldChangeFunc'];
-                                       if ($alertMsgOnChange) {
-                                               $fakeParameterArray['fieldChangeFunc']['alert'] = $alertMsgOnChange;
-                                       }
-
-                                       $fakeParameterArray['onFocus'] = $parameterArray['onFocus'];
-                                       $fakeParameterArray['label'] = $parameterArray['label'];
-                                       $fakeParameterArray['itemFormElName'] = $parameterArray['itemFormElName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $lkey . ']';
-                                       $fakeParameterArray['itemFormElID'] = $fakeParameterArray['itemFormElName'];
-                                       if (isset($flexFormRowData[$flexFormFieldName][$lkey])) {
-                                               $fakeParameterArray['itemFormElValue'] = $flexFormRowData[$flexFormFieldName][$lkey];
+                               // Set up options for single element
+                               $fakeParameterArray = [
+                                       'fieldConf' => [
+                                               'label' => $languageService->sL(trim($flexFormFieldArray['label'])),
+                                               'config' => $flexFormFieldArray['config'],
+                                               'defaultExtras' => $flexFormFieldArray['defaultExtras'],
+                                               'onChange' => $flexFormFieldArray['onChange'],
+                                       ],
+                                       'fieldChangeFunc' => $parameterArray['fieldChangeFunc'],
+                                       'onFocus' => $parameterArray['onFocus'],
+                                       'label' => $parameterArray['label'],
+                               ];
+
+                               $alertMsgOnChange = '';
+                               if (
+                                       $fakeParameterArray['fieldConf']['onChange'] === 'reload'
+                                       || !empty($GLOBALS['TCA'][$table]['ctrl']['type']) && $GLOBALS['TCA'][$table]['ctrl']['type'] === $flexFormFieldName
+                                       || !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate']) && GeneralUtility::inList($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'], $flexFormFieldName)
+                               ) {
+                                       if ($this->getBackendUserAuthentication()->jsConfirmation(JsConfirmation::TYPE_CHANGE)) {
+                                               $alertMsgOnChange = 'top.TYPO3.Modal.confirm(TBE_EDITOR.labels.refreshRequired.title, TBE_EDITOR.labels.refreshRequired.content).on("button.clicked", function(e) { if (e.target.name == "ok" && TBE_EDITOR.checkSubmit(-1)) { TBE_EDITOR.submitForm() } top.TYPO3.Modal.dismiss(); });';
                                        } else {
-                                               $fakeParameterArray['itemFormElValue'] = $fakeParameterArray['fieldConf']['config']['default'];
+                                               $alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm();}';
                                        }
+                               }
+                               if ($alertMsgOnChange) {
+                                       $fakeParameterArray['fieldChangeFunc']['alert'] = $alertMsgOnChange;
+                               }
 
-                                       $options = $this->data;
-                                       $options['parameterArray'] = $fakeParameterArray;
-                                       $options['elementBaseName'] = $this->data['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $lkey . ']';
-
-                                       if (!empty($flexFormFieldArray['config']['renderType'])) {
-                                               $options['renderType'] = $flexFormFieldArray['config']['renderType'];
-                                       } else {
-                                               // Fallback to type if no renderType is given
-                                               $options['renderType'] = $flexFormFieldArray['config']['type'];
-                                       }
-                                       $childResult = $this->nodeFactory->create($options)->render();
-
-                                       $theTitle = htmlspecialchars($fakeParameterArray['fieldConf']['label']);
-                                       $defInfo = array();
-
-                                       // Possible line breaks in the label through xml: \n => <br/>, usage of nl2br() not possible, so it's done through str_replace (?!)
-                                       $processedTitle = str_replace('\\n', '<br />', $theTitle);
-                                       // @todo: Similar to the processing within SingleElementContainer ... use it from there?!
-                                       $html[] = '<div class="form-group t3js-formengine-palette-field t3js-formengine-validation-marker">';
-                                       $html[] = '<label class="t3js-formengine-label">';
-                                       if (is_array($metaData) && isset($metaData['langChildren']) && $metaData['langChildren']) {
-                                               // Find language uid of this iso code
-                                               $languageUid = 0;
-                                               $lKeyWithoutV = substr($lkey, 1);
-                                               if ($lKeyWithoutV !== 'DEF') {
-                                                       foreach ($this->data['systemLanguageRows'] as $systemLanguageRow) {
-                                                               if ($systemLanguageRow['iso'] === $lKeyWithoutV) {
-                                                                       $languageUid = $systemLanguageRow['uid'];
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                               $languageIcon = $iconFactory->getIcon($this->data['systemLanguageRows'][$languageUid]['flagIconIdentifier'], Icon::SIZE_SMALL)->render();
-                                               $html[] = $languageIcon;
-                                       }
-                                       $html[] = BackendUtility::wrapInHelp($parameterArray['_cshKey'], $flexFormFieldName, $processedTitle);
-                                       $html[] = '</label>';
-                                       $html[] = '<div class="t3js-formengine-field-item">';
-                                       $html[] = $childResult['html'];
-                                       $html[] = implode(LF, $defInfo);
-                                       $html[] = $this->renderVDEFDiff($flexFormRowData[$flexFormFieldName], $lkey);
-                                       $html[] = '</div>';
-                                       $html[] = '</div>';
+                               $fakeParameterArray['itemFormElName'] = $parameterArray['itemFormElName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][vDEF]';
+                               $fakeParameterArray['itemFormElID'] = $fakeParameterArray['itemFormElName'];
+                               if (isset($flexFormRowData[$flexFormFieldName]['vDEF'])) {
+                                       $fakeParameterArray['itemFormElValue'] = $flexFormRowData[$flexFormFieldName]['vDEF'];
+                               } else {
+                                       $fakeParameterArray['itemFormElValue'] = $fakeParameterArray['fieldConf']['config']['default'];
                                }
 
-                               if (!empty($html)) {
-                                       $resultArray['html'] .= '<div class="form-section">' . implode(LF, $html) . '</div>';
+                               $options = $this->data;
+                               $options['parameterArray'] = $fakeParameterArray;
+                               $options['elementBaseName'] = $this->data['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][vDEF]';
+
+                               if (!empty($flexFormFieldArray['config']['renderType'])) {
+                                       $options['renderType'] = $flexFormFieldArray['config']['renderType'];
+                               } else {
+                                       // Fallback to type if no renderType is given
+                                       $options['renderType'] = $flexFormFieldArray['config']['type'];
                                }
+                               $childResult = $this->nodeFactory->create($options)->render();
+
+                               // Possible line breaks in the label through xml: \n => <br/>, usage of nl2br() not possible, so it's done through str_replace (?!)
+                               $processedTitle = str_replace('\\n', '<br />', htmlspecialchars($fakeParameterArray['fieldConf']['label']));
+                               $html = [];
+                               $html[] = '<div class="form-section">';
+                               $html[] =       '<div class="form-group t3js-formengine-palette-field t3js-formengine-validation-marker">';
+                               $html[] =               '<label class="t3js-formengine-label">';
+                               $html[] =                       BackendUtility::wrapInHelp($parameterArray['_cshKey'], $flexFormFieldName, $processedTitle);
+                               $html[] =               '</label>';
+                               $html[] =               '<div class="t3js-formengine-field-item">';
+                               $html[] =                       $childResult['html'];
+                               $html[] =               '</div>';
+                               $html[] =       '</div>';
+                               $html[] = '</div>';
+
+                               $resultArray['html'] .= implode(LF, $html);
                                $childResult['html'] = '';
                                $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childResult);
                        }
@@ -185,28 +147,6 @@ class FlexFormElementContainer extends AbstractContainer {
                return $resultArray;
        }
 
-       /**
-        * Renders the diff-view of vDEF fields in flex forms
-        *
-        * @param array $vArray Record array of the record being edited
-        * @param string $vDEFkey HTML of the form field. This is what we add the content to.
-        * @return string Item string returned again, possibly with the original value added to.
-        */
-       protected function renderVDEFDiff($vArray, $vDEFkey) {
-               $item = NULL;
-               if (
-                       $GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase'] && isset($vArray[$vDEFkey . '.vDEFbase'])
-                       && (string)$vArray[$vDEFkey . '.vDEFbase'] !== (string)$vArray['vDEF'][0]
-               ) {
-                       // Create diff-result:
-                       $diffUtility = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Utility\DiffUtility::class);
-                       $diffres = $diffUtility->makeDiffDisplay($vArray[$vDEFkey . '.vDEFbase'], $vArray['vDEF']);
-                       $item = '<div class="typo3-TCEforms-diffBox">' . '<div class="typo3-TCEforms-diffBox-header">'
-                               . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.changeInOrig')) . ':</div>' . $diffres . '</div>';
-               }
-               return $item;
-       }
-
        /**
         * @return LanguageService
         */
diff --git a/typo3/sysext/backend/Classes/Form/Container/FlexFormEntryContainer.php b/typo3/sysext/backend/Classes/Form/Container/FlexFormEntryContainer.php
new file mode 100644 (file)
index 0000000..e192754
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+namespace TYPO3\CMS\Backend\Form\Container;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Entry container to a flex form element. This container is created by
+ * SingleFieldContainer if a type='flex' field is rendered.
+ *
+ * It either forks a FlexFormTabsContainer or a FlexFormNoTabsContainer.
+ */
+class FlexFormEntryContainer extends AbstractContainer {
+
+       /**
+        * Entry method
+        *
+        * @return array As defined in initializeResultArray() of AbstractNode
+        */
+       public function render() {
+               $flexFormDataStructureArray = $this->data['parameterArray']['fieldConf']['config']['ds'];
+
+               $options = $this->data;
+               $options['flexFormDataStructureArray'] = $flexFormDataStructureArray;
+               $options['flexFormRowData'] = $this->data['parameterArray']['itemFormElValue'];
+               $options['renderType'] = 'flexFormNoTabsContainer';
+
+               // Enable tabs if there is more than one sheet
+               if (count($flexFormDataStructureArray['sheets']) > 1) {
+                       $options['renderType'] = 'flexFormTabsContainer';
+               }
+
+               $resultArray = $this->nodeFactory->create($options)->render();
+               $resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/FormEngineFlexForm';
+
+               return $resultArray;
+       }
+
+}
diff --git a/typo3/sysext/backend/Classes/Form/Container/FlexFormLanguageContainer.php b/typo3/sysext/backend/Classes/Form/Container/FlexFormLanguageContainer.php
deleted file mode 100644 (file)
index 1160022..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Form\Container;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Imaging\IconFactory;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * Handle flex form language overlays.
- *
- * Entry container to a flex form element. This container is created by
- * SingleFieldContainer if a type='flexform' field is rendered.
- *
- * For each existing language overlay it forks a FlexFormTabsContainer or a
- * FlexFormNoTabsContainer for rendering a full flex form record of the specific language.
- */
-class FlexFormLanguageContainer extends AbstractContainer {
-
-       /**
-        * Entry method
-        *
-        * @return array As defined in initializeResultArray() of AbstractNode
-        */
-       public function render() {
-               $flexFormDataStructureArray = $this->data['parameterArray']['fieldConf']['config']['ds'];
-               $flexFormRowData = $this->data['parameterArray']['itemFormElValue'];
-
-               /** @var IconFactory $iconFactory */
-               $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
-
-               // Tabs or no tabs - that's the question
-               $hasTabs = FALSE;
-               if (count($flexFormDataStructureArray['sheets']) > 1) {
-                       $hasTabs = TRUE;
-               }
-
-               $resultArray = $this->initializeResultArray();
-
-               foreach ($flexFormDataStructureArray['meta']['languagesOnSheetLevel'] as $lKey) {
-                       // Add language as header
-                       if (!$flexFormDataStructureArray['meta']['langChildren'] && !$flexFormDataStructureArray['meta']['langDisable']) {
-                               // Find language uid of this iso code
-                               $languageUid = 0;
-                               if ($lKey !== 'DEF') {
-                                       foreach ($this->data['systemLanguageRows'] as $systemLanguageRow) {
-                                               if ($systemLanguageRow['iso'] === $lKey) {
-                                                       $languageUid = $systemLanguageRow['uid'];
-                                                       break;
-                                               }
-                                       }
-                               }
-                               $resultArray['html'] .= LF
-                                       . '<strong>'
-                                       . $iconFactory->getIcon($this->data['systemLanguageRows'][$languageUid]['flagIconIdentifier'], Icon::SIZE_SMALL)->render()
-                                       . htmlspecialchars($this->data['systemLanguageRows'][$languageUid]['title'])
-                                       . '</strong>';
-                       }
-
-                       // Default language "lDEF", other options are "lUK" or whatever country code
-                       $flexFormCurrentLanguage = 'l' . $lKey;
-
-                       $options = $this->data;
-                       $options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage;
-                       $options['flexFormDataStructureArray'] = $flexFormDataStructureArray;
-                       $options['flexFormRowData'] = $flexFormRowData;
-                       if (!$hasTabs) {
-                               $options['renderType'] = 'flexFormNoTabsContainer';
-                               $flexFormNoTabsResult = $this->nodeFactory->create($options)->render();
-                               $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormNoTabsResult);
-                       } else {
-                               $options['renderType'] = 'flexFormTabsContainer';
-                               $flexFormTabsContainerResult = $this->nodeFactory->create($options)->render();
-                               $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormTabsContainerResult);
-                       }
-               }
-               $resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/FormEngineFlexForm';
-
-               return $resultArray;
-       }
-
-}
index 27608a6..46aa94e 100644 (file)
@@ -19,7 +19,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 /**
  * Handle a flex form that has no tabs.
  *
- * This container is called by FlexFormLanguageContainer if only a default sheet
+ * This container is called by FlexFormEntryContainer if only a default sheet
  * exists. It evaluates the display condition and hands over rendering of single
  * fields to FlexFormElementContainer.
  */
@@ -36,14 +36,13 @@ class FlexFormNoTabsContainer extends AbstractContainer {
                $fieldName = $this->data['fieldName']; // field name of the flex form field in DB
                $parameterArray = $this->data['parameterArray'];
                $flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
-               $flexFormCurrentLanguage = $this->data['flexFormCurrentLanguage'];
                $flexFormRowData = $this->data['flexFormRowData'];
                $resultArray = $this->initializeResultArray();
 
                // Flex ds was normalized in flex provider to always have a sheet.
                // Determine this single sheet name, most often it ends up with sDEF, except if only one sheet was defined
                $sheetName = array_pop(array_keys($flexFormDataStructureArray['sheets']));
-               $flexFormRowDataSubPart = $flexFormRowData['data'][$sheetName][$flexFormCurrentLanguage];
+               $flexFormRowDataSubPart = $flexFormRowData['data'][$sheetName]['lDEF'] ?: [];
 
                // That was taken from GeneralUtility::resolveSheetDefInDS - no idea if it is important
                unset($flexFormDataStructureArray['meta']);
@@ -66,7 +65,7 @@ class FlexFormNoTabsContainer extends AbstractContainer {
                $options = $this->data;
                $options['flexFormDataStructureArray'] = $flexFormDataStructureArray['sheets'][$sheetName]['ROOT']['el'];
                $options['flexFormRowData'] = $flexFormRowDataSubPart;
-               $options['flexFormFormPrefix'] = '[data][' . $sheetName . '][' . $flexFormCurrentLanguage . ']';
+               $options['flexFormFormPrefix'] = '[data][' . $sheetName . '][lDEF]';
                $options['parameterArray'] = $parameterArray;
 
                $options['renderType'] = 'flexFormElementContainer';
index fc7fd12..84049d4 100644 (file)
@@ -21,7 +21,7 @@ use TYPO3\CMS\Lang\LanguageService;
 /**
  * Handle flex forms that have tabs (multiple "sheets").
  *
- * This container is called by FlexFormLanguageContainer. It resolves each
+ * This container is called by FlexFormEntryContainer. It resolves each
  * sheet and hands rendering of single sheet content over to FlexFormElementContainer.
  */
 class FlexFormTabsContainer extends AbstractContainer {
@@ -40,17 +40,16 @@ class FlexFormTabsContainer extends AbstractContainer {
                $fieldName = $this->data['fieldName']; // field name of the flex form field in DB
                $parameterArray = $this->data['parameterArray'];
                $flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
-               $flexFormCurrentLanguage = $this->data['flexFormCurrentLanguage'];
                $flexFormRowData = $this->data['flexFormRowData'];
 
-               $tabId = 'TCEFORMS:flexform:' . $this->data['parameterArray']['itemFormElName'] . $flexFormCurrentLanguage;
+               $tabId = 'TCEFORMS:flexform:' . $this->data['parameterArray']['itemFormElName'] . 'lDEF';
                $tabIdString = $docTemplate->getDynTabMenuId($tabId);
                $tabCounter = 0;
 
                $resultArray = $this->initializeResultArray();
                $tabsContent = array();
                foreach ($flexFormDataStructureArray['sheets'] as $sheetName => $sheetDataStructure) {
-                       $flexFormRowSheetDataSubPart = $flexFormRowData['data'][$sheetName][$flexFormCurrentLanguage];
+                       $flexFormRowSheetDataSubPart = $flexFormRowData['data'][$sheetName]['lDEF'] ?: [];
 
                        if (!is_array($sheetDataStructure['ROOT']['el'])) {
                                $resultArray['html'] .= LF . 'No Data Structure ERROR: No [\'ROOT\'][\'el\'] found for sheet "' . $sheetName . '".';
@@ -72,7 +71,7 @@ class FlexFormTabsContainer extends AbstractContainer {
                        $options = $this->data;
                        $options['flexFormDataStructureArray'] = $sheetDataStructure['ROOT']['el'];
                        $options['flexFormRowData'] = $flexFormRowSheetDataSubPart;
-                       $options['flexFormFormPrefix'] = '[data][' . $sheetName . '][' . $flexFormCurrentLanguage . ']';
+                       $options['flexFormFormPrefix'] = '[data][' . $sheetName . '][lDEF]';
                        $options['parameterArray'] = $parameterArray;
                        // Merge elements of this tab into a single list again and hand over to
                        // palette and single field container to render this group
index 7be1ab5..ce0ad1b 100644 (file)
@@ -30,7 +30,7 @@ use TYPO3\CMS\Core\Database\RelationHandler;
  * Container around a "single field".
  *
  * This container is the last one in the chain before processing is handed over to single element classes.
- * If a single field is of type flex or inline, it however creates FlexFormLanguageContainer or InlineControlContainer.
+ * If a single field is of type flex or inline, it however creates FlexFormEntryContainer or InlineControlContainer.
  *
  * The container does various checks and processing for a given single fields, for example it resolves
  * display conditions and the HTML to compare different languages.
index c4874e1..e02835d 100644 (file)
@@ -48,7 +48,6 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
                        $result = $this->modifyOuterDataStructure($result, $fieldName, $pageTsConfigOfFlex);
                        $result = $this->removeExcludeFieldsFromDataStructure($result, $fieldName, $flexIdentifier);
                        $result = $this->removeDisabledFieldsFromDataStructure($result, $fieldName, $pageTsConfigOfFlex);
-                       $result = $this->prepareLanguageHandlingInDataValues($result, $fieldName);
                        $result = $this->modifyDataStructureAndDataValuesByFlexFormSegmentGroup($result, $fieldName, $pageTsConfigOfFlex);
                }
 
@@ -126,13 +125,6 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
        protected function modifyOuterDataStructure(array $result, $fieldName, $pageTsConfig) {
                $modifiedDataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
 
-               if (isset($pageTsConfig['langDisable'])) {
-                       $modifiedDataStructure['meta']['langDisable'] = $pageTsConfig['langDisable'];
-               }
-               if (isset($pageTsConfig['langChildren'])) {
-                       $modifiedDataStructure['meta']['langChildren'] = $pageTsConfig['langChildren'];
-               }
-
                if (isset($modifiedDataStructure['sheets']) && is_array($modifiedDataStructure['sheets'])) {
                        // Handling multiple sheets
                        foreach ($modifiedDataStructure['sheets'] as $sheetName => $sheetStructure) {
@@ -151,13 +143,6 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
                        }
                }
 
-               $modifiedDataStructure['meta']['langDisable'] = isset($modifiedDataStructure['meta']['langDisable'])
-                       ? (bool)$modifiedDataStructure['meta']['langDisable']
-                       : FALSE;
-               $modifiedDataStructure['meta']['langChildren'] = isset($modifiedDataStructure['meta']['langChildren'])
-                       ? (bool)$modifiedDataStructure['meta']['langChildren']
-                       : FALSE;
-
                $result['processedTca']['columns'][$fieldName]['config']['ds'] = $modifiedDataStructure;
 
                return $result;
@@ -205,8 +190,7 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
        }
 
        /**
-        * Handle "outer" flex data structure changes like language and sheet
-        * description. Does not change "TCA" or values of single elements
+        * Remove fields from data structure that are disabled in pageTsConfig.
         *
         * @param array $result Result array
         * @param string $fieldName Current handle field name
@@ -229,104 +213,6 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
                                }
                        }
                }
-
-               return $result;
-       }
-
-       /**
-        * Remove data values in languages the user has no access to and add dummy entries
-        * for languages that are available but do not exist in data values yet.
-        *
-        * @param array $result Result array
-        * @param string $fieldName Current handle field name
-        * @return array Modified item array
-        */
-       protected function prepareLanguageHandlingInDataValues(array $result, $fieldName) {
-               $backendUser = $this->getBackendUser();
-               $dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
-
-               $langDisabled = $dataStructure['meta']['langDisable'];
-               $langChildren = $dataStructure['meta']['langChildren'];
-
-               // Existing page language overlays are only considered if options.checkPageLanguageOverlay is set in userTs
-               $checkPageLanguageOverlay = FALSE;
-               if (isset($result['userTsConfig']['options.']) && is_array($result['userTsConfig']['options.'])
-                       && array_key_exists('checkPageLanguageOverlay', $result['userTsConfig']['options.'])
-               ) {
-                       $checkPageLanguageOverlay = (bool)$result['userTsConfig']['options.']['checkPageLanguageOverlay'];
-               }
-
-               $systemLanguageRows = $result['systemLanguageRows'];
-
-               // Contains all language iso code that are valid and user has access to
-               $availableLanguageCodes = [];
-               $defaultCodeWasAdded = FALSE;
-               foreach ($systemLanguageRows as $systemLanguageRow) {
-                       $isoCode = $systemLanguageRow['iso'];
-                       $isAvailable = TRUE;
-                       if ($langDisabled && $isoCode !== 'DEF') {
-                               $isAvailable = FALSE;
-                       }
-                       // @todo: Is it possible a user has no write access to default lang? If so, what to do?
-                       if (!$backendUser->checkLanguageAccess($systemLanguageRow['uid'])) {
-                               $isAvailable = FALSE;
-                       }
-                       if ($checkPageLanguageOverlay && $systemLanguageRow['uid'] > 0) {
-                               $found = FALSE;
-                               foreach ($result['pageLanguageOverlayRows'] as $overlayRow) {
-                                       if ((int)$overlayRow['sys_language_uid'] === (int)$systemLanguageRow['uid']) {
-                                               $found = TRUE;
-                                               break;
-                                       }
-                               }
-                               if (!$found) {
-                                       $isAvailable = FALSE;
-                               }
-                       }
-                       if ($isoCode === 'DEF' && $defaultCodeWasAdded) {
-                               $isAvailable = FALSE;
-                       }
-                       if ($isAvailable) {
-                               $availableLanguageCodes[] = $isoCode;
-                       }
-                       if ($isoCode === 'DEF') {
-                               $defaultCodeWasAdded = TRUE;
-                       }
-               }
-               // Set the list of available languages in the data structure "meta" section to have it
-               // available for the render engine to iterate over it.
-               $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['availableLanguageCodes'] = $availableLanguageCodes;
-
-               if (!$langChildren) {
-                       $allowedLanguageSheetKeys = [];
-                       foreach ($availableLanguageCodes as $isoCode) {
-                               $allowedLanguageSheetKeys['l' . $isoCode] = [];
-                       }
-                       $result = $this->setLanguageSheetsInDataValues($result, $fieldName, $allowedLanguageSheetKeys);
-
-                       // With $langChildren = 0, values must only contain vDEF prefixed keys
-                       $allowedValueLevelLanguageKeys = [];
-                       $allowedValueLevelLanguageKeys['vDEF'] = [];
-                       $allowedValueLevelLanguageKeys['vDEF.vDEFbase'] = [];
-                       // A richtext special
-                       $allowedValueLevelLanguageKeys['_TRANSFORM_vDEF.vDEFbase'] = [];
-                       $result = $this->setLanguageValueLevelValues($result, $fieldName, $allowedValueLevelLanguageKeys);
-               } else {
-                       // langChildren is set - only lDEF as sheet language is allowed, but more fields on value field level
-                       $allowedLanguageSheetKeys = [
-                               'lDEF' => [],
-                       ];
-                       $result = $this->setLanguageSheetsInDataValues($result, $fieldName, $allowedLanguageSheetKeys);
-
-                       $allowedValueLevelLanguageKeys = [];
-                       foreach ($availableLanguageCodes as $isoCode) {
-                               $allowedValueLevelLanguageKeys['v' . $isoCode] = [];
-                               $allowedValueLevelLanguageKeys['v' . $isoCode . '.vDEFbase'] = [];
-                               $allowedValueLevelLanguageKeys['_TRANSFORM_v' . $isoCode . '.vDEFbase'] = [];
-                       }
-                       $result = $this->setLanguageValueLevelValues($result, $fieldName, $allowedValueLevelLanguageKeys);
-               }
-
                return $result;
        }
 
@@ -349,18 +235,6 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
                $dataValues = $result['databaseRow'][$fieldName];
                $tableName = $result['tableName'];
 
-               $availableLanguageCodes = $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['availableLanguageCodes'];
-               if ($dataStructure['meta']['langChildren']) {
-                       $languagesOnSheetLevel = [ 'DEF' ];
-                       $languagesOnElementLevel = $availableLanguageCodes;
-               } else {
-                       $languagesOnSheetLevel = $availableLanguageCodes;
-                       $languagesOnElementLevel = [ 'DEF' ];
-               }
-
-               $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['languagesOnSheetLevel'] = $languagesOnSheetLevel;
-               $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['languagesOnElement'] = $languagesOnElementLevel;
-
                if (!isset($dataStructure['sheets']) || !is_array($dataStructure['sheets'])) {
                        return $result;
                }
@@ -382,194 +256,182 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
                                $pageTsConfigMerged['TCEFORM.'][$tableName . '.'] = $pageTsConfig[$dataStructureSheetName . '.'];
                        }
 
-                       foreach ($languagesOnSheetLevel as $isoSheetLevel) {
-                               $langSheetLevel = 'l' . $isoSheetLevel;
-                               foreach ($dataStructureSheetElements as $dataStructureSheetElementName => $dataStructureSheetElementDefinition) {
-                                       if (isset($dataStructureSheetElementDefinition['type']) && $dataStructureSheetElementDefinition['type'] === 'array'
-                                               && isset($dataStructureSheetElementDefinition['section']) && $dataStructureSheetElementDefinition['section'] === '1'
+                       foreach ($dataStructureSheetElements as $dataStructureSheetElementName => $dataStructureSheetElementDefinition) {
+                               if (isset($dataStructureSheetElementDefinition['type']) && $dataStructureSheetElementDefinition['type'] === 'array'
+                                       && isset($dataStructureSheetElementDefinition['section']) && $dataStructureSheetElementDefinition['section'] === '1'
+                               ) {
+                                       // A section
+
+                                       // Existing section container elements
+                                       if (isset($dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['el'])
+                                               && is_array($dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['el'])
                                        ) {
-                                               // A section
-
-                                               // Existing section container elements
-                                               if (isset($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'])
-                                                       && is_array($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'])
-                                               ) {
-                                                       $containerArray = $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'];
-                                                       foreach ($containerArray as $aContainerNumber => $aContainerArray) {
-                                                               if (is_array($aContainerArray)) {
-                                                                       foreach ($aContainerArray as $aContainerName => $aContainerElementArray) {
-                                                                               if ($aContainerName === '_TOGGLE') {
-                                                                                       // Don't handle internal toggle state field
-                                                                                       continue;
-                                                                               }
-                                                                               if (!isset($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName])) {
-                                                                                       // Container not defined in ds
-                                                                                       continue;
+                                               $containerArray = $dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['el'];
+                                               foreach ($containerArray as $aContainerNumber => $aContainerArray) {
+                                                       if (is_array($aContainerArray)) {
+                                                               foreach ($aContainerArray as $aContainerName => $aContainerElementArray) {
+                                                                       if ($aContainerName === '_TOGGLE') {
+                                                                               // Don't handle internal toggle state field
+                                                                               continue;
+                                                                       }
+                                                                       if (!isset($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName])) {
+                                                                               // Container not defined in ds
+                                                                               continue;
+                                                                       }
+                                                                       foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName]['el'] as $singleFieldName => $singleFieldConfiguration) {
+                                                                               // $singleFieldValueArray = ['data']['sSections']['lDEF']['section_1']['el']['1']['container_1']['el']['element_1']
+                                                                               $singleFieldValueArray = [];
+                                                                               if (isset($aContainerElementArray['el'][$singleFieldName])
+                                                                                       && is_array($aContainerElementArray['el'][$singleFieldName])
+                                                                               ) {
+                                                                                       $singleFieldValueArray = $aContainerElementArray['el'][$singleFieldName];
                                                                                }
-                                                                               foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName]['el'] as $singleFieldName => $singleFieldConfiguration) {
-                                                                                       // $singleFieldValueArray = ['data']['sSections']['lDEF']['section_1']['el']['1']['container_1']['el']['element_1']
-                                                                                       $singleFieldValueArray = [];
-                                                                                       if (isset($aContainerElementArray['el'][$singleFieldName])
-                                                                                               && is_array($aContainerElementArray['el'][$singleFieldName])
-                                                                                       ) {
-                                                                                               $singleFieldValueArray = $aContainerElementArray['el'][$singleFieldName];
-                                                                                       }
-                                                                                       foreach ($languagesOnElementLevel as $isoElementLevel) {
-                                                                                               $langElementLevel = 'v' . $isoElementLevel;
-                                                                                               $valueArray = [
-                                                                                                       'uid' => $result['databaseRow']['uid'],
-                                                                                               ];
-                                                                                               $command = 'new';
-                                                                                               if (array_key_exists($langElementLevel, $singleFieldValueArray)) {
-                                                                                                       $command = 'edit';
-                                                                                                       $valueArray[$singleFieldName] = $singleFieldValueArray[$langElementLevel];
-                                                                                               }
-                                                                                               $inputToFlexFormSegment = [
-                                                                                                       'tableName' => $result['tableName'],
-                                                                                                       'command' => $command,
-                                                                                                       // It is currently not possible to have pageTsConfig for section container
-                                                                                                       'pageTsConfigMerged' => [],
-                                                                                                       'databaseRow' => $valueArray,
-                                                                                                       'vanillaTableTca' => [
-                                                                                                               'ctrl' => [],
-                                                                                                               'columns' => [
-                                                                                                                       $singleFieldName => $singleFieldConfiguration,
-                                                                                                               ],
-                                                                                                       ],
-                                                                                                       'processedTca' => [
-                                                                                                               'ctrl' => [],
-                                                                                                               'columns' => [
-                                                                                                                       $singleFieldName => $singleFieldConfiguration,
-                                                                                                               ],
-                                                                                                       ],
-                                                                                               ];
-                                                                                               $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
-                                                                                               // Set data value result
-                                                                                               if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
-                                                                                                       $result['databaseRow'][$fieldName]
-                                                                                                       ['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el']
-                                                                                                       [$aContainerNumber][$aContainerName]['el']
-                                                                                                       [$singleFieldName][$langElementLevel]
-                                                                                                               = $flexSegmentResult['databaseRow'][$singleFieldName];
-                                                                                               }
-                                                                                               // Set TCA structure result, actually, this call *might* be obsolete since the "dummy"
-                                                                                               // handling below will set it again.
-                                                                                               $result['processedTca']['columns'][$fieldName]['config']['ds']
-                                                                                               ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
-                                                                                               [$aContainerName]['el'][$singleFieldName]
-                                                                                                       = $flexSegmentResult['processedTca']['columns'][$singleFieldName];
-                                                                                       }
+                                                                               $valueArray = [
+                                                                                       'uid' => $result['databaseRow']['uid'],
+                                                                               ];
+                                                                               $command = 'new';
+                                                                               if (array_key_exists('vDEF', $singleFieldValueArray)) {
+                                                                                       $command = 'edit';
+                                                                                       $valueArray[$singleFieldName] = $singleFieldValueArray['vDEF'];
                                                                                }
-                                                                       }
-                                                               }
-                                                       }
-                                               } // End of existing data value handling
-
-                                               // Prepare "fresh" row for every possible container
-                                               if (isset($dataStructureSheetElements[$dataStructureSheetElementName]['el']) && is_array($dataStructureSheetElements[$dataStructureSheetElementName]['el'])) {
-                                                       foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'] as $possibleContainerName => $possibleContainerConfiguration) {
-                                                               if (isset($possibleContainerConfiguration['el']) && is_array($possibleContainerConfiguration['el'])) {
-                                                                       // Initialize result data array templateRows
-                                                                       $result['databaseRow'][$fieldName]
-                                                                       ['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['templateRows']
-                                                                       [$possibleContainerName]['el']
-                                                                               = [];
-                                                                       foreach ($possibleContainerConfiguration['el'] as $singleFieldName => $singleFieldConfiguration) {
-                                                                               foreach ($languagesOnElementLevel as $isoElementLevel) {
-                                                                                       $langElementLevel = 'v' . $isoElementLevel;
-                                                                                       $inputToFlexFormSegment = [
-                                                                                               'tableName' => $result['tableName'],
-                                                                                               'command' => 'new',
-                                                                                               'pageTsConfigMerged' => [],
-                                                                                               'databaseRow' => [
-                                                                                                       'uid' => $result['databaseRow']['uid'],
+                                                                               $inputToFlexFormSegment = [
+                                                                                       'tableName' => $result['tableName'],
+                                                                                       'command' => $command,
+                                                                                       // It is currently not possible to have pageTsConfig for section container
+                                                                                       'pageTsConfigMerged' => [],
+                                                                                       'databaseRow' => $valueArray,
+                                                                                       'vanillaTableTca' => [
+                                                                                               'ctrl' => [],
+                                                                                               'columns' => [
+                                                                                                       $singleFieldName => $singleFieldConfiguration,
                                                                                                ],
-                                                                                               'vanillaTableTca' => [
-                                                                                                       'ctrl' => [],
-                                                                                                       'columns' => [
-                                                                                                               $singleFieldName => $singleFieldConfiguration,
-                                                                                                       ],
+                                                                                       ],
+                                                                                       'processedTca' => [
+                                                                                               'ctrl' => [],
+                                                                                               'columns' => [
+                                                                                                       $singleFieldName => $singleFieldConfiguration,
                                                                                                ],
-                                                                                               'processedTca' => [
-                                                                                                       'ctrl' => [],
-                                                                                                       'columns' => [
-                                                                                                               $singleFieldName => $singleFieldConfiguration,
-                                                                                                       ],
-                                                                                               ],
-                                                                                       ];
-                                                                                       $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
-                                                                                       if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
-                                                                                               $result['databaseRow'][$fieldName]
-                                                                                               ['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['templateRows']
-                                                                                               [$possibleContainerName]['el'][$singleFieldName][$langElementLevel]
-                                                                                                = $flexSegmentResult['databaseRow'][$singleFieldName];
-                                                                                       }
-                                                                                       $result['processedTca']['columns'][$fieldName]['config']['ds']
-                                                                                       ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
-                                                                                       [$possibleContainerName]['el'][$singleFieldName]
-                                                                                               = $flexSegmentResult['processedTca']['columns'][$singleFieldName];
+                                                                                       ],
+                                                                               ];
+                                                                               $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
+                                                                               // Set data value result
+                                                                               if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
+                                                                                       $result['databaseRow'][$fieldName]
+                                                                                       ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['el']
+                                                                                       [$aContainerNumber][$aContainerName]['el']
+                                                                                       [$singleFieldName]['vDEF']
+                                                                                               = $flexSegmentResult['databaseRow'][$singleFieldName];
                                                                                }
+                                                                               // Set TCA structure result, actually, this call *might* be obsolete since the "dummy"
+                                                                               // handling below will set it again.
+                                                                               $result['processedTca']['columns'][$fieldName]['config']['ds']
+                                                                               ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
+                                                                               [$aContainerName]['el'][$singleFieldName]
+                                                                                       = $flexSegmentResult['processedTca']['columns'][$singleFieldName];
                                                                        }
                                                                }
                                                        }
-                                               } // End of preparation for each possible container
-
-                                       // type without section is not ok
-                                       } elseif (isset($dataStructureSheetElementDefinition['type']) || isset($dataStructureSheetElementDefinition['section'])) {
-                                               throw new \UnexpectedValueException(
-                                                       'Broken data structure on field name ' . $fieldName . '. section without type or vice versa is not allowed',
-                                                       1440685208
-                                               );
-
-                                       // A "normal" TCA element
-                                       } else {
-                                               foreach ($languagesOnElementLevel as $isoElementLevel) {
-                                                       $langElementLevel = 'v' . $isoElementLevel;
-                                                       $valueArray = [
-                                                               // uid of "parent" is given down for inline elements to resolve correctly
-                                                               'uid' => $result['databaseRow']['uid'],
-                                                       ];
-                                                       $command = 'new';
-                                                       if (isset($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName])
-                                                               && array_key_exists($langElementLevel, $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName])
-                                                       ) {
-                                                               $command = 'edit';
-                                                               $valueArray[$dataStructureSheetElementName] = $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName][$langElementLevel];
-                                                       }
-                                                       $inputToFlexFormSegment = [
-                                                               // tablename of "parent" is given down for inline elements to resolve correctly
-                                                               'tableName' => $result['tableName'],
-                                                               'command' => $command,
-                                                               'pageTsConfigMerged' => $pageTsConfigMerged,
-                                                               'databaseRow' => $valueArray,
-                                                               'vanillaTableTca' => [
-                                                                       'ctrl' => [],
-                                                                       'columns' => [
-                                                                               $dataStructureSheetElementName => $dataStructureSheetElementDefinition,
-                                                                       ],
-                                                               ],
-                                                               'processedTca' => [
-                                                                       'ctrl' => [],
-                                                                       'columns' => [
-                                                                               $dataStructureSheetElementName => $dataStructureSheetElementDefinition,
-                                                                       ],
-                                                               ],
-                                                       ];
-                                                       $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
-                                                       // Set data value result
-                                                       if (array_key_exists($dataStructureSheetElementName, $flexSegmentResult['databaseRow'])) {
+                                               }
+                                       } // End of existing data value handling
+
+                                       // Prepare "fresh" row for every possible container
+                                       if (isset($dataStructureSheetElements[$dataStructureSheetElementName]['el']) && is_array($dataStructureSheetElements[$dataStructureSheetElementName]['el'])) {
+                                               foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'] as $possibleContainerName => $possibleContainerConfiguration) {
+                                                       if (isset($possibleContainerConfiguration['el']) && is_array($possibleContainerConfiguration['el'])) {
+                                                               // Initialize result data array templateRows
                                                                $result['databaseRow'][$fieldName]
-                                                               ['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName][$langElementLevel]
-                                                                       = $flexSegmentResult['databaseRow'][$dataStructureSheetElementName];
+                                                               ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['templateRows']
+                                                               [$possibleContainerName]['el']
+                                                                       = [];
+                                                               foreach ($possibleContainerConfiguration['el'] as $singleFieldName => $singleFieldConfiguration) {
+                                                                       $inputToFlexFormSegment = [
+                                                                               'tableName' => $result['tableName'],
+                                                                               'command' => 'new',
+                                                                               'pageTsConfigMerged' => [],
+                                                                               'databaseRow' => [
+                                                                                       'uid' => $result['databaseRow']['uid'],
+                                                                               ],
+                                                                               'vanillaTableTca' => [
+                                                                                       'ctrl' => [],
+                                                                                       'columns' => [
+                                                                                               $singleFieldName => $singleFieldConfiguration,
+                                                                                       ],
+                                                                               ],
+                                                                               'processedTca' => [
+                                                                                       'ctrl' => [],
+                                                                                       'columns' => [
+                                                                                               $singleFieldName => $singleFieldConfiguration,
+                                                                                       ],
+                                                                               ],
+                                                                       ];
+                                                                       $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
+                                                                       if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
+                                                                               $result['databaseRow'][$fieldName]
+                                                                               ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['templateRows']
+                                                                               [$possibleContainerName]['el'][$singleFieldName]['vDEF']
+                                                                                = $flexSegmentResult['databaseRow'][$singleFieldName];
+                                                                       }
+                                                                       $result['processedTca']['columns'][$fieldName]['config']['ds']
+                                                                       ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
+                                                                       [$possibleContainerName]['el'][$singleFieldName]
+                                                                               = $flexSegmentResult['processedTca']['columns'][$singleFieldName];
+                                                               }
                                                        }
-                                                       // Set TCA structure result
-                                                       $result['processedTca']['columns'][$fieldName]['config']['ds']
-                                                       ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]
-                                                               = $flexSegmentResult['processedTca']['columns'][$dataStructureSheetElementName];
                                                }
-                                       } // End of single element handling
+                                       } // End of preparation for each possible container
+
+                               // type without section is not ok
+                               } elseif (isset($dataStructureSheetElementDefinition['type']) || isset($dataStructureSheetElementDefinition['section'])) {
+                                       throw new \UnexpectedValueException(
+                                               'Broken data structure on field name ' . $fieldName . '. section without type or vice versa is not allowed',
+                                               1440685208
+                                       );
+
+                               // A "normal" TCA element
+                               } else {
+                                       $valueArray = [
+                                               // uid of "parent" is given down for inline elements to resolve correctly
+                                               'uid' => $result['databaseRow']['uid'],
+                                       ];
+                                       $command = 'new';
+                                       if (isset($dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName])
+                                               && array_key_exists('vDEF', $dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName])
+                                       ) {
+                                               $command = 'edit';
+                                               $valueArray[$dataStructureSheetElementName] = $dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['vDEF'];
+                                       }
+                                       $inputToFlexFormSegment = [
+                                               // tablename of "parent" is given down for inline elements to resolve correctly
+                                               'tableName' => $result['tableName'],
+                                               'command' => $command,
+                                               'pageTsConfigMerged' => $pageTsConfigMerged,
+                                               'databaseRow' => $valueArray,
+                                               'vanillaTableTca' => [
+                                                       'ctrl' => [],
+                                                       'columns' => [
+                                                               $dataStructureSheetElementName => $dataStructureSheetElementDefinition,
+                                                       ],
+                                               ],
+                                               'processedTca' => [
+                                                       'ctrl' => [],
+                                                       'columns' => [
+                                                               $dataStructureSheetElementName => $dataStructureSheetElementDefinition,
+                                                       ],
+                                               ],
+                                       ];
+                                       $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
+                                       // Set data value result
+                                       if (array_key_exists($dataStructureSheetElementName, $flexSegmentResult['databaseRow'])) {
+                                               $result['databaseRow'][$fieldName]
+                                               ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['vDEF']
+                                                       = $flexSegmentResult['databaseRow'][$dataStructureSheetElementName];
+                                       }
+                                       // Set TCA structure result
+                                       $result['processedTca']['columns'][$fieldName]['config']['ds']
+                                       ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]
+                                               = $flexSegmentResult['processedTca']['columns'][$dataStructureSheetElementName];
+                               } // End of single element handling
 
-                               }
                        }
                }
 
@@ -606,104 +468,6 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
                return $dataStructure;
        }
 
-       /**
-        * Add new sheet languages not yet in data values and remove invalid ones
-        *
-        * databaseRow['aFlex']['data']['sDEF'] = array('lDEF', 'lNotAllowed');
-        * allowedLanguageKeys = array('lDEF', 'lNEW')
-        * -> databaseRow['aFlex']['data']['sDEF'] = array('lDEF', 'lNEW');
-        *
-        * @param array $result Result array
-        * @param string $fieldName Current handle field name
-        * @param array $allowedKeys List of allowed keys
-        * @return array Modified result
-        */
-       protected function setLanguageSheetsInDataValues(array $result, $fieldName, array $allowedKeys) {
-               $valueArray = [];
-               if (isset($result['databaseRow'][$fieldName]['data']) && is_array($result['databaseRow'][$fieldName]['data'])) {
-                       $valueArray = $result['databaseRow'][$fieldName]['data'];
-               }
-               foreach ($valueArray as $sheetName => $sheetLanguages) {
-                       // Add iso code with empty array if it does not yet exist in data
-                       // and remove codes from data that do not exist in $allowed
-                       $result['databaseRow'][$fieldName]['data'][$sheetName]
-                               = array_intersect_key(array_merge($allowedKeys, $sheetLanguages), $allowedKeys);
-               }
-               return $result;
-       }
-
-       /**
-        * Remove invalid keys from data value array the user has no access to
-        * or that were removed or similar to prevent any rendering of this stuff
-        *
-        * Handles this for "normal" fields and also for section container element values.
-        *
-        * @param array $result Result array
-        * @param string $fieldName Current handle field name
-        * @param array $allowedKeys List of allowed keys
-        * @return array Modified result
-        */
-       protected function setLanguageValueLevelValues(array $result, $fieldName, $allowedKeys) {
-               $valueArray = [];
-               if (isset($result['databaseRow'][$fieldName]['data']) && is_array($result['databaseRow'][$fieldName]['data'])) {
-                       $valueArray = $result['databaseRow'][$fieldName]['data'];
-               }
-               foreach ($valueArray as $sheetName => $sheetLanguages) {
-                       if (!is_array($sheetLanguages)) {
-                               continue;
-                       }
-                       foreach ($sheetLanguages as $languageName => $languageFields) {
-                               if (!is_array($languageFields)) {
-                                       continue;
-                               }
-                               foreach ($languageFields as $flexFieldName => $fieldValues) {
-                                       if (!is_array($fieldValues)) {
-                                               continue;
-                                       }
-                                       $allowedSingleValues = [];
-                                       foreach ($fieldValues as $fieldValueName => $fieldValueValue) {
-                                               if (is_array($fieldValueValue) && $fieldValueName === 'el') {
-                                                       // A section container
-                                                       foreach ($fieldValueValue as $sectionNumber => $sectionElementArray) {
-                                                               if (is_array($sectionElementArray)) {
-                                                                       $allowedSingleValues['el'][$sectionNumber] = [];
-                                                                       foreach ($sectionElementArray as $sectionElementName => $containerElementArray) {
-                                                                               if (isset($containerElementArray['el']) && is_array($containerElementArray['el']) && !empty($containerElementArray['el'])) {
-                                                                                       foreach ($containerElementArray['el'] as $aContainerElementName => $aContainerElementValues) {
-                                                                                               if (is_array($aContainerElementValues)) {
-                                                                                                       foreach ($aContainerElementValues as $aContainerElementValueKey => $aContainerElementValueValue) {
-                                                                                                               if (array_key_exists($aContainerElementValueKey, $allowedKeys)) {
-                                                                                                                       $allowedSingleValues['el'][$sectionNumber][$sectionElementName]
-                                                                                                                       ['el'][$aContainerElementName][$aContainerElementValueKey] = $aContainerElementValueValue;
-                                                                                                               }
-                                                                                                       }
-                                                                                               } else {
-                                                                                                       $allowedSingleValues['el'][$sectionNumber][$sectionElementName]['el']
-                                                                                                       [$aContainerElementName] = $aContainerElementValues;
-                                                                                               }
-                                                                                       }
-                                                                               } else {
-                                                                                       $allowedSingleValues['el'][$sectionNumber][$sectionElementName] = $containerElementArray;
-                                                                               }
-                                                                       }
-                                                               } else {
-                                                                       $allowedSingleValues = $sectionElementArray;
-                                                               }
-                                                       }
-                                               } else {
-                                                       // "normal" value field
-                                                       if (array_key_exists($fieldValueName, $allowedKeys)) {
-                                                               $allowedSingleValues[$fieldValueName] = $fieldValueValue;
-                                                       }
-                                               }
-                                       }
-                                       $result['databaseRow'][$fieldName]['data'][$sheetName][$languageName][$flexFieldName] = $allowedSingleValues;
-                               }
-                       }
-               }
-               return $result;
-       }
-
        /**
         * @return BackendUserAuthentication
         */
index 28b1895..663bb83 100644 (file)
@@ -29,7 +29,7 @@ class NodeFactory {
         * @var array
         */
        protected $nodeTypes = array(
-               'flex' => Container\FlexFormLanguageContainer::class,
+               'flex' => Container\FlexFormEntryContainer::class,
                'flexFormContainerContainer' => Container\FlexFormContainerContainer::class,
                'flexFormElementContainer' => Container\FlexFormElementContainer::class,
                'flexFormNoTabsContainer' => Container\FlexFormNoTabsContainer::class,
index 6521377..2ec5a69 100644 (file)
@@ -17,11 +17,8 @@ namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;
 use Prophecy\Argument;
 use Prophecy\Prophecy\ObjectProphecy;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
-use TYPO3\CMS\Core\Cache\CacheManager;
-use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
 use TYPO3\CMS\Core\Tests\UnitTestCase;
 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexProcess;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Lang\LanguageService;
 
 /**
@@ -53,122 +50,6 @@ class TcaFlexProcessTest extends UnitTestCase {
                $this->subject = new TcaFlexProcess();
        }
 
-       /**
-        * @test
-        */
-       public function addDataOverwritesDataStructureLangDisableIfSetViaPageTsConfig() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => [
-                                                               'sheets' => [
-                                                                       'sDEF' => [
-                                                                               'ROOT' => [],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-                       'pageTsConfigMerged' => [
-                               'TCEFORM.' => [
-                                       'aTable.' => [
-                                               'aField.' => [
-                                                       'aFlex.' => [
-                                                               'langDisable' => 1,
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [],
-                       'langDisable' => TRUE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ],
-               ];
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataOverwritesDataStructureLangChildrenIfSetViaPageTsConfig() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => [
-                                                               'sheets' => [
-                                                                       'sDEF' => [
-                                                                               'ROOT' => [],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-                       'pageTsConfigMerged' => [
-                               'TCEFORM.' => [
-                                       'aTable.' => [
-                                               'aField.' => [
-                                                       'aFlex.' => [
-                                                               'langChildren' => FALSE,
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [],
-                       'langDisable' => FALSE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ]
-               ];
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
        /**
         * @test
         */
@@ -178,11 +59,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -227,15 +106,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [],
                ];
 
@@ -251,11 +121,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -300,15 +168,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [
                                'aSheet' => [
                                        'ROOT' => [
@@ -339,11 +198,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -388,15 +245,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [
                                'aSheet' => [
                                        'ROOT' => [
@@ -427,11 +275,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -476,15 +322,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [
                                'aSheet' => [
                                        'ROOT' => [
@@ -515,11 +352,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -564,15 +399,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [
                                'sDEF' => [
                                        'ROOT' => [
@@ -603,11 +429,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -644,15 +468,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [
                                'sDEF' => [
                                        'ROOT' => [
@@ -675,11 +490,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -716,15 +529,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [
                                'sDEF' => [
                                        'ROOT' => [
@@ -755,11 +559,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -796,15 +598,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [
                                'sDEF' => [
                                        'ROOT' => [
@@ -835,11 +628,9 @@ class TcaFlexProcessTest extends UnitTestCase {
                        'databaseRow' => [
                                'aField' => [
                                        'data' => [],
-                                       'meta' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -886,15 +677,6 @@ class TcaFlexProcessTest extends UnitTestCase {
 
                $expected = $input;
                $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
                        'sheets' => [
                                'sDEF' => [
                                        'ROOT' => [
@@ -911,86 +693,15 @@ class TcaFlexProcessTest extends UnitTestCase {
        /**
         * @test
         */
-       public function addDataCleansLanguageDisabledDataValues() {
+       public function addDataHandlesPageTsConfigSettingsOfSingleFlexField() {
                $input = [
                        'tableName' => 'aTable',
                        'databaseRow' => [
                                'aField' => [
-                                       'data' => [
-                                               'sDEF' => [
-                                                       'lDEF' => [
-                                                               'input_1' => [
-                                                                       'vDEF' => 'input1 text',
-                                                                       'vDEF.vDEFbase' => 'base',
-                                                                       '_TRANSFORM_vDEF.vDEFbase' => 'transform',
-                                                                       'vRemoveMe' => 'removeMe',
-                                                                       'vRemoveMe.vDEFbase' => 'removeMe',
-                                                                       '_TRANSFORM_vRemoveMe.vDEFbase' => 'removeMe',
-                                                               ],
-                                                               'section_1' => [
-                                                                       'el' => [
-                                                                               '1' => [
-                                                                                       'container_1' => [
-                                                                                               'el' => [
-                                                                                                       'input_2' => [
-                                                                                                               'vDEF' => 'input2 text',
-                                                                                                               'vRemoveMe' => 'removeMe',
-                                                                                                       ]
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                               'invalid1' => 'keepMe',
-                                                               'invalid2' => [
-                                                                       'el' => [
-                                                                               '1' => [
-                                                                                       'keepMe',
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                               'invalid3' => [
-                                                                       'el' => [
-                                                                               '1' => [
-                                                                                       'container_2' => 'keepMe',
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                               'invalid4' => [
-                                                                       'el' => [
-                                                                               '1' => [
-                                                                                       'container_2' => [
-                                                                                               'el' => 'keepMe',
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                               'invalid5' => [
-                                                                       'el' => [
-                                                                               '1' => [
-                                                                                       'container_2' => [
-                                                                                               'el' => [
-                                                                                                       'field' => 'keepMe',
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                                       'lRemoveMe' => [],
-                                               ],
-                                       ],
-                                       'meta' => [],
+                                       'data' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'title' => 'aLanguageTitle',
-                                       'iso' => 'DEF',
-                               ],
-                       ],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -998,10 +709,44 @@ class TcaFlexProcessTest extends UnitTestCase {
                                                        'type' => 'flex',
                                                        'ds_pointerField' => 'pointerField',
                                                        'ds' => [
-                                                               'meta' => [
-                                                                       'langDisable' => 1,
+                                                               'sheets' => [
+                                                                       'sDEF' => [
+                                                                               'ROOT' => [
+                                                                                       'type' => 'array',
+                                                                                       'el' => [
+                                                                                               'aFlexField' => [
+                                                                                                       'label' => 'aFlexFieldLabel',
+                                                                                                       'config' => [
+                                                                                                               'type' => 'radio',
+                                                                                                               'items' => [
+                                                                                                                       0 => [
+                                                                                                                               0 => 'aLabel',
+                                                                                                                               1 => 'aValue',
+                                                                                                                       ],
+                                                                                                               ],
+                                                                                                       ],
+                                                                                               ],
+                                                                                       ],
+                                                                               ],
+                                                                       ],
+                                                               ],
+                                                       ],
+                                               ],
+                                       ],
+                               ],
+                       ],
+                       'pageTsConfigMerged' => [
+                               'TCEFORM.' => [
+                                       'aTable.' => [
+                                               'aField.' => [
+                                                       'aFlex.' => [
+                                                               'sDEF.' => [
+                                                                       'aFlexField.' => [
+                                                                               'altLabels.' => [
+                                                                                       '0' => 'labelOverride',
+                                                                               ],
+                                                                       ],
                                                                ],
-                                                               'sheets' => [],
                                                        ],
                                                ],
                                        ],
@@ -1009,79 +754,58 @@ class TcaFlexProcessTest extends UnitTestCase {
                        ],
                ];
 
+               $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [
+                       \TYPO3\CMS\Backend\Form\FormDataProvider\TcaRadioItems::class => [],
+               ];
+
+               /** @var LanguageService|ObjectProphecy $languageService */
+               $languageService = $this->prophesize(LanguageService::class);
+               $GLOBALS['LANG'] = $languageService->reveal();
+               $languageService->sL(Argument::cetera())->willReturnArgument(0);
+
                $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('0')->shouldBeCalled()->willReturn(TRUE);
+               $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(TRUE);
 
                $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                       ],
-                       'langDisable' => TRUE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
+               $expected['processedTca']['columns']['aField']['config']['ds'] = [
+                       'sheets' => [
+                               'sDEF' => [
+                                       'ROOT' => [
+                                               'type' => 'array',
+                                               'el' => [
+                                                       'aFlexField' => [
+                                                               'label' => 'aFlexFieldLabel',
+                                                               'config' => [
+                                                                       'type' => 'radio',
+                                                                       'items' => [
+                                                                               0 => [
+                                                                                       0 => 'labelOverride',
+                                                                                       1 => 'aValue',
+                                                                               ],
+                                                                       ],
+                                                               ],
+                                                       ],
+                                               ],
+                                       ],
+                               ],
                        ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ]
                ];
 
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lRemoveMe']);
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lDEF']['input_1']['vRemoveMe']);
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lDEF']['input_1']['vRemoveMe.vDEFbase']);
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lDEF']['input_1']['_TRANSFORM_vRemoveMe.vDEFbase']);
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['el']['1']['container_1']['el']['input_2']['vRemoveMe']);
-
                $this->assertEquals($expected, $this->subject->addData($input));
        }
 
        /**
         * @test
         */
-       public function addDataRemovesDataValuesIfUserHasNoAccess() {
+       public function addDataSetsDefaultValueFromFlexTcaForField() {
                $input = [
                        'tableName' => 'aTable',
                        'databaseRow' => [
                                'aField' => [
-                                       'data' => [
-                                               'sDEF' => [
-                                                       'lDEF' => [
-                                                               'input_1' => [
-                                                                       'vDEF' => 'input1 text',
-                                                               ],
-                                                               'section_1' => [
-                                                                       'el' => [
-                                                                               '1' => [
-                                                                                       'container_1' => [
-                                                                                               'el' => [
-                                                                                                       'input_2' => [
-                                                                                                               'vDEF' => 'input2 text',
-                                                                                                               'vNoAccess' => 'removeMe',
-                                                                                                       ]
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                                       'lNoAccess' => [],
-                                               ],
-                                       ],
-                                       'meta' => [],
+                                       'data' => [],
                                ],
                                'pointerField' => 'aFlex',
                        ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'NoAccess',
-                               ],
-                       ],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -1089,720 +813,6 @@ class TcaFlexProcessTest extends UnitTestCase {
                                                        'type' => 'flex',
                                                        'ds_pointerField' => 'pointerField',
                                                        'ds' => [
-                                                               'meta' => [
-                                                                       'langDisable' => 0,
-                                                               ],
-                                                               'sheets' => [],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('0')->shouldBeCalled()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('1')->shouldBeCalled()->willReturn(FALSE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ]
-               ];
-
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lNoAccess']);
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['el']['1']['container_1']['el']['input_2']['vNoAccess']);
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataAddsNewLanguageDataValues() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [
-                                               'sDEF' => [
-                                                       'lDEF' => [
-                                                               'input_1' => [
-                                                                       'vDEF' => 'input1 text',
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'EN',
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => [
-                                                               'meta' => [
-                                                                       'langDisable' => 0,
-                                                               ],
-                                                               'sheets' => [],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('0')->shouldBeCalled()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('1')->shouldBeCalled()->willReturn(TRUE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ]
-               ];
-
-               $expected['databaseRow']['aField']['data']['sDEF']['lEN'] = [];
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataRemovesDataValuesIfPageOverlayCheckIsEnabled() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [
-                                               'sDEF' => [
-                                                       'lDEF' => [],
-                                                       'lEN' => [],
-                                                       'lNoOverlay' => [],
-                                               ],
-                                       ],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'EN',
-                               ],
-                               2 => [
-                                       'uid' => 2,
-                                       'iso' => 'NoOverlay',
-                               ],
-                       ],
-                       'userTsConfig' => [
-                               'options.' => [
-                                       'checkPageLanguageOverlay' => '1',
-                               ],
-                       ],
-                       'pageLanguageOverlayRows' => [
-                               0 => [
-                                       'uid' => 1,
-                                       'sys_language_uid' => 1,
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => [
-                                                               'meta' => [
-                                                                       'langDisable' => 0,
-                                                               ],
-                                                               'sheets' => [],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('0')->shouldBeCalled()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('1')->shouldBeCalled()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('2')->shouldBeCalled()->willReturn(TRUE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ]
-               ];
-
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lNoOverlay']);
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataRemovesLanguageDataValuesIfUserHasNoAccessWithLangChildren() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [
-                                               'sDEF' => [
-                                                       'lDEF' => [
-                                                               'input_1' => [
-                                                                       'vDEF' => 'input1 text',
-                                                                       'vNoAccess' => 'removeMe',
-                                                               ],
-                                                               'section_1' => [
-                                                                       'el' => [
-                                                                               '1' => [
-                                                                                       'container_1' => [
-                                                                                               'el' => [
-                                                                                                       'input_2' => [
-                                                                                                               'vDEF' => 'input2 text',
-                                                                                                               'vNoAccess' => 'removeMe',
-                                                                                                       ]
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                                       'lNoAccess' => [],
-                                               ],
-                                       ],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'NoAccess',
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => [
-                                                               'meta' => [
-                                                                       'langDisable' => 0,
-                                                                       'langChildren' => 1,
-                                                               ],
-                                                               'sheets' => [],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('0')->shouldBeCalled()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('1')->shouldBeCalled()->willReturn(FALSE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => TRUE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ]
-               ];
-
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lNoAccess']);
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lDEF']['input_1']['vNoAccess']);
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['el']['1']['container_1']['el']['input_2']['vNoAccess']);
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataRemovesDataValuesIfPageOverlayCheckIsEnabledWithLangChildren() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [
-                                               'sDEF' => [
-                                                       'lDEF' => [
-                                                               'input_1' => [
-                                                                       'vDEF' => 'input1 text',
-                                                                       'vEN' => 'input1 en text',
-                                                                       'vNoOverlay' => 'removeMe',
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'EN',
-                               ],
-                               2 => [
-                                       'uid' => 2,
-                                       'iso' => 'NoOverlay',
-                               ],
-                       ],
-                       'userTsConfig' => [
-                               'options.' => [
-                                       'checkPageLanguageOverlay' => '1',
-                               ],
-                       ],
-                       'pageLanguageOverlayRows' => [
-                               0 => [
-                                       'uid' => 1,
-                                       'sys_language_uid' => 1,
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => [
-                                                               'meta' => [
-                                                                       'langDisable' => 0,
-                                                                       'langChildren' => 1,
-                                                               ],
-                                                               'sheets' => [],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('0')->shouldBeCalled()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('1')->shouldBeCalled()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess('2')->shouldBeCalled()->willReturn(TRUE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => TRUE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ]
-               ];
-
-               unset($expected['databaseRow']['aField']['data']['sDEF']['lDEF']['input_1']['vNoOverlay']);
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataHandlesPageTsConfigSettingsOfSingleFlexField() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => [
-                                                               'meta' => [
-                                                                       'langDisable' => 0,
-                                                                       'langChildren' => 0,
-                                                               ],
-                                                               'sheets' => [
-                                                                       'sDEF' => [
-                                                                               'ROOT' => [
-                                                                                       'type' => 'array',
-                                                                                       'el' => [
-                                                                                               'aFlexField' => [
-                                                                                                       'label' => 'aFlexFieldLabel',
-                                                                                                       'config' => [
-                                                                                                               'type' => 'radio',
-                                                                                                               'items' => [
-                                                                                                                       0 => [
-                                                                                                                               0 => 'aLabel',
-                                                                                                                               1 => 'aValue',
-                                                                                                                       ],
-                                                                                                               ],
-                                                                                                       ],
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-                       'pageTsConfigMerged' => [
-                               'TCEFORM.' => [
-                                       'aTable.' => [
-                                               'aField.' => [
-                                                       'aFlex.' => [
-                                                               'sDEF.' => [
-                                                                       'aFlexField.' => [
-                                                                               'altLabels.' => [
-                                                                                       '0' => 'labelOverride',
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [
-                       \TYPO3\CMS\Backend\Form\FormDataProvider\TcaRadioItems::class => [],
-               ];
-
-               /** @var LanguageService|ObjectProphecy $languageService */
-               $languageService = $this->prophesize(LanguageService::class);
-               $GLOBALS['LANG'] = $languageService->reveal();
-               $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(TRUE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds'] = [
-                       'meta' => [
-                               'availableLanguageCodes' => [
-                                       0 => 'DEF',
-                               ],
-                               'langDisable' => FALSE,
-                               'langChildren' => FALSE,
-                               'languagesOnSheetLevel' => [
-                                       0 => 'DEF',
-                               ],
-                               'languagesOnElement' => [
-                                       0 => 'DEF',
-                               ]
-                       ],
-                       'sheets' => [
-                               'sDEF' => [
-                                       'ROOT' => [
-                                               'type' => 'array',
-                                               'el' => [
-                                                       'aFlexField' => [
-                                                               'label' => 'aFlexFieldLabel',
-                                                               'config' => [
-                                                                       'type' => 'radio',
-                                                                       'items' => [
-                                                                               0 => [
-                                                                                       0 => 'labelOverride',
-                                                                                       1 => 'aValue',
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataSetsDefaultValueFromFlexTcaForField() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => [
-                                                               'sheets' => [
-                                                                       'sDEF' => [
-                                                                               'ROOT' => [
-                                                                                       'type' => 'array',
-                                                                                       'el' => [
-                                                                                               'aFlexField' => [
-                                                                                                       'label' => 'aFlexFieldLabel',
-                                                                                                       'config' => [
-                                                                                                               'type' => 'input',
-                                                                                                               'default' => 'defaultValue',
-                                                                                                       ],
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-                       'pageTsConfigMerged' => [],
-               ];
-
-               $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [
-                       \TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class => [],
-               ];
-
-               /** @var LanguageService|ObjectProphecy $languageService */
-               $languageService = $this->prophesize(LanguageService::class);
-               $GLOBALS['LANG'] = $languageService->reveal();
-               $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(TRUE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ]
-               ];
-
-               $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['aFlexField']['vDEF'] = 'defaultValue';
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataSetsDefaultValueFromFlexTcaForFieldInLocalizedSheet() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [],
-                                       'meta' => [],
-                               ],
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'EN',
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds' => [
-                                                               'sheets' => [
-                                                                       'sDEF' => [
-                                                                               'ROOT' => [
-                                                                                       'type' => 'array',
-                                                                                       'el' => [
-                                                                                               'aFlexField' => [
-                                                                                                       'label' => 'aFlexFieldLabel',
-                                                                                                       'config' => [
-                                                                                                               'type' => 'input',
-                                                                                                               'default' => 'defaultValue',
-                                                                                                       ],
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-                       'pageTsConfigMerged' => [],
-               ];
-
-               $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [
-                       \TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class => [],
-               ];
-
-               /** @var LanguageService|ObjectProphecy $languageService */
-               $languageService = $this->prophesize(LanguageService::class);
-               $GLOBALS['LANG'] = $languageService->reveal();
-               $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(TRUE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF'
-                       ]
-               ];
-
-               $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['aFlexField']['vDEF'] = 'defaultValue';
-               $expected['databaseRow']['aField']['data']['sDEF']['lEN']['aFlexField']['vDEF'] = 'defaultValue';
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataSetsDefaultValueFromFlexTcaForFieldInLocalizedSheetWithLangChildren() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [],
-                                       'meta' => [],
-                               ],
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'EN',
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds' => [
-                                                               'meta' => [
-                                                                       'langChildren' => 1,
-                                                               ],
                                                                'sheets' => [
                                                                        'sDEF' => [
                                                                                'ROOT' => [
@@ -1840,24 +850,7 @@ class TcaFlexProcessTest extends UnitTestCase {
                $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(TRUE);
 
                $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => TRUE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                               1 => 'EN'
-                       ]
-               ];
-
                $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['aFlexField']['vDEF'] = 'defaultValue';
-               $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['aFlexField']['vEN'] = 'defaultValue';
 
                $this->assertEquals($expected, $this->subject->addData($input));
        }
@@ -1874,12 +867,6 @@ class TcaFlexProcessTest extends UnitTestCase {
                                        'meta' => [],
                                ],
                        ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                       ],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -1926,12 +913,6 @@ class TcaFlexProcessTest extends UnitTestCase {
                                        'meta' => [],
                                ],
                        ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                       ],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -1969,7 +950,7 @@ class TcaFlexProcessTest extends UnitTestCase {
        /**
         * @test
         */
-       public function addDataSetsValuesAndStructureForSectionContainerElementsNoLangChildren() {
+       public function addDataSetsValuesAndStructureForSectionContainerElements() {
                $input = [
                        'tableName' => 'aTable',
                        'databaseRow' => [
@@ -2015,16 +996,6 @@ class TcaFlexProcessTest extends UnitTestCase {
                                        'meta' => [],
                                ],
                        ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'EN',
-                               ],
-                       ],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -2079,319 +1050,14 @@ class TcaFlexProcessTest extends UnitTestCase {
                $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(TRUE);
 
                $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => FALSE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                       ]
-               ];
 
                // A default value for existing container field aFlexField should have been set
                $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['el']['1']['container_1']['el']['aFlexField']['vDEF'] = 'defaultValue';
-               // Also for the other defined language
-               $expected['databaseRow']['aField']['data']['sDEF']['lEN']['section_1']['el']['1']['container_1']['el']['aFlexField']['vDEF'] = 'defaultValue';
 
                // Dummy row values for container_1 on lDEF sheet
                $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['templateRows']['container_1']['el']['aFlexField']['vDEF'] = 'defaultValue';
-               // Dummy row values for container_1 on lDEF sheet
-               $expected['databaseRow']['aField']['data']['sDEF']['lEN']['section_1']['templateRows']['container_1']['el']['aFlexField']['vDEF'] = 'defaultValue';
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataSetsValuesAndStructureForSectionContainerElementsWithLangChildren() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [
-                                               'sDEF' => [
-                                                       'lDEF' => [
-                                                               'section_1' => [
-                                                                       'el' => [
-                                                                               '1' => [
-                                                                                       'container_1' => [
-                                                                                               // It should set a default for both vDEF and vEN
-                                                                                               'el' => [
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                               '2' => [
-                                                                                       'container_1' => [
-                                                                                               'el' => [
-                                                                                                       'aFlexField' => [
-                                                                                                               // It should keep this value
-                                                                                                               'vDEF' => 'dbValue',
-                                                                                                               // It should set a default for vEN
-                                                                                                       ],
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                                       'meta' => [],
-                               ],
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'EN',
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds' => [
-                                                               'meta' => [
-                                                                       'langChildren' => 1,
-                                                               ],
-                                                               'sheets' => [
-                                                                       'sDEF' => [
-                                                                               'ROOT' => [
-                                                                                       'type' => 'array',
-                                                                                       'el' => [
-                                                                                               'section_1' => [
-                                                                                                       'section' => '1',
-                                                                                                       'type' => 'array',
-                                                                                                       'el' => [
-                                                                                                               'container_1' => [
-                                                                                                                       'type' => 'array',
-                                                                                                                       'el' => [
-                                                                                                                               'aFlexField' => [
-                                                                                                                                       'label' => 'aFlexFieldLabel',
-                                                                                                                                       'config' => [
-                                                                                                                                               'type' => 'input',
-                                                                                                                                               'default' => 'defaultValue',
-                                                                                                                                       ],
-                                                                                                                               ],
-                                                                                                                       ],
-                                                                                                               ],
-                                                                                                       ],
-                                                                                               ],
-                                                                                       ],
-                                                                               ],
-                                                                       ],
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                               ],
-                       ],
-                       'pageTsConfigMerged' => [],
-               ];
-
-               $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [
-                       \TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class => [],
-               ];
-
-               /** @var LanguageService|ObjectProphecy $languageService */
-               $languageService = $this->prophesize(LanguageService::class);
-               $GLOBALS['LANG'] = $languageService->reveal();
-               $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
-               $this->backendUserProphecy->isAdmin()->willReturn(TRUE);
-               $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(TRUE);
-
-               $expected = $input;
-               $expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [
-                       'availableLanguageCodes' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ],
-                       'langDisable' => FALSE,
-                       'langChildren' => TRUE,
-                       'languagesOnSheetLevel' => [
-                               0 => 'DEF',
-                       ],
-                       'languagesOnElement' => [
-                               0 => 'DEF',
-                               1 => 'EN',
-                       ]
-               ];
-
-               // A default value for existing container field aFlexField should have been set
-               $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['el']['1']['container_1']['el']['aFlexField']['vDEF'] = 'defaultValue';
-               $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['el']['1']['container_1']['el']['aFlexField']['vEN'] = 'defaultValue';
-               // Also for the other defined language
-               $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['el']['2']['container_1']['el']['aFlexField']['vEN'] = 'defaultValue';
-
-               // There should be a templateRow for container_1 with defaultValue set for both languages
-               $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['templateRows']['container_1']['el']['aFlexField']['vDEF'] = 'defaultValue';
-               $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['templateRows']['container_1']['el']['aFlexField']['vEN'] = 'defaultValue';
 
                $this->assertEquals($expected, $this->subject->addData($input));
        }
 
-
-       /**
-        * Date provider for addDataSetsLanguageFlags
-        *
-        * @return array
-        */
-       public function addDataSetsLanguageFlagsDataProvider() {
-               return [
-                       'Default values are set' => [
-                               'sheets' => [
-                                       'sDEF' => [
-                                               'ROOT' => [],
-                                       ],
-                               ],
-                               FALSE,
-                               FALSE,
-                               [],
-                               [0 => 'DEF'],
-                       ],
-                       'langDisable is set to FALSE' => [
-                               'sheets' => [
-                                       'meta' => [
-                                               'langDisable' => 0,
-                                       ],
-                                       'sDEF' => [
-                                               'ROOT' => [],
-                                       ],
-                               ],
-                               FALSE,
-                               FALSE,
-                               [],
-                               [0 => 'DEF'],
-                       ],
-                       'langDisable is set to TRUE' => [
-                               'sheets' => [
-                                       'meta' => [
-                                               'langDisable' => 1,
-                                       ],
-                                       'sDEF' => [
-                                               'ROOT' => [],
-                                       ],
-                               ],
-                               TRUE,
-                               FALSE,
-                               [],
-                               [0 => 'DEF'],
-                       ],
-                       'langChildren is set to FALSE' => [
-                               'sheets' => [
-                                       'meta' => [
-                                               'langChildren' => 0,
-                                       ],
-                                       'sDEF' => [
-                                               'ROOT' => [],
-                                       ],
-                               ],
-                               FALSE,
-                               FALSE,
-                               [],
-                               [0 => 'DEF'],
-                       ],
-                       'langChildren is set to TRUE' => [
-                               'sheets' => [
-                                       'meta' => [
-                                               'langChildren' => 1,
-                                       ],
-                                       'sDEF' => [
-                                               'ROOT' => [],
-                                       ],
-                               ],
-                               FALSE,
-                               TRUE,
-                               [0 => 'DEF'],
-                               [],
-                       ],
-                       'langDisable and langChildren are set' => [
-                               'sheets' => [
-                                       'meta' => [
-                                               'langDisable' => 1,
-                                               'langChildren' => 1,
-                                       ],
-                                       'sDEF' => [
-                                               'ROOT' => [],
-                                       ],
-                               ],
-                               TRUE,
-                               TRUE,
-                               [0 => 'DEF'],
-                               [],
-                       ],
-               ];
-       }
-
-       /**
-        * @test
-        * @param $flexform
-        * @param $expectedLangDisable
-        * @param $expectedLangChildren
-        * @param $expectedLanguagesOnSheetLevel
-        * @param $expectedLanguagesOnElement
-        * @dataProvider addDataSetsLanguageFlagsDataProvider
-        */
-       public function addDataSetsLanguageFlags($flexform, $expectedLangDisable, $expectedLangChildren, $expectedLanguagesOnSheetLevel, $expectedLanguagesOnElement) {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'aField' => [
-                                       'data' => [
-                                               'sDEF' => [
-                                                       'lDEF' => [
-                                                               'input_1' => [
-                                                                       'vDEF' => 'input1 text',
-                                                               ],
-                                                       ],
-                                               ],
-                                       ],
-                                       'meta' => [],
-                               ],
-                               'pointerField' => 'aFlex',
-                       ],
-                       'systemLanguageRows' => [
-                               0 => [
-                                       'uid' => 0,
-                                       'iso' => 'DEF',
-                               ],
-                               1 => [
-                                       'uid' => 1,
-                                       'iso' => 'EN',
-                               ],
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'flex',
-                                                       'ds_pointerField' => 'pointerField',
-                                                       'ds' => $flexform,
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $result = $this->subject->addData($input);
-
-               $this->assertEquals($expectedLangDisable, $result['processedTca']['columns']['aField']['config']['ds']['meta']['langDisable']);
-               $this->assertEquals($expectedLangChildren, $result['processedTca']['columns']['aField']['config']['ds']['meta']['langChildren']);
-               $this->assertEquals($expectedLanguagesOnSheetLevel, $result['processedTca']['columns']['aField']['config']['ds']['meta']['languagesOnSheetLevel']);
-               $this->assertEquals($expectedLanguagesOnElement, $result['processedTca']['columns']['aField']['config']['ds']['meta']['languagesOnElement']);
-       }
-
 }
diff --git a/typo3/sysext/compatibility6/Classes/Configuration/FlexForm/FlexFormTools.php b/typo3/sysext/compatibility6/Classes/Configuration/FlexForm/FlexFormTools.php
new file mode 100644 (file)
index 0000000..70d97bc
--- /dev/null
@@ -0,0 +1,412 @@
+<?php
+namespace TYPO3\CMS\Compatibility6\Configuration\FlexForm;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Contains functions for manipulating flex form data
+ */
+class FlexFormTools {
+
+       /**
+        * If set, the charset of data XML is converted to system charset.
+        *
+        * @var bool
+        */
+       public $convertCharset = FALSE;
+
+       /**
+        * If set, section indexes are re-numbered before processing
+        *
+        * @var bool
+        */
+       public $reNumberIndexesOfSectionData = FALSE;
+
+       /**
+        * Contains data structure when traversing flexform
+        *
+        * @var array
+        */
+       public $traverseFlexFormXMLData_DS = array();
+
+       /**
+        * Contains data array when traversing flexform
+        *
+        * @var array
+        */
+       public $traverseFlexFormXMLData_Data = array();
+
+       /**
+        * Options for array2xml() for flexform.
+        * This will map the weird keys from the internal array to tags that could potentially be checked with a DTD/schema
+        *
+        * @var array
+        */
+       public $flexArray2Xml_options = array(
+               'parentTagMap' => array(
+                       'data' => 'sheet',
+                       'sheet' => 'language',
+                       'language' => 'field',
+                       'el' => 'field',
+                       'field' => 'value',
+                       'field:el' => 'el',
+                       'el:_IS_NUM' => 'section',
+                       'section' => 'itemType'
+               ),
+               'disableTypeAttrib' => 2
+       );
+
+       /**
+        * Reference to object called
+        *
+        * @var object
+        */
+       public $callBackObj = NULL;
+
+       /**
+        * Used for accumulation of clean XML
+        *
+        * @var array
+        */
+       public $cleanFlexFormXML = array();
+
+       /**
+        * Handler for Flex Forms
+        *
+        * @param string $table The table name of the record
+        * @param string $field The field name of the flexform field to work on
+        * @param array $row The record data array
+        * @param object $callBackObj Object in which the call back function is located
+        * @param string $callBackMethod_value Method name of call back function in object for values
+        * @return bool|string If TRUE, error happened (error string returned)
+        */
+       public function traverseFlexFormXMLData($table, $field, $row, $callBackObj, $callBackMethod_value) {
+               if (!is_array($GLOBALS['TCA'][$table]) || !is_array($GLOBALS['TCA'][$table]['columns'][$field])) {
+                       return 'TCA table/field was not defined.';
+               }
+               $this->callBackObj = $callBackObj;
+               // Get Data Structure:
+               $dataStructArray = BackendUtility::getFlexFormDS($GLOBALS['TCA'][$table]['columns'][$field]['config'], $row, $table, $field);
+               // If data structure was ok, proceed:
+               if (is_array($dataStructArray)) {
+                       // Get flexform XML data:
+                       $xmlData = $row[$field];
+                       // Convert charset:
+                       if ($this->convertCharset) {
+                               $xmlHeaderAttributes = GeneralUtility::xmlGetHeaderAttribs($xmlData);
+                               $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
+                               if ($storeInCharset) {
+                                       $currentCharset = $GLOBALS['LANG']->charSet;
+                                       $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
+                               }
+                       }
+                       $editData = GeneralUtility::xml2array($xmlData);
+                       if (!is_array($editData)) {
+                               return 'Parsing error: ' . $editData;
+                       }
+                       // Language settings:
+                       $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
+                       $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
+                       // Empty or invalid <meta>
+                       if (!is_array($editData['meta'])) {
+                               $editData['meta'] = array();
+                       }
+                       $editData['meta']['currentLangId'] = array();
+                       $languages = $this->getAvailableLanguages();
+                       foreach ($languages as $lInfo) {
+                               $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
+                       }
+                       if (empty($editData['meta']['currentLangId'])) {
+                               $editData['meta']['currentLangId'] = array('DEF');
+                       }
+                       $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
+                       if ($langChildren || $langDisabled) {
+                               $lKeys = array('DEF');
+                       } else {
+                               $lKeys = $editData['meta']['currentLangId'];
+                       }
+                       // Tabs sheets
+                       if (is_array($dataStructArray['sheets'])) {
+                               $sKeys = array_keys($dataStructArray['sheets']);
+                       } else {
+                               $sKeys = array('sDEF');
+                       }
+                       // Traverse languages:
+                       foreach ($lKeys as $lKey) {
+                               foreach ($sKeys as $sheet) {
+                                       $sheetCfg = $dataStructArray['sheets'][$sheet];
+                                       list($dataStruct, $sheet) = GeneralUtility::resolveSheetDefInDS($dataStructArray, $sheet);
+                                       // Render sheet:
+                                       if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
+                                               // Separate language key
+                                               $lang = 'l' . $lKey;
+                                               $PA['vKeys'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : array('DEF');
+                                               $PA['lKey'] = $lang;
+                                               $PA['callBackMethod_value'] = $callBackMethod_value;
+                                               $PA['table'] = $table;
+                                               $PA['field'] = $field;
+                                               $PA['uid'] = $row['uid'];
+                                               $this->traverseFlexFormXMLData_DS = &$dataStruct;
+                                               $this->traverseFlexFormXMLData_Data = &$editData;
+                                               // Render flexform:
+                                               $this->traverseFlexFormXMLData_recurse($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $PA, 'data/' . $sheet . '/' . $lang);
+                                       } else {
+                                               return 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
+                                       }
+                               }
+                       }
+               } else {
+                       return 'Data Structure ERROR: ' . $dataStructArray;
+               }
+       }
+
+       /**
+        * Recursively traversing flexform data according to data structure and element data
+        *
+        * @param array $dataStruct (Part of) data structure array that applies to the sub section of the flexform data we are processing
+        * @param array $editData (Part of) edit data array, reflecting current part of data structure
+        * @param array $PA Additional parameters passed.
+        * @param string $path Telling the "path" to the element in the flexform XML
+        * @return array
+        */
+       public function traverseFlexFormXMLData_recurse($dataStruct, $editData, &$PA, $path = '') {
+               if (is_array($dataStruct)) {
+                       foreach ($dataStruct as $key => $value) {
+                               // The value of each entry must be an array.
+                               if (is_array($value)) {
+                                       if ($value['type'] == 'array') {
+                                               // Array (Section) traversal
+                                               if ($value['section']) {
+                                                       $cc = 0;
+                                                       if (is_array($editData[$key]['el'])) {
+                                                               if ($this->reNumberIndexesOfSectionData) {
+                                                                       $temp = array();
+                                                                       $c3 = 0;
+                                                                       foreach ($editData[$key]['el'] as $v3) {
+                                                                               $temp[++$c3] = $v3;
+                                                                       }
+                                                                       $editData[$key]['el'] = $temp;
+                                                               }
+                                                               foreach ($editData[$key]['el'] as $k3 => $v3) {
+                                                                       if (is_array($v3)) {
+                                                                               $cc = $k3;
+                                                                               $theType = key($v3);
+                                                                               $theDat = $v3[$theType];
+                                                                               $newSectionEl = $value['el'][$theType];
+                                                                               if (is_array($newSectionEl)) {
+                                                                                       $this->traverseFlexFormXMLData_recurse(array($theType => $newSectionEl), array($theType => $theDat), $PA, $path . '/' . $key . '/el/' . $cc);
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               } else {
+                                                       // Array traversal
+                                                       if (is_array($editData) && is_array($editData[$key])) {
+                                                               $this->traverseFlexFormXMLData_recurse($value['el'], $editData[$key]['el'], $PA, $path . '/' . $key . '/el');
+                                                       }
+                                               }
+                                       } elseif (is_array($value['TCEforms']['config'])) {
+                                               // Processing a field value:
+                                               foreach ($PA['vKeys'] as $vKey) {
+                                                       $vKey = 'v' . $vKey;
+                                                       // Call back
+                                                       if ($PA['callBackMethod_value'] && is_array($editData) && is_array($editData[$key])) {
+                                                               $this->executeCallBackMethod($PA['callBackMethod_value'], array($value, $editData[$key][$vKey], $PA, $path . '/' . $key . '/' . $vKey, $this));
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Execute method on callback object
+        *
+        * @param string $methodName Method name to call
+        * @param array $parameterArray Parameters
+        * @return mixed Result of callback object
+        */
+       protected function executeCallBackMethod($methodName, array $parameterArray) {
+               return call_user_func_array(array($this->callBackObj, $methodName), $parameterArray);
+       }
+
+       /**
+        * Returns an array of available languages to use for FlexForm operations
+        *
+        * @return array
+        */
+       public function getAvailableLanguages() {
+               $isL = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('static_info_tables');
+               // Find all language records in the system
+               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+                       'language_isocode,static_lang_isocode,title,uid',
+                       'sys_language',
+                       'pid=0' . BackendUtility::deleteClause('sys_language'),
+                       '',
+                       'title'
+               );
+               // Traverse them
+               $output = array();
+               $output[0] = array(
+                       'uid' => 0,
+                       'title' => 'Default language',
+                       'ISOcode' => 'DEF'
+               );
+               while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+                       $output[$row['uid']] = $row;
+                       if (!empty($row['language_isocode'])) {
+                               $output[$row['uid']]['ISOcode'] = $row['language_isocode'];
+                       } elseif ($isL && $row['static_lang_isocode']) {
+                               \TYPO3\CMS\Core\Utility\GeneralUtility::deprecationLog('Usage of the field "static_lang_isocode" is discouraged, and will stop working with CMS 8. Use the built-in language field "language_isocode" in your sys_language records.');
+                               $rr = BackendUtility::getRecord('static_languages', $row['static_lang_isocode'], 'lg_iso_2');
+                               if ($rr['lg_iso_2']) {
+                                       $output[$row['uid']]['ISOcode'] = $rr['lg_iso_2'];
+                               }
+                       }
+                       if (!$output[$row['uid']]['ISOcode']) {
+                               unset($output[$row['uid']]);
+                       }
+               }
+               $GLOBALS['TYPO3_DB']->sql_free_result($res);
+               return $output;
+       }
+
+       /***********************************
+        *
+        * Processing functions
+        *
+        ***********************************/
+       /**
+        * Cleaning up FlexForm XML to hold only the values it may according to its Data Structure. Also the order of tags will follow that of the data structure.
+        * BE CAREFUL: DO not clean records in workspaces unless IN the workspace! The Data Structure might resolve falsely on a workspace record when cleaned from Live workspace.
+        *
+        * @param string $table Table name
+        * @param string $field Field name of the flex form field in which the XML is found that should be cleaned.
+        * @param array $row The record
+        * @return string Clean XML from FlexForm field
+        */
+       public function cleanFlexFormXML($table, $field, $row) {
+               // New structure:
+               $this->cleanFlexFormXML = array();
+               // Create and call iterator object:
+               $flexObj = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class);
+               $flexObj->reNumberIndexesOfSectionData = TRUE;
+               $flexObj->traverseFlexFormXMLData($table, $field, $row, $this, 'cleanFlexFormXML_callBackFunction');
+               return $this->flexArray2Xml($this->cleanFlexFormXML, TRUE);
+       }
+
+       /**
+        * Call back function for \TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools class
+        * Basically just setting the value in a new array (thus cleaning because only values that are valid are visited!)
+        *
+        * @param array $dsArr Data structure for the current value
+        * @param mixed $data Current value
+        * @param array $PA Additional configuration used in calling function
+        * @param string $path Path of value in DS structure
+        * @param FlexFormTools $pObj caller
+        * @return void
+        */
+       public function cleanFlexFormXML_callBackFunction($dsArr, $data, $PA, $path, $pObj) {
+               // Just setting value in our own result array, basically replicating the structure:
+               $pObj->setArrayValueByPath($path, $this->cleanFlexFormXML, $data);
+               // Looking if an "extension" called ".vDEFbase" is found and if so, accept that too:
+               if ($GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase']) {
+                       $vDEFbase = $pObj->getArrayValueByPath($path . '.vDEFbase', $pObj->traverseFlexFormXMLData_Data);
+                       if (isset($vDEFbase)) {
+                               $pObj->setArrayValueByPath($path . '.vDEFbase', $this->cleanFlexFormXML, $vDEFbase);
+                       }
+               }
+       }
+
+       /***********************************
+        *
+        * Multi purpose functions
+        *
+        ***********************************/
+       /**
+        * Get a value from a multi-dimensional array by giving a path "../../.." pointing to the element
+        *
+        * @param string $pathArray The path pointing to the value field, eg. test/2/title to access $array['test'][2]['title']
+        * @param array $array Array to get value from. Passed by reference so the value returned can be used to change the value in the array!
+        * @return mixed Value returned
+        */
+       public function &getArrayValueByPath($pathArray, &$array) {
+               if (!is_array($pathArray)) {
+                       $pathArray = explode('/', $pathArray);
+               }
+               if (is_array($array) && !empty($pathArray)) {
+                       $key = array_shift($pathArray);
+                       if (isset($array[$key])) {
+                               if (empty($pathArray)) {
+                                       return $array[$key];
+                               }
+                               return $this->getArrayValueByPath($pathArray, $array[$key]);
+                       }
+                       return NULL;
+               }
+       }
+
+       /**
+        * Set a value in a multi-dimensional array by giving a path "../../.." pointing to the element
+        *
+        * @param string $pathArray The path pointing to the value field, eg. test/2/title to access $array['test'][2]['title']
+        * @param array $array Array to set value in. Passed by reference so the value returned can be used to change the value in the array!
+        * @param mixed $value Value to set
+        * @return mixed Value returned
+        */
+       public function setArrayValueByPath($pathArray, &$array, $value) {
+               if (isset($value)) {
+                       if (!is_array($pathArray)) {
+                               $pathArray = explode('/', $pathArray);
+                       }
+                       if (is_array($array) && !empty($pathArray)) {
+                               $key = array_shift($pathArray);
+                               if (empty($pathArray)) {
+                                       $array[$key] = $value;
+                                       return TRUE;
+                               }
+                               if (!isset($array[$key])) {
+                                       $array[$key] = array();
+                               }
+                               return $this->setArrayValueByPath($pathArray, $array[$key], $value);
+
+                       }
+               }
+       }
+
+       /**
+        * Convert FlexForm data array to XML
+        *
+        * @param array $array Array to output in <T3FlexForms> XML
+        * @param bool $addPrologue If set, the XML prologue is returned as well.
+        * @return string XML content.
+        */
+       public function flexArray2Xml($array, $addPrologue = FALSE) {
+               if ($GLOBALS['TYPO3_CONF_VARS']['BE']['flexformForceCDATA']) {
+                       $this->flexArray2Xml_options['useCDATA'] = 1;
+               }
+               $options = $GLOBALS['TYPO3_CONF_VARS']['BE']['niceFlexFormXMLtags'] ? $this->flexArray2Xml_options : array();
+               $spaceInd = $GLOBALS['TYPO3_CONF_VARS']['BE']['compactFlexFormXML'] ? -1 : 4;
+               $output = GeneralUtility::array2xml($array, '', 0, 'T3FlexForms', $spaceInd, $options);
+               if ($addPrologue) {
+                       $output = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>' . LF . $output;
+               }
+               return $output;
+       }
+
+}
diff --git a/typo3/sysext/compatibility6/Classes/Form/Container/FlexFormElementContainer.php b/typo3/sysext/compatibility6/Classes/Form/Container/FlexFormElementContainer.php
new file mode 100644 (file)
index 0000000..95838be
--- /dev/null
@@ -0,0 +1,224 @@
+<?php
+namespace TYPO3\CMS\Compatibility6\Form\Container;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\Form\Container\AbstractContainer;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Lang\LanguageService;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+
+/**
+ * The container handles single elements.
+ *
+ * This one is called by FlexFormTabsContainer, FlexFormNoTabsContainer or FlexFormContainerContainer.
+ * For single fields, the code is similar to SingleFieldContainer, processing will end up in single
+ * element classes depending on specific type of an element. Additionally, it determines if a
+ * section is handled and hands over to FlexFormSectionContainer in this case.
+ */
+class FlexFormElementContainer extends AbstractContainer {
+
+       /**
+        * Entry method
+        *
+        * @return array As defined in initializeResultArray() of AbstractNode
+        */
+       public function render() {
+               $table = $this->data['tableName'];
+               $row = $this->data['databaseRow'];
+               $flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
+               $flexFormRowData = $this->data['flexFormRowData'];
+               $flexFormFormPrefix = $this->data['flexFormFormPrefix'];
+               $parameterArray = $this->data['parameterArray'];
+               $metaData = $this->data['parameterArray']['fieldConf']['config']['ds']['meta'];
+
+               $languageService = $this->getLanguageService();
+               /** @var IconFactory $iconFactory */
+               $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+               $resultArray = $this->initializeResultArray();
+               foreach ($flexFormDataStructureArray as $flexFormFieldName => $flexFormFieldArray) {
+                       if (
+                               // No item array found at all
+                               !is_array($flexFormFieldArray)
+                               // Not a section or container and not a list of single items
+                               || (!isset($flexFormFieldArray['type']) && !is_array($flexFormFieldArray['config']))
+                       ) {
+                               continue;
+                       }
+
+                       if ($flexFormFieldArray['type'] === 'array') {
+                               // Section
+                               if (empty($flexFormFieldArray['section'])) {
+                                       $resultArray['html'] = LF . 'Section expected at ' . $flexFormFieldName . ' but not found';
+                                       continue;
+                               }
+
+                               $sectionTitle = '';
+                               if (!empty($flexFormFieldArray['title'])) {
+                                       $sectionTitle = $languageService->sL($flexFormFieldArray['title']);
+                               }
+
+                               $options = $this->data;
+                               $options['flexFormDataStructureArray'] = $flexFormFieldArray['el'];
+                               $options['flexFormRowData'] = is_array($flexFormRowData[$flexFormFieldName]['el']) ? $flexFormRowData[$flexFormFieldName]['el'] : array();
+                               $options['flexFormSectionType'] = $flexFormFieldName;
+                               $options['flexFormSectionTitle'] = $sectionTitle;
+                               $options['renderType'] = 'flexFormSectionContainer';
+                               $sectionContainerResult = $this->nodeFactory->create($options)->render();
+                               $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $sectionContainerResult);
+                       } else {
+                               if (is_array($metaData) && isset($metaData['langChildren']) && isset($metaData['languagesOnElement'])) {
+                                       $lkeys = $metaData['languagesOnElement'];
+                                       array_walk($lkeys, function (&$value) {
+                                               $value = 'v' . $value;
+                                       });
+                               } else {
+                                       $lkeys = array('vDEF');
+                               }
+                               $html = array();
+                               foreach ($lkeys as $lkey) {
+                                       // Set up options for single element
+                                       $fakeParameterArray = array(
+                                               'fieldConf' => array(
+                                                       'label' => $languageService->sL(trim($flexFormFieldArray['label'])),
+                                                       'config' => $flexFormFieldArray['config'],
+                                                       'defaultExtras' => $flexFormFieldArray['defaultExtras'],
+                                                       'onChange' => $flexFormFieldArray['onChange'],
+                                               ),
+                                       );
+
+                                       $alertMsgOnChange = '';
+                                       if (
+                                               $fakeParameterArray['fieldConf']['onChange'] === 'reload'
+                                               || !empty($GLOBALS['TCA'][$table]['ctrl']['type']) && $GLOBALS['TCA'][$table]['ctrl']['type'] === $flexFormFieldName
+                                               || !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate']) && GeneralUtility::inList($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'], $flexFormFieldName)
+                                       ) {
+                                               if ($this->getBackendUserAuthentication()->jsConfirmation(JsConfirmation::TYPE_CHANGE)) {
+                                                       $alertMsgOnChange = 'top.TYPO3.Modal.confirm(TBE_EDITOR.labels.refreshRequired.title, TBE_EDITOR.labels.refreshRequired.content).on("button.clicked", function(e) { if (e.target.name == "ok" && TBE_EDITOR.checkSubmit(-1)) { TBE_EDITOR.submitForm() } top.TYPO3.Modal.dismiss(); });';
+                                               } else {
+                                                       $alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm();}';
+                                               }
+                                       }
+                                       $fakeParameterArray['fieldChangeFunc'] = $parameterArray['fieldChangeFunc'];
+                                       if ($alertMsgOnChange) {
+                                               $fakeParameterArray['fieldChangeFunc']['alert'] = $alertMsgOnChange;
+                                       }
+
+                                       $fakeParameterArray['onFocus'] = $parameterArray['onFocus'];
+                                       $fakeParameterArray['label'] = $parameterArray['label'];
+                                       $fakeParameterArray['itemFormElName'] = $parameterArray['itemFormElName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $lkey . ']';
+                                       $fakeParameterArray['itemFormElID'] = $fakeParameterArray['itemFormElName'];
+                                       if (isset($flexFormRowData[$flexFormFieldName][$lkey])) {
+                                               $fakeParameterArray['itemFormElValue'] = $flexFormRowData[$flexFormFieldName][$lkey];
+                                       } else {
+                                               $fakeParameterArray['itemFormElValue'] = $fakeParameterArray['fieldConf']['config']['default'];
+                                       }
+
+                                       $options = $this->data;
+                                       $options['parameterArray'] = $fakeParameterArray;
+                                       $options['elementBaseName'] = $this->data['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $lkey . ']';
+
+                                       if (!empty($flexFormFieldArray['config']['renderType'])) {
+                                               $options['renderType'] = $flexFormFieldArray['config']['renderType'];
+                                       } else {
+                                               // Fallback to type if no renderType is given
+                                               $options['renderType'] = $flexFormFieldArray['config']['type'];
+                                       }
+                                       $childResult = $this->nodeFactory->create($options)->render();
+
+                                       $theTitle = htmlspecialchars($fakeParameterArray['fieldConf']['label']);
+                                       $defInfo = array();
+
+                                       // Possible line breaks in the label through xml: \n => <br/>, usage of nl2br() not possible, so it's done through str_replace (?!)
+                                       $processedTitle = str_replace('\\n', '<br />', $theTitle);
+                                       // @todo: Similar to the processing within SingleElementContainer ... use it from there?!
+                                       $html[] = '<div class="form-group t3js-formengine-palette-field t3js-formengine-validation-marker">';
+                                       $html[] = '<label class="t3js-formengine-label">';
+                                       if (is_array($metaData) && isset($metaData['langChildren']) && $metaData['langChildren']) {
+                                               // Find language uid of this iso code
+                                               $languageUid = 0;
+                                               $lKeyWithoutV = substr($lkey, 1);
+                                               if ($lKeyWithoutV !== 'DEF') {
+                                                       foreach ($this->data['systemLanguageRows'] as $systemLanguageRow) {
+                                                               if ($systemLanguageRow['iso'] === $lKeyWithoutV) {
+                                                                       $languageUid = $systemLanguageRow['uid'];
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               $languageIcon = $iconFactory->getIcon($this->data['systemLanguageRows'][$languageUid]['flagIconIdentifier'], Icon::SIZE_SMALL)->render();
+                                               $html[] = $languageIcon;
+                                       }
+                                       $html[] = BackendUtility::wrapInHelp($parameterArray['_cshKey'], $flexFormFieldName, $processedTitle);
+                                       $html[] = '</label>';
+                                       $html[] = '<div class="t3js-formengine-field-item">';
+                                       $html[] = $childResult['html'];
+                                       $html[] = implode(LF, $defInfo);
+                                       $html[] = $this->renderVDEFDiff($flexFormRowData[$flexFormFieldName], $lkey);
+                                       $html[] = '</div>';
+                                       $html[] = '</div>';
+                               }
+
+                               if (!empty($html)) {
+                                       $resultArray['html'] .= '<div class="form-section">' . implode(LF, $html) . '</div>';
+                               }
+                               $childResult['html'] = '';
+                               $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childResult);
+                       }
+               }
+
+               return $resultArray;
+       }
+
+       /**
+        * Renders the diff-view of vDEF fields in flex forms
+        *
+        * @param array $vArray Record array of the record being edited
+        * @param string $vDEFkey HTML of the form field. This is what we add the content to.
+        * @return string Item string returned again, possibly with the original value added to.
+        */
+       protected function renderVDEFDiff($vArray, $vDEFkey) {
+               $item = NULL;
+               if (
+                       $GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase'] && isset($vArray[$vDEFkey . '.vDEFbase'])
+                       && (string)$vArray[$vDEFkey . '.vDEFbase'] !== (string)$vArray['vDEF'][0]
+               ) {
+                       // Create diff-result:
+                       $diffUtility = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Utility\DiffUtility::class);
+                       $diffres = $diffUtility->makeDiffDisplay($vArray[$vDEFkey . '.vDEFbase'], $vArray['vDEF']);
+                       $item = '<div class="typo3-TCEforms-diffBox">' . '<div class="typo3-TCEforms-diffBox-header">'
+                               . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.changeInOrig')) . ':</div>' . $diffres . '</div>';
+               }
+               return $item;
+       }
+
+       /**
+        * @return LanguageService
+        */
+       protected function getLanguageService() {
+               return $GLOBALS['LANG'];
+       }
+
+       /**
+        * @return BackendUserAuthentication
+        */
+       protected function getBackendUserAuthentication() {
+               return $GLOBALS['BE_USER'];
+       }
+
+}
diff --git a/typo3/sysext/compatibility6/Classes/Form/Container/FlexFormEntryContainer.php b/typo3/sysext/compatibility6/Classes/Form/Container/FlexFormEntryContainer.php
new file mode 100644 (file)
index 0000000..b7e1d8e
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+namespace TYPO3\CMS\Compatibility6\Form\Container;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\Form\Container\AbstractContainer;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Entry container to a flex form element. This container is created by
+ * SingleFieldContainer if a type='flex' field is rendered.
+ *
+ * It either forks a FlexFormTabsContainer or a FlexFormNoTabsContainer.
+ *
+ * This container additionally handles flex form languages on sheet level.
+ */
+class FlexFormEntryContainer extends AbstractContainer {
+
+       /**
+        * Entry method
+        *
+        * @return array As defined in initializeResultArray() of AbstractNode
+        */
+       public function render() {
+               $flexFormDataStructureArray = $this->data['parameterArray']['fieldConf']['config']['ds'];
+               $flexFormRowData = $this->data['parameterArray']['itemFormElValue'];
+
+               /** @var IconFactory $iconFactory */
+               $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+
+               // Tabs or no tabs - that's the question
+               $hasTabs = FALSE;
+               if (count($flexFormDataStructureArray['sheets']) > 1) {
+                       $hasTabs = TRUE;
+               }
+
+               $resultArray = $this->initializeResultArray();
+
+               foreach ($flexFormDataStructureArray['meta']['languagesOnSheetLevel'] as $lKey) {
+                       // Add language as header
+                       if (!$flexFormDataStructureArray['meta']['langChildren'] && !$flexFormDataStructureArray['meta']['langDisable']) {
+                               // Find language uid of this iso code
+                               $languageUid = 0;
+                               if ($lKey !== 'DEF') {
+                                       foreach ($this->data['systemLanguageRows'] as $systemLanguageRow) {
+                                               if ($systemLanguageRow['iso'] === $lKey) {
+                                                       $languageUid = $systemLanguageRow['uid'];
+                                                       break;
+                                               }
+                                       }
+                               }
+                               $resultArray['html'] .= LF
+                                       . '<strong>'
+                                       . $iconFactory->getIcon($this->data['systemLanguageRows'][$languageUid]['flagIconIdentifier'], Icon::SIZE_SMALL)->render()
+                                       . htmlspecialchars($this->data['systemLanguageRows'][$languageUid]['title'])
+                                       . '</strong>';
+                       }
+
+                       // Default language "lDEF", other options are "lUK" or whatever country code
+                       $flexFormCurrentLanguage = 'l' . $lKey;
+
+                       $options = $this->data;
+                       $options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage;
+                       $options['flexFormDataStructureArray'] = $flexFormDataStructureArray;
+           &nb