‪TYPO3CMS  ‪main
FilesControlContainer.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\EventDispatcher\EventDispatcherInterface;
23 use TYPO3\CMS\Backend\Utility\BackendUtility;
26 use TYPO3\CMS\Core\Imaging\IconSize;
36 
49 {
50  public const ‪NODE_TYPE_IDENTIFIER = 'file';
51 
52  private const ‪FILE_REFERENCE_TABLE = 'sys_file_reference';
53 
57  protected array ‪$fileReferenceData = [];
58 
62  protected array ‪$javaScriptModules = [];
63 
65  'tcaDescription' => [
66  'renderType' => 'tcaDescription',
67  ],
68  ];
69 
70  protected ‪$defaultFieldWizard = [
71  'localizationStateSelector' => [
72  'renderType' => 'localizationStateSelector',
73  ],
74  ];
75 
76  public function ‪__construct(
77  private readonly ‪IconFactory $iconFactory,
78  private readonly ‪InlineStackProcessor $inlineStackProcessor,
79  private readonly EventDispatcherInterface $eventDispatcher,
80  private readonly ‪OnlineMediaHelperRegistry $onlineMediaHelperRegistry,
81  private readonly ‪DefaultUploadFolderResolver $defaultUploadFolderResolver,
82  private readonly ‪HashService $hashService,
83  ) {}
84 
90  public function ‪render(): array
91  {
92  $languageService = $this->‪getLanguageService();
93 
94  $this->fileReferenceData = $this->data['inlineData'];
95 
96  $this->inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']);
97 
98  $table = $this->data['tableName'];
99  $row = $this->data['databaseRow'];
100  $field = $this->data['fieldName'];
101  $parameterArray = $this->data['parameterArray'];
102 
103  $resultArray = $this->‪initializeResultArray();
104 
105  $config = $parameterArray['fieldConf']['config'];
106  $isReadOnly = (bool)($config['readOnly'] ?? false);
107  $language = 0;
108  if (BackendUtility::isTableLocalizable($table)) {
109  $languageFieldName = ‪$GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? '';
110  $language = isset($row[$languageFieldName][0]) ? (int)$row[$languageFieldName][0] : (int)$row[$languageFieldName];
111  }
112 
113  // Add the current inline job to the structure stack
114  $newStructureItem = [
115  'table' => $table,
116  'uid' => $row['uid'],
117  'field' => $field,
118  'config' => $config,
119  ];
120 
121  // Extract FlexForm parts (if any) from element name, e.g. array('vDEF', 'lDEF', 'FlexField', 'vDEF')
122  $itemName = (string)$parameterArray['itemFormElName'];
123  if ($itemName !== '') {
124  $flexFormParts = $this->‪extractFlexFormParts($itemName);
125  if ($flexFormParts !== null) {
126  $newStructureItem['flexform'] = $flexFormParts;
127  if ($flexFormParts !== []
128  && isset($this->data['processedTca']['columns'][$field]['config']['dataStructureIdentifier'])
129  ) {
130  // Transport the flexform DS identifier fields to the FormFilesAjaxController
131  $config['dataStructureIdentifier'] = $this->data['processedTca']['columns'][$field]['config']['dataStructureIdentifier'];
132  }
133  }
134  }
135 
136  $this->inlineStackProcessor->pushStableStructureItem($newStructureItem);
137 
138  // Hand over original returnUrl to FormFilesAjaxController. Needed if opening for instance a
139  // nested element in a new view to then go back to the original returnUrl and not the url of
140  // the inline ajax controller
141  $config['originalReturnUrl'] = $this->data['returnUrl'];
142 
143  // e.g. data[<table>][<uid>][<field>]
144  $formFieldName = $this->inlineStackProcessor->getCurrentStructureFormPrefix();
145  // e.g. data-<pid>-<table1>-<uid1>-<field1>-<table2>-<uid2>-<field2>
146  $formFieldIdentifier = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
147 
148  $inlineChildren = $parameterArray['fieldConf']['children'] ?? [];
149 
150  $config['inline']['first'] = $config['inline']['last'] = false;
151  if (is_array($inlineChildren) && $inlineChildren !== []) {
152  $firstChild = $inlineChildren[array_key_first($inlineChildren)] ?? null;
153  if (isset($firstChild['databaseRow']['uid'])) {
154  $config['inline']['first'] = $firstChild['databaseRow']['uid'];
155  }
156  $lastChild = $inlineChildren[array_key_last($inlineChildren)] ?? null;
157  if (isset($lastChild['databaseRow']['uid'])) {
158  $config['inline']['last'] = $lastChild['databaseRow']['uid'];
159  }
160  }
161 
162  $top = $this->inlineStackProcessor->getStructureLevel(0);
163 
164  $this->fileReferenceData['config'][$formFieldIdentifier] = [
166  ];
167  $configJson = (string)json_encode($config);
168  $this->fileReferenceData['config'][$formFieldIdentifier . '-' . ‪self::FILE_REFERENCE_TABLE] = [
169  'min' => $config['minitems'],
170  'max' => $config['maxitems'],
171  'sortable' => $config['appearance']['useSortable'] ?? false,
172  'top' => [
173  'table' => $top['table'],
174  'uid' => $top['uid'],
175  ],
176  'context' => [
177  'config' => $configJson,
178  'hmac' => $this->hashService->hmac($configJson, 'FilesContext'),
179  ],
180  ];
181  $this->fileReferenceData['nested'][$formFieldIdentifier] = $this->data['tabAndInlineStack'];
182 
183  $resultArray['inlineData'] = ‪$this->fileReferenceData;
184 
185  // @todo: It might be a good idea to have something like "isLocalizedRecord" or similar set by a data provider
186  $uidOfDefaultRecord = $row[‪$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] ?? null] ?? 0;
187  $isLocalizedParent = $language > 0
188  && ($uidOfDefaultRecord[0] ?? $uidOfDefaultRecord) > 0
190  $numberOfFullLocalizedChildren = 0;
191  $numberOfNotYetLocalizedChildren = 0;
192  foreach ($inlineChildren as $child) {
193  if (!$child['isInlineDefaultLanguageRecordInLocalizedParentContext']) {
194  $numberOfFullLocalizedChildren++;
195  }
196  if ($isLocalizedParent && $child['isInlineDefaultLanguageRecordInLocalizedParentContext']) {
197  $numberOfNotYetLocalizedChildren++;
198  }
199  }
200 
201  if ($isReadOnly || $numberOfFullLocalizedChildren >= ($config['maxitems'] ?? 0)) {
202  $config['inline']['showNewFileReferenceButton'] = false;
203  $config['inline']['showCreateNewRelationButton'] = false;
204  $config['inline']['showOnlineMediaAddButtonStyle'] = false;
205  }
206 
207  $fieldInformationResult = $this->‪renderFieldInformation();
208  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
209 
210  $fieldWizardResult = $this->‪renderFieldWizard();
211  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
212 
213  $sortableRecordUids = $fileReferencesHtml = [];
214  foreach ($inlineChildren as $options) {
215  $options['inlineParentUid'] = $row['uid'];
216  $options['inlineFirstPid'] = $this->data['inlineFirstPid'];
217  $options['inlineParentConfig'] = $config;
218  $options['inlineData'] = ‪$this->fileReferenceData;
219  $options['inlineStructure'] = $this->inlineStackProcessor->getStructure();
220  $options['inlineExpandCollapseStateArray'] = $this->data['inlineExpandCollapseStateArray'];
221  $options['renderType'] = ‪FileReferenceContainer::NODE_TYPE_IDENTIFIER;
222  $fileReference = $this->nodeFactory->create($options)->render();
223  $fileReferencesHtml[] = $fileReference['html'];
224  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fileReference, false);
225  if (!$options['isInlineDefaultLanguageRecordInLocalizedParentContext'] && isset($options['databaseRow']['uid'])) {
226  // Don't add record to list of "valid" uids if it is only the default
227  // language record of a not yet localized child
228  $sortableRecordUids[] = $options['databaseRow']['uid'];
229  }
230  }
231 
232  $view = $this->backendViewFactory->create($this->data['request']);
233  $view->assignMultiple([
234  'formFieldIdentifier' => $formFieldIdentifier,
235  'formFieldName' => $formFieldName,
236  'formGroupAttributes' => GeneralUtility::implodeAttributes([
237  'class' => 'form-group',
238  'id' => $formFieldIdentifier,
239  'data-uid' => (string)$row['uid'],
240  'data-local-table' => (string)$top['table'],
241  'data-local-field' => (string)$top['field'],
242  'data-foreign-table' => self::FILE_REFERENCE_TABLE,
243  'data-object-group' => $formFieldIdentifier . '-' . self::FILE_REFERENCE_TABLE,
244  'data-form-field' => $formFieldName,
245  'data-appearance' => (string)json_encode($config['appearance'] ?? ''),
246  ], true),
247  'fieldInformation' => $fieldInformationResult['html'],
248  'fieldWizard' => $fieldWizardResult['html'],
249  'fileReferences' => [
250  'id' => $formFieldIdentifier . '_records',
251  'title' => $languageService->sL(trim($parameterArray['fieldConf']['label'] ?? '')),
252  'records' => implode(LF, $fileReferencesHtml),
253  ],
254  'sortableRecordUids' => implode(',', $sortableRecordUids),
255  'validationRules' => $this->‪getValidationDataAsJsonString([
256  'type' => 'inline',
257  'minitems' => $config['minitems'] ?? null,
258  'maxitems' => $config['maxitems'] ?? null,
259  ]),
260  ]);
261 
262  if (!$isReadOnly && ($config['appearance']['showFileSelectors'] ?? true) !== false) {
264  $fileExtensionFilter = GeneralUtility::makeInstance(FileExtensionFilter::class);
265  $fileExtensionFilter->setAllowedFileExtensions($config['allowed'] ?? null);
266  $fileExtensionFilter->setDisallowedFileExtensions($config['disallowed'] ?? null);
267  $view->assign('fileSelectors', $this->‪getFileSelectors($config, $fileExtensionFilter));
268  $view->assignMultiple($fileExtensionFilter->getFilteredFileExtensions());
269  // Render the localization buttons if needed
270  if ($numberOfNotYetLocalizedChildren) {
271  $view->assignMultiple([
272  'showAllLocalizationLink' => !empty($config['appearance']['showAllLocalizationLink']),
273  'showSynchronizationLink' => !empty($config['appearance']['showSynchronizationLink']),
274  ]);
275  }
276  }
277 
278  $event = $this->eventDispatcher->dispatch(
279  new ‪CustomFileControlsEvent($resultArray, $table, $field, $row, $config, $formFieldIdentifier, $formFieldName)
280  );
281  $resultArray = $event->getResultArray();
282  $controls = $event->getControls();
283 
284  if ($controls !== []) {
285  $view->assign('customControls', [
286  'id' => $formFieldIdentifier . '_customControls',
287  'controls' => implode("\n", $controls),
288  ]);
289  }
290 
291  $resultArray['javaScriptModules'] = array_merge(
292  $resultArray['javaScriptModules'],
293  $this->javaScriptModules,
294  [‪JavaScriptModuleInstruction::create('@typo3/backend/form-engine/container/files-control-container.js')]
295  );
296 
297  $resultArray['html'] = $this->‪wrapWithFieldsetAndLegend($view->render('Form/FilesControlContainer'));
298  return $resultArray;
299  }
300 
304  protected function ‪getFileSelectors(array $inlineConfiguration, ‪FileExtensionFilter $fileExtensionFilter): array
305  {
306  $languageService = $this->‪getLanguageService();
307  $backendUser = $this->‪getBackendUserAuthentication();
308 
309  $currentStructureDomObjectIdPrefix = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
310  $objectPrefix = $currentStructureDomObjectIdPrefix . '-' . ‪self::FILE_REFERENCE_TABLE;
311 
312  $controls = [];
313  if ($inlineConfiguration['appearance']['elementBrowserEnabled'] ?? true) {
314  if ($inlineConfiguration['appearance']['createNewRelationLinkTitle'] ?? false) {
315  $buttonText = $inlineConfiguration['appearance']['createNewRelationLinkTitle'];
316  } else {
317  $buttonText = 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.createNewRelation';
318  }
319  $buttonText = $languageService->sL($buttonText);
320  $attributes = [
321  'type' => 'button',
322  'class' => 'btn btn-default t3js-element-browser',
323  'style' => !($inlineConfiguration['inline']['showCreateNewRelationButton'] ?? true) ? 'display: none;' : '',
324  'title' => $buttonText,
325  'data-mode' => 'file',
326  'data-params' => '|||allowed=' . implode(',', $fileExtensionFilter->‪getAllowedFileExtensions() ?? []) . '~disallowed=' . implode(',', $fileExtensionFilter->‪getDisallowedFileExtensions() ?? []) . '|' . $objectPrefix,
327  ];
328  $controls[] = '
329  <button ' . GeneralUtility::implodeAttributes($attributes, true) . '>
330  ' . $this->iconFactory->getIcon('actions-insert-record', IconSize::SMALL)->render() . '
331  ' . htmlspecialchars($buttonText) . '
332  </button>';
333  }
334 
335  $onlineMediaAllowed = [];
336  foreach ($this->onlineMediaHelperRegistry->getSupportedFileExtensions() as $supportedFileExtension) {
337  if ($fileExtensionFilter->‪isAllowed($supportedFileExtension)) {
338  $onlineMediaAllowed[] = $supportedFileExtension;
339  }
340  }
341 
342  $showUpload = (bool)($inlineConfiguration['appearance']['fileUploadAllowed'] ?? true);
343  $showByUrl = ($inlineConfiguration['appearance']['fileByUrlAllowed'] ?? true) && $onlineMediaAllowed !== [];
344 
345  if (($showUpload || $showByUrl) && ($backendUser->uc['edit_docModuleUpload'] ?? false)) {
346  $folder = $this->defaultUploadFolderResolver->resolve(
347  $backendUser,
348  $this->data['tableName'] === 'pages' ? $this->data['vanillaUid'] : ($this->data['parentPageRow']['uid'] ?? 0),
349  $this->data['tableName'],
350  $this->data['fieldName']
351  );
352  if (
353  $folder instanceof ‪Folder
354  && $folder->‪getStorage()->checkUserActionPermission('add', 'File')
355  ) {
356  if ($showUpload) {
357  if ($inlineConfiguration['appearance']['uploadFilesLinkTitle'] ?? false) {
358  $buttonText = $inlineConfiguration['appearance']['uploadFilesLinkTitle'];
359  } else {
360  $buttonText = 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.select-and-submit';
361  }
362  $buttonText = $languageService->sL($buttonText);
363 
364  $attributes = [
365  'type' => 'button',
366  'class' => 'btn btn-default t3js-drag-uploader',
367  'title' => $buttonText,
368  'style' => !($inlineConfiguration['inline']['showCreateNewRelationButton'] ?? true) ? 'display: none;' : '',
369  'data-dropzone-target' => '#' . ‪StringUtility::escapeCssSelector($currentStructureDomObjectIdPrefix),
370  'data-insert-dropzone-before' => '1',
371  'data-file-irre-object' => $objectPrefix,
372  'data-file-allowed' => implode(',', $fileExtensionFilter->‪getAllowedFileExtensions() ?? []),
373  'data-file-disallowed' => implode(',', $fileExtensionFilter->‪getDisallowedFileExtensions() ?? []),
374  'data-target-folder' => $folder->getCombinedIdentifier(),
375  'data-max-file-size' => (string)(GeneralUtility::getMaxUploadFileSize() * 1024),
376  ];
377  $controls[] = '
378  <button ' . GeneralUtility::implodeAttributes($attributes, true) . '>
379  ' . $this->iconFactory->getIcon('actions-upload', IconSize::SMALL)->render() . '
380  ' . htmlspecialchars($buttonText) . '
381  </button>';
382 
383  $this->javaScriptModules[] = ‪JavaScriptModuleInstruction::create('@typo3/backend/drag-uploader.js');
384  }
385  if ($showByUrl) {
386  if ($inlineConfiguration['appearance']['addMediaLinkTitle'] ?? false) {
387  $buttonText = $inlineConfiguration['appearance']['addMediaLinkTitle'];
388  } else {
389  $buttonText = 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.button';
390  }
391  $buttonText = $languageService->sL($buttonText);
392  $attributes = [
393  'type' => 'button',
394  'class' => 'btn btn-default t3js-online-media-add-btn',
395  'title' => $buttonText,
396  'style' => !($inlineConfiguration['inline']['showOnlineMediaAddButtonStyle'] ?? true) ? 'display: none;' : '',
397  'data-target-folder' => $folder->getCombinedIdentifier(),
398  'data-file-irre-object' => $objectPrefix,
399  'data-online-media-allowed' => implode(',', $onlineMediaAllowed),
400  'data-btn-submit' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder'),
401  'data-placeholder' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder'),
402  'data-online-media-allowed-help-text' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowEmbedSources'),
403  ];
404 
405  // @todo Should be implemented as web component
406  $controls[] = '
407  <button ' . GeneralUtility::implodeAttributes($attributes, true) . '>
408  ' . $this->iconFactory->getIcon('actions-online-media-add', IconSize::SMALL)->render() . '
409  ' . htmlspecialchars($buttonText) . '
410  </button>';
411 
412  $this->javaScriptModules[] = ‪JavaScriptModuleInstruction::create('@typo3/backend/online-media.js');
413  }
414  }
415  }
416 
417  return $controls;
418  }
419 
424  protected function ‪extractFlexFormParts(string $formElementName): ?array
425  {
426  $flexFormParts = null;
427  $matches = [];
428  if (preg_match('#^data(?:\[[^]]+\]){3}(\[data\](?:\[[^]]+\]){4,})$#', $formElementName, $matches)) {
429  $flexFormParts = ‪GeneralUtility::trimExplode(
430  '][',
431  trim($matches[1], '[]')
432  );
433  }
434  return $flexFormParts;
435  }
436 
438  {
439  return ‪$GLOBALS['LANG'];
440  }
441 }
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\__construct
‪__construct(private readonly IconFactory $iconFactory, private readonly InlineStackProcessor $inlineStackProcessor, private readonly EventDispatcherInterface $eventDispatcher, private readonly OnlineMediaHelperRegistry $onlineMediaHelperRegistry, private readonly DefaultUploadFolderResolver $defaultUploadFolderResolver, private readonly HashService $hashService,)
Definition: FilesControlContainer.php:76
‪TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry
Definition: OnlineMediaHelperRegistry.php:27
‪TYPO3\CMS\Backend\Form\AbstractNode\mergeChildReturnIntoExistingResult
‪array mergeChildReturnIntoExistingResult(array $existing, array $childReturn, bool $mergeHtml=true)
Definition: AbstractNode.php:104
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\$javaScriptModules
‪array $javaScriptModules
Definition: FilesControlContainer.php:62
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\getFileSelectors
‪getFileSelectors(array $inlineConfiguration, FileExtensionFilter $fileExtensionFilter)
Definition: FilesControlContainer.php:304
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction\create
‪static create(string $name, string $exportName=null)
Definition: JavaScriptModuleInstruction.php:47
‪TYPO3\CMS\Backend\Form\Container
Definition: AbstractContainer.php:16
‪TYPO3\CMS\Backend\Form\Container\AbstractContainer\wrapWithFieldsetAndLegend
‪wrapWithFieldsetAndLegend(string $fieldContent)
Definition: AbstractContainer.php:140
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
Definition: JavaScriptModuleInstruction.php:23
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\$fileReferenceData
‪array $fileReferenceData
Definition: FilesControlContainer.php:57
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger(mixed $var)
Definition: MathUtility.php:69
‪TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter\getDisallowedFileExtensions
‪getDisallowedFileExtensions()
Definition: FileExtensionFilter.php:161
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\FILE_REFERENCE_TABLE
‪const FILE_REFERENCE_TABLE
Definition: FilesControlContainer.php:52
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\getLanguageService
‪getLanguageService()
Definition: FilesControlContainer.php:437
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\$defaultFieldInformation
‪$defaultFieldInformation
Definition: FilesControlContainer.php:64
‪TYPO3\CMS\Core\Resource\DefaultUploadFolderResolver
Definition: DefaultUploadFolderResolver.php:31
‪TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter\getAllowedFileExtensions
‪getAllowedFileExtensions()
Definition: FileExtensionFilter.php:146
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer
Definition: FilesControlContainer.php:49
‪TYPO3\CMS\Backend\Form\Container\AbstractContainer\getBackendUserAuthentication
‪getBackendUserAuthentication()
Definition: AbstractContainer.php:149
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:38
‪TYPO3\CMS\Backend\Form\Container\AbstractContainer
Definition: AbstractContainer.php:29
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪getStorage()
Definition: Folder.php:139
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\extractFlexFormParts
‪extractFlexFormParts(string $formElementName)
Definition: FilesControlContainer.php:424
‪TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter
Definition: FileExtensionFilter.php:31
‪TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter\isAllowed
‪isAllowed(string $fileExtension)
Definition: FileExtensionFilter.php:121
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\$defaultFieldWizard
‪$defaultFieldWizard
Definition: FilesControlContainer.php:70
‪TYPO3\CMS\Backend\Form\Container\AbstractContainer\renderFieldInformation
‪array renderFieldInformation()
Definition: AbstractContainer.php:52
‪TYPO3\CMS\Backend\Form\Event\CustomFileControlsEvent
Definition: CustomFileControlsEvent.php:24
‪TYPO3\CMS\Backend\Form\Container\FileReferenceContainer\NODE_TYPE_IDENTIFIER
‪const NODE_TYPE_IDENTIFIER
Definition: FileReferenceContainer.php:51
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Form\AbstractNode\getValidationDataAsJsonString
‪getValidationDataAsJsonString(array $config)
Definition: AbstractNode.php:133
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\NODE_TYPE_IDENTIFIER
‪const NODE_TYPE_IDENTIFIER
Definition: FilesControlContainer.php:50
‪TYPO3\CMS\Core\Utility\StringUtility\escapeCssSelector
‪static escapeCssSelector(string $selector)
Definition: StringUtility.php:69
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Backend\Form\InlineStackProcessor
Definition: InlineStackProcessor.php:32
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Backend\Form\Container\AbstractContainer\renderFieldWizard
‪array renderFieldWizard()
Definition: AbstractContainer.php:86
‪TYPO3\CMS\Core\Crypto\HashService
Definition: HashService.php:27
‪TYPO3\CMS\Backend\Form\Container\FilesControlContainer\render
‪array render()
Definition: FilesControlContainer.php:90
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822
‪TYPO3\CMS\Backend\Form\AbstractNode\initializeResultArray
‪initializeResultArray()
Definition: AbstractNode.php:77