[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);
                        }
@@ -186,28 +148,6 @@ class FlexFormElementContainer extends AbstractContainer {
        }
 
        /**
-        * 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() {
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
 
-                               }
                        }
                }
 
@@ -607,104 +469,6 @@ class TcaFlexProcess extends AbstractItemProvider implements FormDataProviderInt
        }
 
        /**
-        * 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
         */
        protected function getBackendUser() {
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;
 
 /**
@@ -56,133 +53,15 @@ class TcaFlexProcessTest extends UnitTestCase {
        /**
         * @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
-        */
        public function addDataRemovesSheetIfDisabledByPageTsConfig() {
                $input = [
                        'tableName' => 'aTable',
                        '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;
+                       $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;
+       }
+
+}
diff --git a/typo3/sysext/compatibility6/Classes/Form/Container/FlexFormNoTabsContainer.php b/typo3/sysext/compatibility6/Classes/Form/Container/FlexFormNoTabsContainer.php
new file mode 100644 (file)
index 0000000..eacf04c
--- /dev/null
@@ -0,0 +1,77 @@
+<?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\Utility\GeneralUtility;
+
+/**
+ * Handle a flex form that has no tabs.
+ *
+ * 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.
+ */
+class FlexFormNoTabsContainer extends AbstractContainer {
+
+       /**
+        * Entry method
+        *
+        * @return array As defined in initializeResultArray() of AbstractNode
+        */
+       public function render() {
+               $table = $this->data['tableName'];
+               $row = $this->data['databaseRow'];
+               $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];
+
+               // That was taken from GeneralUtility::resolveSheetDefInDS - no idea if it is important
+               unset($flexFormDataStructureArray['meta']);
+
+               if (!is_array($flexFormDataStructureArray['sheets'][$sheetName]['ROOT']['el'])) {
+                       $resultArray['html'] = 'Data Structure ERROR: No [\'ROOT\'][\'el\'] element found in flex form definition.';
+                       return $resultArray;
+               }
+
+               // Assemble key for loading the correct CSH file
+               // @todo: what is that good for? That is for the title of single elements ... see FlexFormElementContainer!
+               $dsPointerFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['ds_pointerField'], TRUE);
+               $parameterArray['_cshKey'] = $table . '.' . $fieldName;
+               foreach ($dsPointerFields as $key) {
+                       if ((string)$row[$key] !== '') {
+                               $parameterArray['_cshKey'] .= '.' . $row[$key];
+                       }
+               }
+
+               $options = $this->data;
+               $options['flexFormDataStructureArray'] = $flexFormDataStructureArray['sheets'][$sheetName]['ROOT']['el'];
+               $options['flexFormRowData'] = $flexFormRowDataSubPart;
+               $options['flexFormFormPrefix'] = '[data][' . $sheetName . '][' . $flexFormCurrentLanguage . ']';
+               $options['parameterArray'] = $parameterArray;
+
+               $options['renderType'] = 'flexFormElementContainer';
+               return $this->nodeFactory->create($options)->render();
+       }
+
+}
diff --git a/typo3/sysext/compatibility6/Classes/Form/Container/FlexFormTabsContainer.php b/typo3/sysext/compatibility6/Classes/Form/Container/FlexFormTabsContainer.php
new file mode 100644 (file)
index 0000000..e58cfe8
--- /dev/null
@@ -0,0 +1,122 @@
+<?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\Backend\Template\DocumentTemplate;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Lang\LanguageService;
+
+/**
+ * Handle flex forms that have tabs (multiple "sheets").
+ *
+ * This container is called by FlexFormEntryContainer. It resolves each
+ * sheet and hands rendering of single sheet content over to FlexFormElementContainer.
+ */
+class FlexFormTabsContainer extends AbstractContainer {
+
+       /**
+        * Entry method
+        *
+        * @return array As defined in initializeResultArray() of AbstractNode
+        */
+       public function render() {
+               $languageService = $this->getLanguageService();
+               $docTemplate = $this->getDocumentTemplate();
+
+               $table = $this->data['tableName'];
+               $row = $this->data['databaseRow'];
+               $fieldName = $this->data['fieldName']; // field name of the flex form field in DB
+               $parameterArray = $this->data['parameterArray'];
+