‪TYPO3CMS  11.5
TcaInline.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
24 use TYPO3\CMS\Backend\Utility\BackendUtility;
33 
38 {
45  public function ‪addData(array $result)
46  {
47  $result = $this->‪addInlineFirstPid($result);
48 
49  foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
50  if (!$this->‪isInlineField($fieldConfig)) {
51  continue;
52  }
53  $result['processedTca']['columns'][$fieldName]['children'] = [];
54  if (!$this->‪isUserAllowedToModify($fieldConfig)) {
55  continue;
56  }
57  if ($result['inlineResolveExistingChildren']) {
58  $result = $this->‪resolveRelatedRecords($result, $fieldName);
59  $result = $this->‪addForeignSelectorAndUniquePossibleRecords($result, $fieldName);
60  }
61  }
62 
63  return $result;
64  }
65 
72  protected function ‪isInlineField($fieldConfig)
73  {
74  return !empty($fieldConfig['config']['type']) && $fieldConfig['config']['type'] === 'inline';
75  }
76 
83  protected function ‪isUserAllowedToModify($fieldConfig)
84  {
85  return $this->‪getBackendUser()->‪check('tables_modify', $fieldConfig['config']['foreign_table']);
86  }
87 
96  protected function ‪addInlineFirstPid(array $result)
97  {
98  if ($result['inlineFirstPid'] === null) {
99  $table = $result['tableName'];
100  $row = $result['databaseRow'];
101  // If the parent is a page, use the uid(!) of the (new?) page as pid for the child records:
102  if ($table === 'pages') {
103  $liveVersionId = BackendUtility::getLiveVersionIdOfRecord('pages', $row['uid']);
104  $pid = $liveVersionId ?? $row['uid'];
105  } elseif (($row['pid'] ?? 0) < 0) {
106  $prevRec = BackendUtility::getRecord($table, (int)abs($row['pid']));
107  $pid = $prevRec['pid'];
108  } else {
109  $pid = $row['pid'] ?? 0;
110  }
112  $pageRecord = BackendUtility::getRecord('pages', (int)$pid);
113  if (($pageRecord[‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'] ?? null] ?? 0) > 0) {
114  $pid = (int)$pageRecord[‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']];
115  }
116  } elseif (strpos($pid, 'NEW') !== 0) {
117  throw new \RuntimeException(
118  'inlineFirstPid should either be an integer or a "NEW..." string',
119  1521220142
120  );
121  }
122  $result['inlineFirstPid'] = $pid;
123  }
124  return $result;
125  }
126 
135  protected function ‪resolveRelatedRecordsOverlays(array $result, $fieldName)
136  {
137  $childTableName = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'];
138 
139  $connectedUidsOfLocalizedOverlay = [];
140  if ($result['command'] === 'edit') {
141  $connectedUidsOfLocalizedOverlay = $this->‪resolveConnectedRecordUids(
142  $result['processedTca']['columns'][$fieldName]['config'],
143  $result['tableName'],
144  $result['databaseRow']['uid'],
145  $result['databaseRow'][$fieldName]
146  );
147  }
148  $result['databaseRow'][$fieldName] = implode(',', $connectedUidsOfLocalizedOverlay);
149  $connectedUidsOfLocalizedOverlay = $this->‪getWorkspacedUids($connectedUidsOfLocalizedOverlay, $childTableName);
150  if ($result['inlineCompileExistingChildren']) {
151  $tableNameWithDefaultRecords = $result['tableName'];
152  $connectedUidsOfDefaultLanguageRecord = $this->‪resolveConnectedRecordUids(
153  $result['processedTca']['columns'][$fieldName]['config'],
154  $tableNameWithDefaultRecords,
155  $result['defaultLanguageRow']['uid'],
156  $result['defaultLanguageRow'][$fieldName]
157  );
158  $connectedUidsOfDefaultLanguageRecord = $this->‪getWorkspacedUids($connectedUidsOfDefaultLanguageRecord, $childTableName);
159 
160  $showPossible = $result['processedTca']['columns'][$fieldName]['config']['appearance']['showPossibleLocalizationRecords'];
161 
162  // Find which records are localized, which records are not localized and which are
163  // localized but miss default language record
164  $fieldNameWithDefaultLanguageUid = ‪$GLOBALS['TCA'][$childTableName]['ctrl']['transOrigPointerField'] ?? '';
165  foreach ($connectedUidsOfLocalizedOverlay as $localizedUid) {
166  try {
167  $localizedRecord = $this->‪getRecordFromDatabase($childTableName, $localizedUid);
168  } catch (‪DatabaseRecordException $e) {
169  // The child could not be compiled, probably it was deleted and a dangling mm record exists
170  $this->logger->warning(
171  $e->getMessage(),
172  [
173  'table' => $childTableName,
174  'uid' => $localizedUid,
175  'exception' => $e,
176  ]
177  );
178  continue;
179  }
180  if (isset($localizedRecord[$fieldNameWithDefaultLanguageUid])) {
181  $uidOfDefaultLanguageRecord = $localizedRecord[$fieldNameWithDefaultLanguageUid];
182  if (in_array($uidOfDefaultLanguageRecord, $connectedUidsOfDefaultLanguageRecord)) {
183  // This localized child has a default language record. Remove this record from list of default language records
184  $connectedUidsOfDefaultLanguageRecord = array_diff($connectedUidsOfDefaultLanguageRecord, [$uidOfDefaultLanguageRecord]);
185  }
186  }
187  // Compile localized record
188  $compiledChild = $this->‪compileChild($result, $fieldName, $localizedUid);
189  $result['processedTca']['columns'][$fieldName]['children'][] = $compiledChild;
190  }
191  if ($showPossible) {
192  foreach ($connectedUidsOfDefaultLanguageRecord as $defaultLanguageUid) {
193  // If there are still uids in $connectedUidsOfDefaultLanguageRecord, these are records that
194  // exist in default language, but are not localized yet. Compile and mark those
195  try {
196  $compiledChild = $this->‪compileChild($result, $fieldName, $defaultLanguageUid);
197  } catch (‪DatabaseRecordException $e) {
198  // The child could not be compiled, probably it was deleted and a dangling mm record exists
199  $this->logger->warning(
200  $e->getMessage(),
201  [
202  'table' => $childTableName,
203  'uid' => $defaultLanguageUid,
204  'exception' => $e,
205  ]
206  );
207  continue;
208  }
209  $compiledChild['isInlineDefaultLanguageRecordInLocalizedParentContext'] = true;
210  $result['processedTca']['columns'][$fieldName]['children'][] = $compiledChild;
211  }
212  }
213  }
214 
215  return $result;
216  }
217 
226  protected function ‪resolveRelatedRecords(array $result, $fieldName)
227  {
228  if ($result['defaultLanguageRow'] !== null) {
229  return $this->‪resolveRelatedRecordsOverlays($result, $fieldName);
230  }
231 
232  $childTableName = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'];
233  $connectedUidsOfDefaultLanguageRecord = $this->‪resolveConnectedRecordUids(
234  $result['processedTca']['columns'][$fieldName]['config'],
235  $result['tableName'],
236  $result['databaseRow']['uid'],
237  $result['databaseRow'][$fieldName]
238  );
239  $result['databaseRow'][$fieldName] = implode(',', $connectedUidsOfDefaultLanguageRecord);
240 
241  $connectedUidsOfDefaultLanguageRecord = $this->‪getWorkspacedUids($connectedUidsOfDefaultLanguageRecord, $childTableName);
242 
243  if ($result['inlineCompileExistingChildren']) {
244  foreach ($connectedUidsOfDefaultLanguageRecord as $uid) {
245  try {
246  $compiledChild = $this->‪compileChild($result, $fieldName, $uid);
247  $result['processedTca']['columns'][$fieldName]['children'][] = $compiledChild;
248  } catch (‪DatabaseRecordException $e) {
249  // Nothing to do here, missing child is just not being rendered.
250  }
251  }
252  }
253  return $result;
254  }
255 
265  protected function ‪addForeignSelectorAndUniquePossibleRecords(array $result, $fieldName)
266  {
267  if (!is_array($result['processedTca']['columns'][$fieldName]['config']['selectorOrUniqueConfiguration'] ?? null)) {
268  return $result;
269  }
270 
271  $selectorOrUniqueConfiguration = $result['processedTca']['columns'][$fieldName]['config']['selectorOrUniqueConfiguration'];
272  $foreignFieldName = $selectorOrUniqueConfiguration['fieldName'];
273  $selectorOrUniquePossibleRecords = [];
274 
275  if ($selectorOrUniqueConfiguration['config']['type'] === 'select') {
276  // Compile child table data for this field only
277  $selectDataInput = [
278  'tableName' => $result['processedTca']['columns'][$fieldName]['config']['foreign_table'],
279  'command' => 'new',
280  // Since there is no existing record that may have a type, it does not make sense to
281  // do extra handling of pageTsConfig merged here. Just provide "parent" pageTS as is
282  'pageTsConfig' => $result['pageTsConfig'],
283  'userTsConfig' => $result['userTsConfig'],
284  'databaseRow' => $result['databaseRow'],
285  'processedTca' => [
286  'ctrl' => [],
287  'columns' => [
288  $foreignFieldName => [
289  'config' => $selectorOrUniqueConfiguration['config'],
290  ],
291  ],
292  ],
293  'inlineExpandCollapseStateArray' => $result['inlineExpandCollapseStateArray'],
294  'site' => $result['site'],
295  ];
296  $formDataGroup = GeneralUtility::makeInstance(OnTheFly::class);
297  $formDataGroup->setProviderList([TcaSelectItems::class]);
298  $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
299  $compilerResult = $formDataCompiler->compile($selectDataInput);
300  $selectorOrUniquePossibleRecords = $compilerResult['processedTca']['columns'][$foreignFieldName]['config']['items'];
301  }
302 
303  $result['processedTca']['columns'][$fieldName]['config']['selectorOrUniquePossibleRecords'] = $selectorOrUniquePossibleRecords;
304 
305  return $result;
306  }
307 
316  protected function ‪compileChild(array $result, $parentFieldName, $childUid)
317  {
318  $parentConfig = $result['processedTca']['columns'][$parentFieldName]['config'];
319  $childTableName = $parentConfig['foreign_table'];
320 
321  $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
322  $inlineStackProcessor->initializeByGivenStructure($result['inlineStructure']);
323  $inlineTopMostParent = $inlineStackProcessor->getStructureLevel(0) ?: [];
324 
325  $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class);
326  $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
327  $formDataCompilerInput = [
328  'command' => 'edit',
329  'tableName' => $childTableName,
330  'vanillaUid' => (int)$childUid,
331  // Give incoming returnUrl down to children so they generate a returnUrl back to
332  // the originally opening record, also see "originalReturnUrl" in inline container
333  // and FormInlineAjaxController
334  'returnUrl' => $result['returnUrl'],
335  'isInlineChild' => true,
336  'inlineStructure' => $result['inlineStructure'],
337  'inlineExpandCollapseStateArray' => $result['inlineExpandCollapseStateArray'],
338  'inlineFirstPid' => $result['inlineFirstPid'],
339  'inlineParentConfig' => $parentConfig,
340 
341  // values of the current parent element
342  // it is always a string either an id or new...
343  'inlineParentUid' => $result['databaseRow']['uid'],
344  'inlineParentTableName' => $result['tableName'],
345  'inlineParentFieldName' => $parentFieldName,
346 
347  // values of the top most parent element set on first level and not overridden on following levels
348  'inlineTopMostParentUid' => $result['inlineTopMostParentUid'] ?: $inlineTopMostParent['uid'] ?? '',
349  'inlineTopMostParentTableName' => $result['inlineTopMostParentTableName'] ?: $inlineTopMostParent['table'] ?? '',
350  'inlineTopMostParentFieldName' => $result['inlineTopMostParentFieldName'] ?: $inlineTopMostParent['field'] ?? '',
351  ];
352 
353  // For foreign_selector with useCombination $mainChild is the mm record
354  // and $combinationChild is the child-child. For 1:n "normal" relations,
355  // $mainChild is just the normal child record and $combinationChild is empty.
356  $mainChild = $formDataCompiler->compile($formDataCompilerInput);
357  if (($parentConfig['foreign_selector'] ?? false) && ($parentConfig['appearance']['useCombination'] ?? false)) {
358  try {
359  $mainChild['combinationChild'] = $this->‪compileChildChild($mainChild, $parentConfig);
360  } catch (‪DatabaseRecordException $e) {
361  // The child could not be compiled, probably it was deleted and a dangling mm record
362  // exists. This is a data inconsistency, we catch this exception and create a flash message
363  $message = vsprintf(
364  $this->‪getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:formEngine.databaseRecordErrorInlineChildChild'),
365  [$e->‪getTableName(), $e->‪getUid(), $childTableName, (int)$childUid]
366  );
367  $flashMessage = GeneralUtility::makeInstance(
368  FlashMessage::class,
369  $message,
370  '',
372  );
373  GeneralUtility::makeInstance(FlashMessageService::class)->getMessageQueueByIdentifier()->enqueue($flashMessage);
374  }
375  }
376  return $mainChild;
377  }
378 
387  protected function ‪compileChildChild(array $child, array $parentConfig)
388  {
389  // foreign_selector on intermediate is probably type=select, so data provider of this table resolved that to the uid already
390  $childChildUid = $child['databaseRow'][$parentConfig['foreign_selector']][0];
391  // child-child table name is set in child tca "the selector field" foreign_table
392  $childChildTableName = $child['processedTca']['columns'][$parentConfig['foreign_selector']]['config']['foreign_table'];
393  $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class);
394  $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
395 
396  $formDataCompilerInput = [
397  'command' => 'edit',
398  'tableName' => $childChildTableName,
399  'vanillaUid' => (int)$childChildUid,
400  'isInlineChild' => true,
401  'isInlineChildExpanded' => $child['isInlineChildExpanded'],
402  // @todo: this is the wrong inline structure, isn't it? Shouldn't it contain the part from child child, too?
403  'inlineStructure' => $child['inlineStructure'],
404  'inlineFirstPid' => $child['inlineFirstPid'],
405  // values of the top most parent element set on first level and not overridden on following levels
406  'inlineTopMostParentUid' => $child['inlineTopMostParentUid'],
407  'inlineTopMostParentTableName' => $child['inlineTopMostParentTableName'],
408  'inlineTopMostParentFieldName' => $child['inlineTopMostParentFieldName'],
409  ];
410  $childChild = $formDataCompiler->compile($formDataCompilerInput);
411  return $childChild;
412  }
413 
421  protected function ‪getWorkspacedUids(array $connectedUids, $childTableName)
422  {
423  $backendUser = $this->‪getBackendUser();
424  $newConnectedUids = [];
425  foreach ($connectedUids as $uid) {
426  // Fetch workspace version of a record (if any):
427  // @todo: Needs handling
428  if ($backendUser->workspace !== 0 && BackendUtility::isTableWorkspaceEnabled($childTableName)) {
429  $workspaceVersion = BackendUtility::getWorkspaceVersionOfRecord($backendUser->workspace, $childTableName, $uid, 'uid,t3ver_state');
430  if (!empty($workspaceVersion)) {
431  $versionState = ‪VersionState::cast($workspaceVersion['t3ver_state']);
432  if ($versionState->equals(‪VersionState::DELETE_PLACEHOLDER)) {
433  continue;
434  }
435  $uid = $workspaceVersion['uid'];
436  }
437  }
438  $newConnectedUids[] = $uid;
439  }
440  return $newConnectedUids;
441  }
442 
453  protected function ‪resolveConnectedRecordUids(array $parentConfig, $parentTableName, $parentUid, $parentFieldValue)
454  {
455  $directlyConnectedIds = ‪GeneralUtility::trimExplode(',', $parentFieldValue);
456  if (empty($parentConfig['MM'])) {
457  $parentUid = $this->‪getLiveDefaultId($parentTableName, $parentUid);
458  }
459  $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
460  $relationHandler->registerNonTableValues = (bool)($parentConfig['allowedIdValues'] ?? false);
461  $relationHandler->start($parentFieldValue, $parentConfig['foreign_table'] ?? '', $parentConfig['MM'] ?? '', $parentUid, $parentTableName, $parentConfig);
462  $foreignRecordUids = $relationHandler->getValueArray();
463  $resolvedForeignRecordUids = [];
464  foreach ($foreignRecordUids as $aForeignRecordUid) {
465  if ($parentConfig['MM'] ?? $parentConfig['foreign_field'] ?? false) {
466  $resolvedForeignRecordUids[] = (int)$aForeignRecordUid;
467  } else {
468  foreach ($directlyConnectedIds as $id) {
469  if ((int)$aForeignRecordUid === (int)$id) {
470  $resolvedForeignRecordUids[] = (int)$aForeignRecordUid;
471  }
472  }
473  }
474  }
475  return $resolvedForeignRecordUids;
476  }
477 
487  protected function ‪getLiveDefaultId($tableName, $uid)
488  {
489  $liveDefaultId = BackendUtility::getLiveVersionIdOfRecord($tableName, $uid);
490  if ($liveDefaultId === null) {
491  $liveDefaultId = $uid;
492  }
493  return $liveDefaultId;
494  }
495 
499  protected function ‪getBackendUser()
500  {
501  return ‪$GLOBALS['BE_USER'];
502  }
503 
507  protected function ‪getLanguageService()
508  {
509  return ‪$GLOBALS['LANG'];
510  }
511 }
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Backend\Form\FormDataGroup\OnTheFly
Definition: OnTheFly.php:27
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\isUserAllowedToModify
‪bool isUserAllowedToModify($fieldConfig)
Definition: TcaInline.php:83
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:74
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractDatabaseRecordProvider
Definition: AbstractDatabaseRecordProvider.php:30
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\compileChild
‪array compileChild(array $result, $parentFieldName, $childUid)
Definition: TcaInline.php:316
‪TYPO3\CMS\Core\Database\RelationHandler
Definition: RelationHandler.php:37
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\isInlineField
‪bool isInlineField($fieldConfig)
Definition: TcaInline.php:72
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline
Definition: TcaInline.php:38
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\check
‪bool check($type, $value)
Definition: BackendUserAuthentication.php:585
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\addForeignSelectorAndUniquePossibleRecords
‪array addForeignSelectorAndUniquePossibleRecords(array $result, $fieldName)
Definition: TcaInline.php:265
‪TYPO3\CMS\Core\Versioning\VersionState\DELETE_PLACEHOLDER
‪const DELETE_PLACEHOLDER
Definition: VersionState.php:61
‪TYPO3\CMS\Backend\Form\Exception\DatabaseRecordException\getUid
‪int getUid()
Definition: DatabaseRecordException.php:64
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\resolveConnectedRecordUids
‪array resolveConnectedRecordUids(array $parentConfig, $parentTableName, $parentUid, $parentFieldValue)
Definition: TcaInline.php:453
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\addInlineFirstPid
‪array addInlineFirstPid(array $result)
Definition: TcaInline.php:96
‪TYPO3\CMS\Core\Type\Enumeration\cast
‪static static cast($value)
Definition: Enumeration.php:186
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: TcaInline.php:499
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\getLanguageService
‪LanguageService getLanguageService()
Definition: TcaInline.php:507
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractDatabaseRecordProvider\getRecordFromDatabase
‪array getRecordFromDatabase($tableName, $uid)
Definition: AbstractDatabaseRecordProvider.php:43
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\compileChildChild
‪array compileChildChild(array $child, array $parentConfig)
Definition: TcaInline.php:387
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Form\FormDataProvider
Definition: AbstractDatabaseRecordProvider.php:16
‪TYPO3\CMS\Backend\Form\Exception\DatabaseRecordException\getTableName
‪string getTableName()
Definition: DatabaseRecordException.php:54
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\getWorkspacedUids
‪array getWorkspacedUids(array $connectedUids, $childTableName)
Definition: TcaInline.php:421
‪TYPO3\CMS\Backend\Form\FormDataProviderInterface
Definition: FormDataProviderInterface.php:23
‪TYPO3\CMS\Core\Versioning\VersionState
Definition: VersionState.php:24
‪TYPO3\CMS\Backend\Form\Exception\DatabaseRecordException
Definition: DatabaseRecordException.php:24
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:26
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\getLiveDefaultId
‪int getLiveDefaultId($tableName, $uid)
Definition: TcaInline.php:487
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\resolveRelatedRecordsOverlays
‪array resolveRelatedRecordsOverlays(array $result, $fieldName)
Definition: TcaInline.php:135
‪TYPO3\CMS\Backend\Form\InlineStackProcessor
Definition: InlineStackProcessor.php:30
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\resolveRelatedRecords
‪array resolveRelatedRecords(array $result, $fieldName)
Definition: TcaInline.php:226
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Form\FormDataCompiler
Definition: FormDataCompiler.php:25
‪TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord
Definition: TcaDatabaseRecord.php:25
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline\addData
‪array addData(array $result)
Definition: TcaInline.php:45
‪TYPO3\CMS\Core\Messaging\FlashMessageService
Definition: FlashMessageService.php:27
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:31