2 namespace TYPO3\CMS\Backend\Form\FormDataProvider
;
5 * This file is part of the TYPO3 CMS project.
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
14 * The TYPO3 project - inspiring people to share!
17 use TYPO3\CMS\Backend\Form\FormDataCompiler
;
18 use TYPO3\CMS\Backend\Form\FormDataGroup\FlexFormSegment
;
19 use TYPO3\CMS\Backend\Form\FormDataProviderInterface
;
20 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication
;
21 use TYPO3\CMS\Core\Utility\GeneralUtility
;
24 * Process data structures and data values, calculate defaults.
26 * This is typically the last provider, executed after TcaFlexPrepare
28 class TcaFlexProcess
extends AbstractItemProvider
implements FormDataProviderInterface
{
31 * Determine possible pageTsConfig overrides and apply them to ds.
32 * Determine available languages and sanitize dv for further processing. Then kick
33 * and validate further details like excluded fields. Finally for each possible
34 * value and ds call FormDataCompiler with set FlexFormSegment group to resolve
35 * single field stuff like item processor functions.
37 * @param array $result
40 public function addData(array $result) {
41 foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
42 if (empty($fieldConfig['config']['type']) ||
$fieldConfig['config']['type'] !== 'flex') {
46 $flexIdentifier = $this->getFlexIdentifier($result, $fieldName);
47 $pageTsConfigOfFlex = $this->getPageTsOfFlex($result, $fieldName, $flexIdentifier);
48 $result = $this->modifyOuterDataStructure($result, $fieldName, $pageTsConfigOfFlex);
49 $result = $this->removeExcludeFieldsFromDataStructure($result, $fieldName, $flexIdentifier);
50 $result = $this->removeDisabledFieldsFromDataStructure($result, $fieldName, $pageTsConfigOfFlex);
51 $result = $this->prepareLanguageHandlingInDataValues($result, $fieldName);
52 $result = $this->modifyDataStructureAndDataValuesByFlexFormSegmentGroup($result, $fieldName, $pageTsConfigOfFlex);
59 * Take care of ds_pointerField and friends to determine the correct sub array within
62 * Gets extension identifier. Use second pointer field if it's value is not empty, "list" or "*",
63 * else it must be a plugin and first one will be used.
64 * This code basically determines the sub key of ds field:
67 * 'aFlexConfig' => '<flexXml ...
69 * $flexformIdentifier contains "aFlexConfig" after this operation.
71 * @todo: This method is only implemented half. It basically should do all the
72 * @todo: pointer handling that is done within BackendUtility::getFlexFormDS() to $srcPointer.
74 * @param array $result Result array
75 * @param string $fieldName Current handle field name
76 * @return string Pointer
78 protected function getFlexIdentifier(array $result, $fieldName) {
79 // @todo: Current implementation with the "list_type, CType" fallback is rather limited and customized for
80 // @todo: tt_content, also it forces a ds_pointerField to be defined and a casual "default" sub array does not work
81 $pointerFields = !empty($result['processedTca']['columns'][$fieldName]['config']['ds_pointerField'])
82 ?
$result['processedTca']['columns'][$fieldName]['config']['ds_pointerField']
84 $pointerFields = GeneralUtility
::trimExplode(',', $pointerFields);
85 $flexformIdentifier = !empty($result['databaseRow'][$pointerFields[0]]) ?
$result['databaseRow'][$pointerFields[0]] : '';
86 if (!empty($result['databaseRow'][$pointerFields[1]])
87 && $result['databaseRow'][$pointerFields[1]] !== 'list'
88 && $result['databaseRow'][$pointerFields[1]] !== '*'
90 $flexformIdentifier = $result['databaseRow'][$pointerFields[1]];
92 if (empty($flexformIdentifier)) {
93 $flexformIdentifier = 'default';
96 return $flexformIdentifier;
100 * Determine TCEFORM.aTable.aField.matchingIdentifier
102 * @param array $result Result array
103 * @param string $fieldName Handled field name
104 * @param string $flexIdentifier Determined identifier
105 * @return array PageTsConfig for this flex
107 protected function getPageTsOfFlex(array $result, $fieldName, $flexIdentifier) {
108 $table = $result['tableName'];
110 if (!empty($result['pageTsConfigMerged']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'])
111 && is_array($result['pageTsConfigMerged']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'])) {
112 $pageTs = $result['pageTsConfigMerged']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'];
118 * Handle "outer" flex data structure changes like language and sheet
119 * description. Does not change "TCA" or values of single elements
121 * @param array $result Result array
122 * @param string $fieldName Current handle field name
123 * @param array $pageTsConfig Given pageTsConfig of this flex form
124 * @return array Modified item array
126 protected function modifyOuterDataStructure(array $result, $fieldName, $pageTsConfig) {
127 $modifiedDataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
129 if (isset($pageTsConfig['langDisable'])) {
130 $modifiedDataStructure['meta']['langDisable'] = $pageTsConfig['langDisable'];
132 if (isset($pageTsConfig['langChildren'])) {
133 $modifiedDataStructure['meta']['langChildren'] = $pageTsConfig['langChildren'];
136 if (isset($modifiedDataStructure['sheets']) && is_array($modifiedDataStructure['sheets'])) {
137 // Handling multiple sheets
138 foreach ($modifiedDataStructure['sheets'] as $sheetName => $sheetStructure) {
139 if (isset($pageTsConfig[$sheetName . '.']) && is_array($pageTsConfig[$sheetName . '.'])) {
140 $pageTsOfSheet = $pageTsConfig[$sheetName . '.'];
142 // Remove whole sheet if disabled
143 if (!empty($pageTsOfSheet['disabled'])) {
144 unset($modifiedDataStructure['sheets'][$sheetName]);
148 // sheetTitle, sheetDescription, sheetShortDescr
149 $modifiedDataStructure['sheets'][$sheetName] = $this->modifySingleSheetInformation($sheetStructure, $pageTsOfSheet);
154 $modifiedDataStructure['meta']['langDisable'] = isset($modifiedDataStructure['meta']['langDisable'])
155 ?
(bool
)$modifiedDataStructure['meta']['langDisable']
157 $modifiedDataStructure['meta']['langChildren'] = isset($modifiedDataStructure['meta']['langChildren'])
158 ?
(bool
)$modifiedDataStructure['meta']['langChildren']
161 $result['processedTca']['columns'][$fieldName]['config']['ds'] = $modifiedDataStructure;
167 * Removes fields from data structure the user has no access to
169 * @param array $result Result array
170 * @param string $fieldName Current handle field name
171 * @param string $flexIdentifier Determined identifier
172 * @return array Modified result
174 protected function removeExcludeFieldsFromDataStructure(array $result, $fieldName, $flexIdentifier) {
175 $dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
176 $backendUser = $this->getBackendUser();
177 if ($backendUser->isAdmin() ||
!isset($dataStructure['sheets']) ||
!is_array($dataStructure['sheets'])) {
181 $userNonExcludeFields = GeneralUtility
::trimExplode(',', $backendUser->groupData
['non_exclude_fields']);
182 $excludeFieldsPrefix = $result['tableName'] . ':' . $fieldName . ';' . $flexIdentifier . ';';
183 $nonExcludeFields = [];
184 foreach ($userNonExcludeFields as $userNonExcludeField) {
185 if (strpos($userNonExcludeField, $excludeFieldsPrefix) !== FALSE
) {
186 $exploded = explode(';', $userNonExcludeField);
187 $sheetName = $exploded[2];
188 $fieldName = $exploded[3];
189 $nonExcludeFields[$sheetName] = $fieldName;
193 foreach ($dataStructure['sheets'] as $sheetName => $sheetDefinition) {
194 if (!isset($sheetDefinition['ROOT']['el']) ||
!is_array($sheetDefinition['ROOT']['el'])) {
197 foreach ($sheetDefinition['ROOT']['el'] as $flexFieldName => $fieldDefinition) {
198 if (!empty($fieldDefinition['exclude']) && empty($nonExcludeFields[$sheetName])) {
199 unset($result['processedTca']['columns'][$fieldName]['config']['ds']['sheets'][$sheetName]['ROOT']['el'][$flexFieldName]);
208 * Handle "outer" flex data structure changes like language and sheet
209 * description. Does not change "TCA" or values of single elements
211 * @param array $result Result array
212 * @param string $fieldName Current handle field name
213 * @param array $pageTsConfig Given pageTsConfig of this flex form
214 * @return array Modified item array
216 protected function removeDisabledFieldsFromDataStructure(array $result, $fieldName, $pageTsConfig) {
217 $dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
218 if (!isset($dataStructure['sheets']) ||
!is_array($dataStructure['sheets'])) {
221 foreach ($dataStructure['sheets'] as $sheetName => $sheetDefinition) {
222 if (!isset($sheetDefinition['ROOT']['el']) ||
!is_array($sheetDefinition['ROOT']['el'])
223 ||
!isset($pageTsConfig[$sheetName . '.'])) {
226 foreach ($sheetDefinition['ROOT']['el'] as $flexFieldName => $fieldDefinition) {
227 if (!empty($pageTsConfig[$sheetName . '.'][$flexFieldName . '.']['disabled'])) {
228 unset($result['processedTca']['columns'][$fieldName]['config']['ds']['sheets'][$sheetName]['ROOT']['el'][$flexFieldName]);
237 * Remove data values in languages the user has no access to and add dummy entries
238 * for languages that are available but do not exist in data values yet.
240 * @param array $result Result array
241 * @param string $fieldName Current handle field name
242 * @return array Modified item array
244 protected function prepareLanguageHandlingInDataValues(array $result, $fieldName) {
245 $backendUser = $this->getBackendUser();
246 $dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
248 $langDisabled = $dataStructure['meta']['langDisable'];
249 $langChildren = $dataStructure['meta']['langChildren'];
251 // Existing page language overlays are only considered if options.checkPageLanguageOverlay is set in userTs
252 $checkPageLanguageOverlay = FALSE
;
253 if (isset($result['userTsConfig']['options.']) && is_array($result['userTsConfig']['options.'])
254 && array_key_exists('checkPageLanguageOverlay', $result['userTsConfig']['options.'])
256 $checkPageLanguageOverlay = (bool
)$result['userTsConfig']['options.']['checkPageLanguageOverlay'];
259 $systemLanguageRows = $result['systemLanguageRows'];
261 // Contains all language iso code that are valid and user has access to
262 $availableLanguageCodes = [];
263 $defaultCodeWasAdded = FALSE
;
264 foreach ($systemLanguageRows as $systemLanguageRow) {
265 $isoCode = $systemLanguageRow['iso'];
267 if ($langDisabled && $isoCode !== 'DEF') {
268 $isAvailable = FALSE
;
270 // @todo: Is it possible a user has no write access to default lang? If so, what to do?
271 if (!$backendUser->checkLanguageAccess($systemLanguageRow['uid'])) {
272 $isAvailable = FALSE
;
274 if ($checkPageLanguageOverlay && $systemLanguageRow['uid'] > 0) {
276 foreach ($result['pageLanguageOverlayRows'] as $overlayRow) {
277 if ((int)$overlayRow['sys_language_uid'] === (int)$systemLanguageRow['uid']) {
283 $isAvailable = FALSE
;
286 if ($isoCode === 'DEF' && $defaultCodeWasAdded) {
287 $isAvailable = FALSE
;
290 $availableLanguageCodes[] = $isoCode;
292 if ($isoCode === 'DEF') {
293 $defaultCodeWasAdded = TRUE
;
296 // Set the list of available languages in the data structure "meta" section to have it
297 // available for the render engine to iterate over it.
298 $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['availableLanguageCodes'] = $availableLanguageCodes;
300 if (!$langChildren) {
301 $allowedLanguageSheetKeys = [];
302 foreach ($availableLanguageCodes as $isoCode) {
303 $allowedLanguageSheetKeys['l' . $isoCode] = [];
305 $result = $this->setLanguageSheetsInDataValues($result, $fieldName, $allowedLanguageSheetKeys);
307 // With $langChildren = 0, values must only contain vDEF prefixed keys
308 $allowedValueLevelLanguageKeys = [];
309 $allowedValueLevelLanguageKeys['vDEF'] = [];
310 $allowedValueLevelLanguageKeys['vDEF.vDEFbase'] = [];
311 // A richtext special
312 $allowedValueLevelLanguageKeys['_TRANSFORM_vDEF.vDEFbase'] = [];
313 $result = $this->setLanguageValueLevelValues($result, $fieldName, $allowedValueLevelLanguageKeys);
315 // langChildren is set - only lDEF as sheet language is allowed, but more fields on value field level
316 $allowedLanguageSheetKeys = [
319 $result = $this->setLanguageSheetsInDataValues($result, $fieldName, $allowedLanguageSheetKeys);
321 $allowedValueLevelLanguageKeys = [];
322 foreach ($availableLanguageCodes as $isoCode) {
323 $allowedValueLevelLanguageKeys['v' . $isoCode] = [];
324 $allowedValueLevelLanguageKeys['v' . $isoCode . '.vDEFbase'] = [];
325 $allowedValueLevelLanguageKeys['_TRANSFORM_v' . $isoCode . '.vDEFbase'] = [];
327 $result = $this->setLanguageValueLevelValues($result, $fieldName, $allowedValueLevelLanguageKeys);
334 * Feed single flex field and data to FlexFormSegment FormData compiler and merge result.
335 * This one is nasty. Goal is to have processed TCA stuff in DS and also have validated / processed data values.
337 * Three main parts in this method:
338 * * Process values of existing section container for default values
339 * * Process values and TCA of possible section container and create a default value row for each
340 * * Process TCA of "normal" fields and have default values in data ['templateRows']['containerName'] parallel to section ['el']
342 * @param array $result Result array
343 * @param string $fieldName Current handle field name
344 * @param array $pageTsConfig Given pageTsConfig of this flex form
345 * @return array Modified item array
347 protected function modifyDataStructureAndDataValuesByFlexFormSegmentGroup(array $result, $fieldName, $pageTsConfig) {
348 $dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
349 $dataValues = $result['databaseRow'][$fieldName];
350 $tableName = $result['tableName'];
352 $availableLanguageCodes = $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['availableLanguageCodes'];
353 if ($dataStructure['meta']['langChildren']) {
354 $languagesOnSheetLevel = [ 'DEF' ];
355 $languagesOnElementLevel = $availableLanguageCodes;
357 $languagesOnSheetLevel = $availableLanguageCodes;
358 $languagesOnElementLevel = [ 'DEF' ];
361 $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['languagesOnSheetLevel'] = $languagesOnSheetLevel;
362 $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['languagesOnElement'] = $languagesOnElementLevel;
364 if (!isset($dataStructure['sheets']) ||
!is_array($dataStructure['sheets'])) {
368 /** @var FlexFormSegment $formDataGroup */
369 $formDataGroup = GeneralUtility
::makeInstance(FlexFormSegment
::class);
370 /** @var FormDataCompiler $formDataCompiler */
371 $formDataCompiler = GeneralUtility
::makeInstance(FormDataCompiler
::class, $formDataGroup);
373 foreach ($dataStructure['sheets'] as $dataStructureSheetName => $dataStructureSheetDefinition) {
374 if (!isset($dataStructureSheetDefinition['ROOT']['el']) ||
!is_array($dataStructureSheetDefinition['ROOT']['el'])) {
377 $dataStructureSheetElements = $dataStructureSheetDefinition['ROOT']['el'];
379 // Prepare pageTsConfig of this sheet
380 $pageTsConfigMerged['TCEFORM.'][$tableName . '.'] = [];
381 if (isset($pageTsConfig[$dataStructureSheetName . '.']) && is_array($pageTsConfig[$dataStructureSheetName . '.'])) {
382 $pageTsConfigMerged['TCEFORM.'][$tableName . '.'] = $pageTsConfig[$dataStructureSheetName . '.'];
385 foreach ($languagesOnSheetLevel as $isoSheetLevel) {
386 $langSheetLevel = 'l' . $isoSheetLevel;
387 foreach ($dataStructureSheetElements as $dataStructureSheetElementName => $dataStructureSheetElementDefinition) {
388 if (isset($dataStructureSheetElementDefinition['type']) && $dataStructureSheetElementDefinition['type'] === 'array'
389 && isset($dataStructureSheetElementDefinition['section']) && $dataStructureSheetElementDefinition['section'] === '1'
393 // Existing section container elements
394 if (isset($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'])
395 && is_array($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'])
397 $containerArray = $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'];
398 foreach ($containerArray as $aContainerNumber => $aContainerArray) {
399 if (is_array($aContainerArray)) {
400 foreach ($aContainerArray as $aContainerName => $aContainerElementArray) {
401 if ($aContainerName === '_TOGGLE') {
402 // Don't handle internal toggle state field
405 if (!isset($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName])) {
406 // Container not defined in ds
409 foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName]['el'] as $singleFieldName => $singleFieldConfiguration) {
410 // $singleFieldValueArray = ['data']['sSections']['lDEF']['section_1']['el']['1']['container_1']['el']['element_1']
411 $singleFieldValueArray = [];
412 if (isset($aContainerElementArray['el'][$singleFieldName])
413 && is_array($aContainerElementArray['el'][$singleFieldName])
415 $singleFieldValueArray = $aContainerElementArray['el'][$singleFieldName];
417 foreach ($languagesOnElementLevel as $isoElementLevel) {
418 $langElementLevel = 'v' . $isoElementLevel;
420 'uid' => $result['databaseRow']['uid'],
423 if (array_key_exists($langElementLevel, $singleFieldValueArray)) {
425 $valueArray[$singleFieldName] = $singleFieldValueArray[$langElementLevel];
427 $inputToFlexFormSegment = [
428 'tableName' => $result['tableName'],
429 'command' => $command,
430 // It is currently not possible to have pageTsConfig for section container
431 'pageTsConfigMerged' => [],
432 'databaseRow' => $valueArray,
433 'vanillaTableTca' => [
436 $singleFieldName => $singleFieldConfiguration,
442 $singleFieldName => $singleFieldConfiguration,
446 $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
447 // Set data value result
448 if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
449 $result['databaseRow'][$fieldName]
450 ['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el']
451 [$aContainerNumber][$aContainerName]['el']
452 [$singleFieldName][$langElementLevel]
453 = $flexSegmentResult['databaseRow'][$singleFieldName];
455 // Set TCA structure result, actually, this call *might* be obsolete since the "dummy"
456 // handling below will set it again.
457 $result['processedTca']['columns'][$fieldName]['config']['ds']
458 ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
459 [$aContainerName]['el'][$singleFieldName]
460 = $flexSegmentResult['processedTca']['columns'][$singleFieldName];
466 } // End of existing data value handling
468 // Prepare "fresh" row for every possible container
469 if (isset($dataStructureSheetElements[$dataStructureSheetElementName]['el']) && is_array($dataStructureSheetElements[$dataStructureSheetElementName]['el'])) {
470 foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'] as $possibleContainerName => $possibleContainerConfiguration) {
471 if (isset($possibleContainerConfiguration['el']) && is_array($possibleContainerConfiguration['el'])) {
472 // Initialize result data array templateRows
473 $result['databaseRow'][$fieldName]
474 ['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['templateRows']
475 [$possibleContainerName]['el']
477 foreach ($possibleContainerConfiguration['el'] as $singleFieldName => $singleFieldConfiguration) {
478 foreach ($languagesOnElementLevel as $isoElementLevel) {
479 $langElementLevel = 'v' . $isoElementLevel;
480 $inputToFlexFormSegment = [
481 'tableName' => $result['tableName'],
483 'pageTsConfigMerged' => [],
485 'uid' => $result['databaseRow']['uid'],
487 'vanillaTableTca' => [
490 $singleFieldName => $singleFieldConfiguration,
496 $singleFieldName => $singleFieldConfiguration,
500 $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
501 if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
502 $result['databaseRow'][$fieldName]
503 ['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['templateRows']
504 [$possibleContainerName]['el'][$singleFieldName][$langElementLevel]
505 = $flexSegmentResult['databaseRow'][$singleFieldName];
507 $result['processedTca']['columns'][$fieldName]['config']['ds']
508 ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
509 [$possibleContainerName]['el'][$singleFieldName]
510 = $flexSegmentResult['processedTca']['columns'][$singleFieldName];
515 } // End of preparation for each possible container
517 // type without section is not ok
518 } elseif (isset($dataStructureSheetElementDefinition['type']) ||
isset($dataStructureSheetElementDefinition['section'])) {
519 throw new \
UnexpectedValueException(
520 'Broken data structure on field name ' . $fieldName . '. section without type or vice versa is not allowed',
524 // A "normal" TCA element
526 foreach ($languagesOnElementLevel as $isoElementLevel) {
527 $langElementLevel = 'v' . $isoElementLevel;
529 // uid of "parent" is given down for inline elements to resolve correctly
530 'uid' => $result['databaseRow']['uid'],
533 if (isset($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName])
534 && array_key_exists($langElementLevel, $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName])
537 $valueArray[$dataStructureSheetElementName] = $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName][$langElementLevel];
539 $inputToFlexFormSegment = [
540 // tablename of "parent" is given down for inline elements to resolve correctly
541 'tableName' => $result['tableName'],
542 'command' => $command,
543 'pageTsConfigMerged' => $pageTsConfigMerged,
544 'databaseRow' => $valueArray,
545 'vanillaTableTca' => [
548 $dataStructureSheetElementName => $dataStructureSheetElementDefinition,
554 $dataStructureSheetElementName => $dataStructureSheetElementDefinition,
558 $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
559 // Set data value result
560 if (array_key_exists($dataStructureSheetElementName, $flexSegmentResult['databaseRow'])) {
561 $result['databaseRow'][$fieldName]
562 ['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName][$langElementLevel]
563 = $flexSegmentResult['databaseRow'][$dataStructureSheetElementName];
565 // Set TCA structure result
566 $result['processedTca']['columns'][$fieldName]['config']['ds']
567 ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]
568 = $flexSegmentResult['processedTca']['columns'][$dataStructureSheetElementName];
570 } // End of single element handling
580 * Modify data structure of a single "sheet"
581 * Sets "secondary" data like sheet names and so on, but does NOT modify single elements
583 * @param array $dataStructure Given data structure
584 * @param array $pageTsOfSheet Page Ts config of given field
585 * @return array Modified data structure
587 protected function modifySingleSheetInformation(array $dataStructure, array $pageTsOfSheet) {
588 // Return if no elements defined
589 if (!isset($dataStructure['ROOT']['el']) ||
!is_array($dataStructure['ROOT']['el'])) {
590 return $dataStructure;
593 // Rename sheet (tab)
594 if (!empty($pageTsOfSheet['sheetTitle'])) {
595 $dataStructure['ROOT']['sheetTitle'] = $pageTsOfSheet['sheetTitle'];
597 // Set sheet description (tab)
598 if (!empty($pageTsOfSheet['sheetDescription'])) {
599 $dataStructure['ROOT']['sheetDescription'] = $pageTsOfSheet['sheetDescription'];
601 // Set sheet short description (tab)
602 if (!empty($pageTsOfSheet['sheetShortDescr'])) {
603 $dataStructure['ROOT']['sheetShortDescr'] = $pageTsOfSheet['sheetShortDescr'];
606 return $dataStructure;
610 * Add new sheet languages not yet in data values and remove invalid ones
612 * databaseRow['aFlex']['data']['sDEF'] = array('lDEF', 'lNotAllowed');
613 * allowedLanguageKeys = array('lDEF', 'lNEW')
614 * -> databaseRow['aFlex']['data']['sDEF'] = array('lDEF', 'lNEW');
616 * @param array $result Result array
617 * @param string $fieldName Current handle field name
618 * @param array $allowedKeys List of allowed keys
619 * @return array Modified result
621 protected function setLanguageSheetsInDataValues(array $result, $fieldName, array $allowedKeys) {
623 if (isset($result['databaseRow'][$fieldName]['data']) && is_array($result['databaseRow'][$fieldName]['data'])) {
624 $valueArray = $result['databaseRow'][$fieldName]['data'];
626 foreach ($valueArray as $sheetName => $sheetLanguages) {
627 // Add iso code with empty array if it does not yet exist in data
628 // and remove codes from data that do not exist in $allowed
629 $result['databaseRow'][$fieldName]['data'][$sheetName]
630 = array_intersect_key(array_merge($allowedKeys, $sheetLanguages), $allowedKeys);
636 * Remove invalid keys from data value array the user has no access to
637 * or that were removed or similar to prevent any rendering of this stuff
639 * Handles this for "normal" fields and also for section container element values.
641 * @param array $result Result array
642 * @param string $fieldName Current handle field name
643 * @param array $allowedKeys List of allowed keys
644 * @return array Modified result
646 protected function setLanguageValueLevelValues(array $result, $fieldName, $allowedKeys) {
648 if (isset($result['databaseRow'][$fieldName]['data']) && is_array($result['databaseRow'][$fieldName]['data'])) {
649 $valueArray = $result['databaseRow'][$fieldName]['data'];
651 foreach ($valueArray as $sheetName => $sheetLanguages) {
652 if (!is_array($sheetLanguages)) {
655 foreach ($sheetLanguages as $languageName => $languageFields) {
656 if (!is_array($languageFields)) {
659 foreach ($languageFields as $flexFieldName => $fieldValues) {
660 if (!is_array($fieldValues)) {
663 $allowedSingleValues = [];
664 foreach ($fieldValues as $fieldValueName => $fieldValueValue) {
665 if (is_array($fieldValueValue) && $fieldValueName === 'el') {
666 // A section container
667 foreach ($fieldValueValue as $sectionNumber => $sectionElementArray) {
668 if (is_array($sectionElementArray)) {
669 $allowedSingleValues['el'][$sectionNumber] = [];
670 foreach ($sectionElementArray as $sectionElementName => $containerElementArray) {
671 if (isset($containerElementArray['el']) && is_array($containerElementArray['el']) && !empty($containerElementArray['el'])) {
672 foreach ($containerElementArray['el'] as $aContainerElementName => $aContainerElementValues) {
673 if (is_array($aContainerElementValues)) {
674 foreach ($aContainerElementValues as $aContainerElementValueKey => $aContainerElementValueValue) {
675 if (array_key_exists($aContainerElementValueKey, $allowedKeys)) {
676 $allowedSingleValues['el'][$sectionNumber][$sectionElementName]
677 ['el'][$aContainerElementName][$aContainerElementValueKey] = $aContainerElementValueValue;
681 $allowedSingleValues['el'][$sectionNumber][$sectionElementName]['el']
682 [$aContainerElementName] = $aContainerElementValues;
686 $allowedSingleValues['el'][$sectionNumber][$sectionElementName] = $containerElementArray;
690 $allowedSingleValues = $sectionElementArray;
694 // "normal" value field
695 if (array_key_exists($fieldValueName, $allowedKeys)) {
696 $allowedSingleValues[$fieldValueName] = $fieldValueValue;
700 $result['databaseRow'][$fieldName]['data'][$sheetName][$languageName][$flexFieldName] = $allowedSingleValues;
708 * @return BackendUserAuthentication
710 protected function getBackendUser() {
711 return $GLOBALS['BE_USER'];