b199ae3450e2073fa910779b0e426bfcc6ff3c67
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / FormDataProvider / TcaFlexProcess.php
1 <?php
2 namespace TYPO3\CMS\Backend\Form\FormDataProvider;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
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.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
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;
22
23 /**
24 * Process data structures and data values, calculate defaults.
25 *
26 * This is typically the last provider, executed after TcaFlexPrepare
27 */
28 class TcaFlexProcess implements FormDataProviderInterface
29 {
30 /**
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.
36 *
37 * @param array $result
38 * @return array
39 */
40 public function addData(array $result)
41 {
42 foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
43 if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'flex') {
44 continue;
45 }
46
47 $flexIdentifier = $this->getFlexIdentifier($result, $fieldName);
48 $pageTsConfigOfFlex = $this->getPageTsOfFlex($result, $fieldName, $flexIdentifier);
49 $result = $this->modifyOuterDataStructure($result, $fieldName, $pageTsConfigOfFlex);
50 $result = $this->removeExcludeFieldsFromDataStructure($result, $fieldName, $flexIdentifier);
51 $result = $this->removeDisabledFieldsFromDataStructure($result, $fieldName, $pageTsConfigOfFlex);
52 $result = $this->modifyDataStructureAndDataValuesByFlexFormSegmentGroup($result, $fieldName, $pageTsConfigOfFlex);
53 $result = $this->addDataStructurePointersToMetaData($result, $fieldName);
54 }
55
56 return $result;
57 }
58
59 /**
60 * Take care of ds_pointerField and friends to determine the correct sub array within
61 * TCA config ds.
62 *
63 * Gets extension identifier. Use second pointer field if it's value is not empty, "list" or "*",
64 * else it must be a plugin and first one will be used.
65 * This code basically determines the sub key of ds field:
66 * config = array(
67 * ds => array(
68 * 'aFlexConfig' => '<flexXml ...
69 * ^^^^^^^^^^^
70 * $flexformIdentifier contains "aFlexConfig" after this operation.
71 *
72 * @todo: This method is only implemented half. It basically should do all the
73 * @todo: pointer handling that is done within BackendUtility::getFlexFormDS() to $srcPointer.
74 *
75 * @param array $result Result array
76 * @param string $fieldName Current handle field name
77 * @return string Pointer
78 */
79 protected function getFlexIdentifier(array $result, $fieldName)
80 {
81 // @todo: Current implementation with the "list_type, CType" fallback is rather limited and customized for
82 // @todo: tt_content, also it forces a ds_pointerField to be defined and a casual "default" sub array does not work
83 $pointerFields = !empty($result['processedTca']['columns'][$fieldName]['config']['ds_pointerField'])
84 ? $result['processedTca']['columns'][$fieldName]['config']['ds_pointerField']
85 : 'list_type,CType';
86 $pointerFields = GeneralUtility::trimExplode(',', $pointerFields);
87 $flexformIdentifier = !empty($result['databaseRow'][$pointerFields[0]]) ? $result['databaseRow'][$pointerFields[0]] : '';
88 if (!empty($result['databaseRow'][$pointerFields[1]])
89 && $result['databaseRow'][$pointerFields[1]] !== 'list'
90 && $result['databaseRow'][$pointerFields[1]] !== '*'
91 ) {
92 $flexformIdentifier = $result['databaseRow'][$pointerFields[1]];
93 }
94 if (empty($flexformIdentifier)) {
95 $flexformIdentifier = 'default';
96 }
97
98 return $flexformIdentifier;
99 }
100
101 /**
102 * Determine TCEFORM.aTable.aField.matchingIdentifier
103 *
104 * @param array $result Result array
105 * @param string $fieldName Handled field name
106 * @param string $flexIdentifier Determined identifier
107 * @return array PageTsConfig for this flex
108 */
109 protected function getPageTsOfFlex(array $result, $fieldName, $flexIdentifier)
110 {
111 $table = $result['tableName'];
112 $pageTs = [];
113 if (!empty($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'])
114 && is_array($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'])) {
115 $pageTs = $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'];
116 }
117 return $pageTs;
118 }
119
120 /**
121 * Handle "outer" flex data structure changes like language and sheet
122 * description. Does not change "TCA" or values of single elements
123 *
124 * @param array $result Result array
125 * @param string $fieldName Current handle field name
126 * @param array $pageTsConfig Given pageTsConfig of this flex form
127 * @return array Modified item array
128 */
129 protected function modifyOuterDataStructure(array $result, $fieldName, $pageTsConfig)
130 {
131 $modifiedDataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
132
133 if (isset($modifiedDataStructure['sheets']) && is_array($modifiedDataStructure['sheets'])) {
134 // Handling multiple sheets
135 foreach ($modifiedDataStructure['sheets'] as $sheetName => $sheetStructure) {
136 if (isset($pageTsConfig[$sheetName . '.']) && is_array($pageTsConfig[$sheetName . '.'])) {
137 $pageTsOfSheet = $pageTsConfig[$sheetName . '.'];
138
139 // Remove whole sheet if disabled
140 if (!empty($pageTsOfSheet['disabled'])) {
141 unset($modifiedDataStructure['sheets'][$sheetName]);
142 continue;
143 }
144
145 // sheetTitle, sheetDescription, sheetShortDescr
146 $modifiedDataStructure['sheets'][$sheetName] = $this->modifySingleSheetInformation($sheetStructure, $pageTsOfSheet);
147 }
148 }
149 }
150
151 $result['processedTca']['columns'][$fieldName]['config']['ds'] = $modifiedDataStructure;
152
153 return $result;
154 }
155
156 /**
157 * Removes fields from data structure the user has no access to
158 *
159 * @param array $result Result array
160 * @param string $fieldName Current handle field name
161 * @param string $flexIdentifier Determined identifier
162 * @return array Modified result
163 */
164 protected function removeExcludeFieldsFromDataStructure(array $result, $fieldName, $flexIdentifier)
165 {
166 $dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
167 $backendUser = $this->getBackendUser();
168 if ($backendUser->isAdmin() || !isset($dataStructure['sheets']) || !is_array($dataStructure['sheets'])) {
169 return $result;
170 }
171
172 $userNonExcludeFields = GeneralUtility::trimExplode(',', $backendUser->groupData['non_exclude_fields']);
173 $excludeFieldsPrefix = $result['tableName'] . ':' . $fieldName . ';' . $flexIdentifier . ';';
174 $nonExcludeFields = [];
175 foreach ($userNonExcludeFields as $userNonExcludeField) {
176 if (strpos($userNonExcludeField, $excludeFieldsPrefix) !== false) {
177 $exploded = explode(';', $userNonExcludeField);
178 $sheetName = $exploded[2];
179 $allowedFlexFieldName = $exploded[3];
180 $nonExcludeFields[$sheetName][$allowedFlexFieldName] = true;
181 }
182 }
183 foreach ($dataStructure['sheets'] as $sheetName => $sheetDefinition) {
184 if (!isset($sheetDefinition['ROOT']['el']) || !is_array($sheetDefinition['ROOT']['el'])) {
185 continue;
186 }
187 foreach ($sheetDefinition['ROOT']['el'] as $flexFieldName => $fieldDefinition) {
188 if (!empty($fieldDefinition['exclude']) && !isset($nonExcludeFields[$sheetName][$flexFieldName])) {
189 unset($result['processedTca']['columns'][$fieldName]['config']['ds']['sheets'][$sheetName]['ROOT']['el'][$flexFieldName]);
190 }
191 }
192 }
193
194 return $result;
195 }
196
197 /**
198 * Remove fields from data structure that are disabled in pageTsConfig.
199 *
200 * @param array $result Result array
201 * @param string $fieldName Current handle field name
202 * @param array $pageTsConfig Given pageTsConfig of this flex form
203 * @return array Modified item array
204 */
205 protected function removeDisabledFieldsFromDataStructure(array $result, $fieldName, $pageTsConfig)
206 {
207 $dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
208 if (!isset($dataStructure['sheets']) || !is_array($dataStructure['sheets'])) {
209 return $result;
210 }
211 foreach ($dataStructure['sheets'] as $sheetName => $sheetDefinition) {
212 if (!isset($sheetDefinition['ROOT']['el']) || !is_array($sheetDefinition['ROOT']['el'])
213 || !isset($pageTsConfig[$sheetName . '.'])) {
214 continue;
215 }
216 foreach ($sheetDefinition['ROOT']['el'] as $flexFieldName => $fieldDefinition) {
217 if (!empty($pageTsConfig[$sheetName . '.'][$flexFieldName . '.']['disabled'])) {
218 unset($result['processedTca']['columns'][$fieldName]['config']['ds']['sheets'][$sheetName]['ROOT']['el'][$flexFieldName]);
219 }
220 }
221 }
222 return $result;
223 }
224
225 /**
226 * Feed single flex field and data to FlexFormSegment FormData compiler and merge result.
227 * This one is nasty. Goal is to have processed TCA stuff in DS and also have validated / processed data values.
228 *
229 * Three main parts in this method:
230 * * Process values of existing section container for default values
231 * * Process values and TCA of possible section container and create a default value row for each
232 * * Process TCA of "normal" fields and have default values in data ['templateRows']['containerName'] parallel to section ['el']
233 *
234 * @param array $result Result array
235 * @param string $fieldName Current handle field name
236 * @param array $pageTsConfig Given pageTsConfig of this flex form
237 * @return array Modified item array
238 */
239 protected function modifyDataStructureAndDataValuesByFlexFormSegmentGroup(array $result, $fieldName, $pageTsConfig)
240 {
241 $dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
242 $dataValues = $result['databaseRow'][$fieldName];
243 $tableName = $result['tableName'];
244
245 if (!isset($dataStructure['sheets']) || !is_array($dataStructure['sheets'])) {
246 return $result;
247 }
248
249 /** @var FlexFormSegment $formDataGroup */
250 $formDataGroup = GeneralUtility::makeInstance(FlexFormSegment::class);
251 /** @var FormDataCompiler $formDataCompiler */
252 $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
253
254 foreach ($dataStructure['sheets'] as $dataStructureSheetName => $dataStructureSheetDefinition) {
255 if (!isset($dataStructureSheetDefinition['ROOT']['el']) || !is_array($dataStructureSheetDefinition['ROOT']['el'])) {
256 continue;
257 }
258 $dataStructureSheetElements = $dataStructureSheetDefinition['ROOT']['el'];
259
260 // Prepare pageTsConfig of this sheet
261 $pageTsConfig['TCEFORM.'][$tableName . '.'] = [];
262 if (isset($pageTsConfig[$dataStructureSheetName . '.']) && is_array($pageTsConfig[$dataStructureSheetName . '.'])) {
263 $pageTsConfig['TCEFORM.'][$tableName . '.'] = $pageTsConfig[$dataStructureSheetName . '.'];
264 }
265
266 $tcaNewColumns = [];
267 $tcaEditColumns = [];
268 $tcaValueArray = [
269 'uid' => $result['databaseRow']['uid'],
270 ];
271 foreach ($dataStructureSheetElements as $dataStructureSheetElementName => $dataStructureSheetElementDefinition) {
272 if (isset($dataStructureSheetElementDefinition['type']) && $dataStructureSheetElementDefinition['type'] === 'array'
273 && isset($dataStructureSheetElementDefinition['section']) && (string)$dataStructureSheetElementDefinition['section'] === '1'
274 ) {
275 // A section
276
277 // Existing section container elements
278 if (isset($dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['el'])
279 && is_array($dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['el'])
280 ) {
281 $containerArray = $dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['el'];
282 foreach ($containerArray as $aContainerNumber => $aContainerArray) {
283 if (is_array($aContainerArray)) {
284 foreach ($aContainerArray as $aContainerName => $aContainerElementArray) {
285 if ($aContainerName === '_TOGGLE') {
286 // Don't handle internal toggle state field
287 continue;
288 }
289 if (!isset($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName])) {
290 // Container not defined in ds
291 continue;
292 }
293
294 $newColumns = [];
295 $editColumns = [];
296 $valueArray = [
297 'uid' => $result['databaseRow']['uid'],
298 ];
299 foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName]['el'] as $singleFieldName => $singleFieldConfiguration) {
300 // $singleFieldValueArray = ['data']['sSections']['lDEF']['section_1']['el']['1']['container_1']['el']['element_1']
301 $singleFieldValueArray = [];
302 if (isset($aContainerElementArray['el'][$singleFieldName])
303 && is_array($aContainerElementArray['el'][$singleFieldName])
304 ) {
305 $singleFieldValueArray = $aContainerElementArray['el'][$singleFieldName];
306 }
307
308 if (array_key_exists('vDEF', $singleFieldValueArray)) {
309 $editColumns[$singleFieldName] = $singleFieldConfiguration;
310 $valueArray[$singleFieldName] = $singleFieldValueArray['vDEF'];
311 } else {
312 $newColumns[$singleFieldName] = $singleFieldConfiguration;
313 }
314 }
315
316 $inputToFlexFormSegment = [
317 'tableName' => $result['tableName'],
318 'command' => '',
319 // It is currently not possible to have pageTsConfig for section container
320 'pageTsConfig' => [],
321 'databaseRow' => $valueArray,
322 'processedTca' => [
323 'ctrl' => [],
324 'columns' => [],
325 ],
326 'flexParentDatabaseRow' => $result['databaseRow'],
327 ];
328
329 if (!empty($newColumns)) {
330 $inputToFlexFormSegment['command'] = 'new';
331 $inputToFlexFormSegment['processedTca']['columns'] = $newColumns;
332 $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
333
334 foreach ($newColumns as $singleFieldName => $_) {
335 // Set data value result
336 if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
337 $result['databaseRow'][$fieldName]
338 ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]
339 ['el'][$aContainerNumber][$aContainerName]['el'][$singleFieldName]['vDEF'] =
340 $flexSegmentResult['databaseRow'][$singleFieldName];
341 }
342 // Set TCA structure result, actually, this call *might* be obsolete since the "dummy"
343 // handling below will set it again.
344 $result['processedTca']['columns'][$fieldName]['config']['ds']
345 ['sheets'][$dataStructureSheetName]['ROOT']['el']
346 [$dataStructureSheetElementName]['el'][$aContainerName]['el'][$singleFieldName] =
347 $flexSegmentResult['processedTca']['columns'][$singleFieldName];
348 }
349 }
350
351 if (!empty($editColumns)) {
352 $inputToFlexFormSegment['command'] = 'edit';
353 $inputToFlexFormSegment['processedTca']['columns'] = $editColumns;
354 $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
355
356 foreach ($editColumns as $singleFieldName => $_) {
357 // Set data value result
358 if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
359 $result['databaseRow'][$fieldName]
360 ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]
361 ['el'][$aContainerNumber][$aContainerName]['el'][$singleFieldName]['vDEF'] =
362 $flexSegmentResult['databaseRow'][$singleFieldName];
363 }
364 // Set TCA structure result, actually, this call *might* be obsolete since the "dummy"
365 // handling below will set it again.
366 $result['processedTca']['columns'][$fieldName]['config']['ds']
367 ['sheets'][$dataStructureSheetName]['ROOT']['el']
368 [$dataStructureSheetElementName]['el'][$aContainerName]['el'][$singleFieldName] =
369 $flexSegmentResult['processedTca']['columns'][$singleFieldName];
370 }
371 }
372 }
373 }
374 }
375 // End of existing data value handling
376 } else {
377 // Force the section to be an empty array if there are no existing containers
378 $result['databaseRow'][$fieldName]
379 ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['el'] = [];
380 }
381
382 // Prepare "fresh" row for every possible container
383 if (isset($dataStructureSheetElements[$dataStructureSheetElementName]['el']) && is_array($dataStructureSheetElements[$dataStructureSheetElementName]['el'])) {
384 foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'] as $possibleContainerName => $possibleContainerConfiguration) {
385 if (isset($possibleContainerConfiguration['el']) && is_array($possibleContainerConfiguration['el'])) {
386 // Initialize result data array templateRows
387 $result['databaseRow'][$fieldName]
388 ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['templateRows']
389 [$possibleContainerName]['el']
390 = [];
391 foreach ($possibleContainerConfiguration['el'] as $singleFieldName => $singleFieldConfiguration) {
392 $inputToFlexFormSegment = [
393 'tableName' => $result['tableName'],
394 'command' => 'new',
395 'pageTsConfig' => [],
396 'databaseRow' => [
397 'uid' => $result['databaseRow']['uid'],
398 ],
399 'processedTca' => [
400 'ctrl' => [],
401 'columns' => [
402 $singleFieldName => $singleFieldConfiguration,
403 ],
404 ],
405 'flexParentDatabaseRow' => $result['databaseRow'],
406 ];
407 $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
408 if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
409 $result['databaseRow'][$fieldName]
410 ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['templateRows']
411 [$possibleContainerName]['el'][$singleFieldName]['vDEF']
412 = $flexSegmentResult['databaseRow'][$singleFieldName];
413 }
414 $result['processedTca']['columns'][$fieldName]['config']['ds']
415 ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
416 [$possibleContainerName]['el'][$singleFieldName]
417 = $flexSegmentResult['processedTca']['columns'][$singleFieldName];
418 }
419 }
420 }
421 } // End of preparation for each possible container
422
423 // type without section is not ok
424 } elseif (isset($dataStructureSheetElementDefinition['type']) || isset($dataStructureSheetElementDefinition['section'])) {
425 throw new \UnexpectedValueException(
426 'Broken data structure on field name ' . $fieldName . '. section without type or vice versa is not allowed',
427 1440685208
428 );
429
430 // A "normal" TCA element
431 } else {
432 if (isset($dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName])
433 && array_key_exists('vDEF', $dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName])
434 ) {
435 $tcaEditColumns[$dataStructureSheetElementName] = $dataStructureSheetElementDefinition;
436 $tcaValueArray[$dataStructureSheetElementName] = $dataValues['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['vDEF'];
437 } else {
438 $tcaNewColumns[$dataStructureSheetElementName] = $dataStructureSheetElementDefinition;
439 }
440 } // End of single element handling
441 }
442
443 // process the tca columns for the current sheet
444 $inputToFlexFormSegment = [
445 // tablename of "parent" is given down for inline elements to resolve correctly
446 'tableName' => $result['tableName'],
447 'command' => '',
448 'pageTsConfig' => $pageTsConfig,
449 'databaseRow' => $tcaValueArray,
450 'processedTca' => [
451 'ctrl' => [],
452 'columns' => [],
453 ],
454 'flexParentDatabaseRow' => $result['databaseRow'],
455 ];
456
457 if (!empty($tcaNewColumns)) {
458 $inputToFlexFormSegment['command'] = 'new';
459 $inputToFlexFormSegment['processedTca']['columns'] = $tcaNewColumns;
460 $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
461
462 foreach ($tcaNewColumns as $dataStructureSheetElementName => $_) {
463 // Set data value result
464 if (array_key_exists($dataStructureSheetElementName, $flexSegmentResult['databaseRow'])) {
465 $result['databaseRow'][$fieldName]
466 ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['vDEF']
467 = $flexSegmentResult['databaseRow'][$dataStructureSheetElementName];
468 }
469 // Set TCA structure result
470 $result['processedTca']['columns'][$fieldName]['config']['ds']
471 ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]
472 = $flexSegmentResult['processedTca']['columns'][$dataStructureSheetElementName];
473 }
474 }
475
476 if (!empty($tcaEditColumns)) {
477 $inputToFlexFormSegment['command'] = 'edit';
478 $inputToFlexFormSegment['processedTca']['columns'] = $tcaEditColumns;
479 $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
480
481 foreach ($tcaEditColumns as $dataStructureSheetElementName => $_) {
482 // Set data value result
483 if (array_key_exists($dataStructureSheetElementName, $flexSegmentResult['databaseRow'])) {
484 $result['databaseRow'][$fieldName]
485 ['data'][$dataStructureSheetName]['lDEF'][$dataStructureSheetElementName]['vDEF']
486 = $flexSegmentResult['databaseRow'][$dataStructureSheetElementName];
487 }
488 // Set TCA structure result
489 $result['processedTca']['columns'][$fieldName]['config']['ds']
490 ['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]
491 = $flexSegmentResult['processedTca']['columns'][$dataStructureSheetElementName];
492 }
493 }
494 }
495
496 return $result;
497 }
498
499 /**
500 * Modify data structure of a single "sheet"
501 * Sets "secondary" data like sheet names and so on, but does NOT modify single elements
502 *
503 * @param array $dataStructure Given data structure
504 * @param array $pageTsOfSheet Page Ts config of given field
505 * @return array Modified data structure
506 */
507 protected function modifySingleSheetInformation(array $dataStructure, array $pageTsOfSheet)
508 {
509 // Return if no elements defined
510 if (!isset($dataStructure['ROOT']['el']) || !is_array($dataStructure['ROOT']['el'])) {
511 return $dataStructure;
512 }
513
514 // Rename sheet (tab)
515 if (!empty($pageTsOfSheet['sheetTitle'])) {
516 $dataStructure['ROOT']['sheetTitle'] = $pageTsOfSheet['sheetTitle'];
517 }
518 // Set sheet description (tab)
519 if (!empty($pageTsOfSheet['sheetDescription'])) {
520 $dataStructure['ROOT']['sheetDescription'] = $pageTsOfSheet['sheetDescription'];
521 }
522 // Set sheet short description (tab)
523 if (!empty($pageTsOfSheet['sheetShortDescr'])) {
524 $dataStructure['ROOT']['sheetShortDescr'] = $pageTsOfSheet['sheetShortDescr'];
525 }
526
527 return $dataStructure;
528 }
529
530 /**
531 * @return BackendUserAuthentication
532 */
533 protected function getBackendUser()
534 {
535 return $GLOBALS['BE_USER'];
536 }
537
538 /**
539 * Add fields and values used by ds_pointerField to the meta data array so they can be used in AJAX context during rendering.
540 *
541 * @todo: This method is a stopgap measure to get required information into the AJAX controller
542 *
543 * @param array $result Result array
544 * @param string $fieldName Current handle field name
545 * @return array
546 * @internal
547 */
548 protected function addDataStructurePointersToMetaData(array $result, $fieldName)
549 {
550 if (empty($result['processedTca']['columns'][$fieldName]['config']['ds_pointerField'])) {
551 return $result;
552 }
553
554 $pointerFields = GeneralUtility::trimExplode(
555 ',',
556 $result['processedTca']['columns'][$fieldName]['config']['ds_pointerField']
557 );
558 $dsPointers = [
559 $pointerFields[0] => !empty($result['databaseRow'][$pointerFields[0]]) ? $result['databaseRow'][$pointerFields[0]] : ''
560 ];
561
562 if (!empty($pointerFields[1])) {
563 $dsPointers[$pointerFields[1]] =
564 !empty($result['databaseRow'][$pointerFields[1]]) ? $result['databaseRow'][$pointerFields[1]] : '';
565 }
566 $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['dataStructurePointers'] = $dsPointers;
567 return $result;
568 }
569 }