TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
AbstractItemProvider.php
Go to the documentation of this file.
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 Doctrine\DBAL\DBALException;
38 
43 abstract class AbstractItemProvider
44 {
53  protected function resolveItemProcessorFunction(array $result, $fieldName, array $items)
54  {
55  $table = $result['tableName'];
56  $config = $result['processedTca']['columns'][$fieldName]['config'];
57 
58  $pageTsProcessorParameters = null;
59  if (!empty($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['itemsProcFunc.'])) {
60  $pageTsProcessorParameters = $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['itemsProcFunc.'];
61  }
62  $processorParameters = [
63  // Function manipulates $items directly and return nothing
64  'items' => &$items,
65  'config' => $config,
66  'TSconfig' => $pageTsProcessorParameters,
67  'table' => $table,
68  'row' => $result['databaseRow'],
69  'field' => $fieldName,
70  ];
71  if (!empty($result['flexParentDatabaseRow'])) {
72  $processorParameters['flexParentDatabaseRow'] = $result['flexParentDatabaseRow'];
73  }
74 
75  try {
76  GeneralUtility::callUserFunction($config['itemsProcFunc'], $processorParameters, $this);
77  } catch (\Exception $exception) {
78  // The itemsProcFunc method may throw an exception, create a flash message if so
79  $languageService = $this->getLanguageService();
80  $fieldLabel = $fieldName;
81  if (!empty($result['processedTca']['columns'][$fieldName]['label'])) {
82  $fieldLabel = $languageService->sL($result['processedTca']['columns'][$fieldName]['label']);
83  }
84  $message = sprintf(
85  $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:error.items_proc_func_error'),
86  $fieldLabel,
87  $exception->getMessage()
88  );
90  $flashMessage = GeneralUtility::makeInstance(
91  FlashMessage::class,
92  $message,
93  '',
95  true
96  );
98  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
99  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
100  $defaultFlashMessageQueue->enqueue($flashMessage);
101  }
102 
103  return $items;
104  }
105 
119  protected function addItemsFromPageTsConfig(array $result, $fieldName, array $items)
120  {
121  $table = $result['tableName'];
122  $iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
123  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
124 
125  if (!empty($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['addItems.'])
126  && is_array($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['addItems.'])
127  ) {
128  $addItemsArray = $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['addItems.'];
129  foreach ($addItemsArray as $value => $label) {
130  // If the value ends with a dot, it is a subelement like "34.icon = mylabel.png", skip it
131  if (substr($value, -1) === '.') {
132  continue;
133  }
134  // Check if value "34 = mylabel" also has a "34.icon = myImage.png"
135  $icon = null;
136  if (isset($addItemsArray[$value . '.'])
137  && is_array($addItemsArray[$value . '.'])
138  && !empty($addItemsArray[$value . '.']['icon'])
139  ) {
140  $iconIdentifier = $addItemsArray[$value . '.']['icon'];
141  if (!$iconRegistry->isRegistered($iconIdentifier)) {
143  'Using a file path for icon in pageTsConfig addItems is deprecated.' .
144  'Use a registered iconIdentifier instead'
145  );
146  $iconPath = GeneralUtility::getFileAbsFileName($iconIdentifier);
147  if ($iconPath !== '') {
148  $iconIdentifier = md5($iconPath);
149  $iconRegistry->registerIcon(
150  $iconIdentifier,
151  $iconRegistry->detectIconProvider($iconPath),
152  [
153  'source' => $iconPath
154  ]
155  );
156  }
157  }
158  $icon = $iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL)->getMarkup('inline');
159  }
160  $items[] = [$label, $value, $icon];
161  }
162  }
163  return $items;
164  }
165 
177  protected function addItemsFromSpecial(array $result, $fieldName, array $items)
178  {
179  // Guard
180  if (empty($result['processedTca']['columns'][$fieldName]['config']['special'])
181  || !is_string($result['processedTca']['columns'][$fieldName]['config']['special'])
182  ) {
183  return $items;
184  }
185 
186  $languageService = $this->getLanguageService();
187  $iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
188  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
189 
190  $special = $result['processedTca']['columns'][$fieldName]['config']['special'];
191  switch (true) {
192  case $special === 'tables':
193  foreach ($GLOBALS['TCA'] as $currentTable => $_) {
194  if (!empty($GLOBALS['TCA'][$currentTable]['ctrl']['adminOnly'])) {
195  // Hide "admin only" tables
196  continue;
197  }
198  $label = !empty($GLOBALS['TCA'][$currentTable]['ctrl']['title']) ? $GLOBALS['TCA'][$currentTable]['ctrl']['title'] : '';
199  $icon = $iconFactory->mapRecordTypeToIconIdentifier($currentTable, []);
200  $helpText = [];
201  $languageService->loadSingleTableDescription($currentTable);
202  // @todo: check if this actually works, currently help texts are missing
203  $helpTextArray = $GLOBALS['TCA_DESCR'][$currentTable]['columns'][''];
204  if (!empty($helpTextArray['description'])) {
205  $helpText['description'] = $helpTextArray['description'];
206  }
207  $items[] = [$label, $currentTable, $icon, $helpText];
208  }
209  break;
210  case $special === 'pagetypes':
211  if (isset($GLOBALS['TCA']['pages']['columns']['doktype']['config']['items'])
212  && is_array($GLOBALS['TCA']['pages']['columns']['doktype']['config']['items'])
213  ) {
214  $specialItems = $GLOBALS['TCA']['pages']['columns']['doktype']['config']['items'];
215  foreach ($specialItems as $specialItem) {
216  if (!is_array($specialItem) || $specialItem[1] === '--div--') {
217  // Skip non arrays and divider items
218  continue;
219  }
220  $label = $specialItem[0];
221  $value = $specialItem[1];
222  $icon = $iconFactory->mapRecordTypeToIconIdentifier('pages', ['doktype' => $specialItem[1]]);
223  $items[] = [$label, $value, $icon];
224  }
225  }
226  break;
227  case $special === 'exclude':
228  $excludeArrays = $this->getExcludeFields();
229  foreach ($excludeArrays as $excludeArray) {
230  // If the field comes from a FlexForm, the syntax is more complex
231  if ($excludeArray['origin'] === 'flexForm') {
232  // The field comes from a plugins FlexForm
233  // Add header if not yet set for plugin section
234  if (!isset($items[$excludeArray['sectionHeader']])) {
235  // there is no icon handling for plugins - we take the icon from the table
236  $icon = $iconFactory->mapRecordTypeToIconIdentifier($excludeArray['table'], []);
237  $items[$excludeArray['sectionHeader']] = [
238  $excludeArray['sectionHeader'],
239  '--div--',
240  $icon
241  ];
242  }
243  } else {
244  // Add header if not yet set for table
245  if (!isset($items[$excludeArray['table']])) {
246  $icon = $iconFactory->mapRecordTypeToIconIdentifier($excludeArray['table'], []);
247  $items[$excludeArray['table']] = [
248  $GLOBALS['TCA'][$excludeArray['table']]['ctrl']['title'],
249  '--div--',
250  $icon
251  ];
252  }
253  }
254  // Add help text
255  $helpText = [];
256  $languageService->loadSingleTableDescription($excludeArray['table']);
257  $helpTextArray = $GLOBALS['TCA_DESCR'][$excludeArray['table']]['columns'][$excludeArray['table']];
258  if (!empty($helpTextArray['description'])) {
259  $helpText['description'] = $helpTextArray['description'];
260  }
261  // Item configuration:
262  $items[] = [
263  rtrim($excludeArray['origin'] === 'flexForm' ? $excludeArray['fieldLabel'] : $languageService->sL($GLOBALS['TCA'][$excludeArray['table']]['columns'][$excludeArray['fieldName']]['label']), ':') . ' (' . $excludeArray['fieldName'] . ')',
264  $excludeArray['table'] . ':' . $excludeArray['fullField'] ,
265  'empty-empty',
266  $helpText
267  ];
268  }
269  break;
270  case $special === 'explicitValues':
271  $theTypes = $this->getExplicitAuthFieldValues();
272  $icons = [
273  'ALLOW' => 'status-status-permission-granted',
274  'DENY' => 'status-status-permission-denied'
275  ];
276  // Traverse types:
277  foreach ($theTypes as $tableFieldKey => $theTypeArrays) {
278  if (is_array($theTypeArrays['items'])) {
279  // Add header:
280  $items[] = [
281  $theTypeArrays['tableFieldLabel'],
282  '--div--',
283  ];
284  // Traverse options for this field:
285  foreach ($theTypeArrays['items'] as $itemValue => $itemContent) {
286  // Add item to be selected:
287  $items[] = [
288  '[' . $itemContent[2] . '] ' . $itemContent[1],
289  $tableFieldKey . ':' . preg_replace('/[:|,]/', '', $itemValue) . ':' . $itemContent[0],
290  $icons[$itemContent[0]]
291  ];
292  }
293  }
294  }
295  break;
296  case $special === 'languages':
297  foreach ($result['systemLanguageRows'] as $language) {
298  if ($language['uid'] !== -1) {
299  $items[] = [
300  0 => $language['title'] . ' [' . $language['uid'] . ']',
301  1 => $language['uid'],
302  2 => $language['flagIconIdentifier']
303  ];
304  }
305  }
306  break;
307  case $special === 'custom':
308  $customOptions = $GLOBALS['TYPO3_CONF_VARS']['BE']['customPermOptions'];
309  if (is_array($customOptions)) {
310  foreach ($customOptions as $coKey => $coValue) {
311  if (is_array($coValue['items'])) {
312  // Add header:
313  $items[] = [
314  $languageService->sL($coValue['header']),
315  '--div--'
316  ];
317  // Traverse items:
318  foreach ($coValue['items'] as $itemKey => $itemCfg) {
319  $icon = 'empty-empty';
320  $helpText = [];
321  if (!empty($itemCfg[1])) {
322  if ($iconRegistry->isRegistered($itemCfg[1])) {
323  // Use icon identifier when registered
324  $icon = $itemCfg[1];
325  }
326  }
327  if (!empty($itemCfg[2])) {
328  $helpText['description'] = $languageService->sL($itemCfg[2]);
329  }
330  $items[] = [
331  $languageService->sL($itemCfg[0]),
332  $coKey . ':' . preg_replace('/[:|,]/', '', $itemKey),
333  $icon,
334  $helpText
335  ];
336  }
337  }
338  }
339  }
340  break;
341  case $special === 'modListGroup' || $special === 'modListUser':
343  $loadModules = GeneralUtility::makeInstance(ModuleLoader::class);
344  $loadModules->load($GLOBALS['TBE_MODULES']);
345  $modList = $special === 'modListUser' ? $loadModules->modListUser : $loadModules->modListGroup;
346  if (is_array($modList)) {
347  foreach ($modList as $theMod) {
348  $moduleLabels = $loadModules->getLabelsForModule($theMod);
349  list($mainModule, $subModule) = explode('_', $theMod, 2);
350  // Icon:
351  if (!empty($subModule)) {
352  $icon = $loadModules->modules[$mainModule]['sub'][$subModule]['iconIdentifier'];
353  } else {
354  $icon = $loadModules->modules[$theMod]['iconIdentifier'];
355  }
356  // Add help text
357  $helpText = [
358  'title' => $languageService->sL($moduleLabels['shortdescription']),
359  'description' => $languageService->sL($moduleLabels['description'])
360  ];
361 
362  $label = '';
363  // Add label for main module if this is a submodule
364  if (!empty($subModule)) {
365  $mainModuleLabels = $loadModules->getLabelsForModule($mainModule);
366  $label .= $languageService->sL($mainModuleLabels['title']) . '>';
367  }
368  // Add modules own label now
369  $label .= $languageService->sL($moduleLabels['title']);
370 
371  // Item configuration
372  $items[] = [$label, $theMod, $icon, $helpText];
373  }
374  }
375  break;
376  default:
377  throw new \UnexpectedValueException(
378  'Unknown special value ' . $special . ' for field ' . $fieldName . ' of table ' . $result['tableName'],
379  1439298496
380  );
381  }
382  return $items;
383  }
384 
396  protected function addItemsFromFolder(array $result, $fieldName, array $items)
397  {
398  if (empty($result['processedTca']['columns'][$fieldName]['config']['fileFolder'])
399  || !is_string($result['processedTca']['columns'][$fieldName]['config']['fileFolder'])
400  ) {
401  return $items;
402  }
403 
404  $fileFolderRaw = $result['processedTca']['columns'][$fieldName]['config']['fileFolder'];
405  $fileFolder = GeneralUtility::getFileAbsFileName($fileFolderRaw);
406  if ($fileFolder === '') {
407  throw new \RuntimeException(
408  'Invalid folder given for item processing: ' . $fileFolderRaw . ' for table ' . $result['tableName'] . ', field ' . $fieldName,
409  1479399227
410  );
411  }
412  $fileFolder = rtrim($fileFolder, '/') . '/';
413 
414  if (@is_dir($fileFolder)) {
415  $fileExtensionList = '';
416  if (!empty($result['processedTca']['columns'][$fieldName]['config']['fileFolder_extList'])
417  && is_string($result['processedTca']['columns'][$fieldName]['config']['fileFolder_extList'])
418  ) {
419  $fileExtensionList = $result['processedTca']['columns'][$fieldName]['config']['fileFolder_extList'];
420  }
421  $recursionLevels = isset($fieldValue['config']['fileFolder_recursions'])
422  ? MathUtility::forceIntegerInRange($fieldValue['config']['fileFolder_recursions'], 0, 99)
423  : 99;
424  $fileArray = GeneralUtility::getAllFilesAndFoldersInPath([], $fileFolder, $fileExtensionList, 0, $recursionLevels);
425  $fileArray = GeneralUtility::removePrefixPathFromList($fileArray, $fileFolder);
426  foreach ($fileArray as $fileReference) {
427  $fileInformation = pathinfo($fileReference);
428  $icon = GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], strtolower($fileInformation['extension']))
429  ? $fileFolder . $fileReference
430  : '';
431  $items[] = [
432  $fileReference,
433  $fileReference,
434  $icon
435  ];
436  }
437  }
438 
439  return $items;
440  }
441 
453  protected function addItemsFromForeignTable(array $result, $fieldName, array $items)
454  {
455  // Guard
456  if (empty($result['processedTca']['columns'][$fieldName]['config']['foreign_table'])
457  || !is_string($result['processedTca']['columns'][$fieldName]['config']['foreign_table'])
458  ) {
459  return $items;
460  }
461 
462  $languageService = $this->getLanguageService();
463 
464  $foreignTable = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'];
465 
466  if (!is_array($GLOBALS['TCA'][$foreignTable])) {
467  throw new \UnexpectedValueException(
468  'Field ' . $fieldName . ' of table ' . $result['tableName'] . ' reference to foreign table '
469  . $foreignTable . ', but this table is not defined in TCA',
470  1439569743
471  );
472  }
473 
474  $queryBuilder = $this->buildForeignTableQueryBuilder($result, $fieldName);
475  try {
476  $queryResult = $queryBuilder->execute();
477  } catch (DBALException $e) {
478  $databaseError = $e->getPrevious()->getMessage();
479  }
480 
481  // Early return on error with flash message
482  if (!empty($databaseError)) {
483  $msg = $databaseError . '. ';
484  $msg .= $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:error.database_schema_mismatch');
485  $msgTitle = $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:error.database_schema_mismatch_title');
487  $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $msg, $msgTitle, FlashMessage::ERROR, true);
489  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
491  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
492  $defaultFlashMessageQueue->enqueue($flashMessage);
493  return $items;
494  }
495 
496  $labelPrefix = '';
497  if (!empty($result['processedTca']['columns'][$fieldName]['config']['foreign_table_prefix'])) {
498  $labelPrefix = $result['processedTca']['columns'][$fieldName]['config']['foreign_table_prefix'];
499  $labelPrefix = $languageService->sL($labelPrefix);
500  }
501 
502  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
503 
504  while ($foreignRow = $queryResult->fetch()) {
505  BackendUtility::workspaceOL($foreignTable, $foreignRow);
506  if (is_array($foreignRow)) {
507  // If the foreign table sets selicon_field, this field can contain an image
508  // that represents this specific row.
509  $iconFieldName = '';
510  if (!empty($GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field'])) {
511  $iconFieldName = $GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field'];
512  }
513  $iconPath = '';
514  if (!empty($GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field_path'])) {
515  $iconPath = $GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field_path'];
516  }
517  if ($iconFieldName && $iconPath && $foreignRow[$iconFieldName]) {
518  // Prepare the row icon if available
519  $iParts = GeneralUtility::trimExplode(',', $foreignRow[$iconFieldName], true);
520  $icon = $iconPath . '/' . trim($iParts[0]);
521  } else {
522  // Else, determine icon based on record type, or a generic fallback
523  $icon = $iconFactory->mapRecordTypeToIconIdentifier($foreignTable, $foreignRow);
524  }
525  // Add the item
526  $items[] = [
527  $labelPrefix . BackendUtility::getRecordTitle($foreignTable, $foreignRow),
528  $foreignRow['uid'],
529  $icon
530  ];
531  }
532  }
533 
534  return $items;
535  }
536 
547  protected function removeItemsByKeepItemsPageTsConfig(array $result, $fieldName, array $items)
548  {
549  $table = $result['tableName'];
550  if (!isset($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['keepItems'])
551  || !is_string($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['keepItems'])
552  ) {
553  return $items;
554  }
555 
556  // If keepItems is set but is an empty list all current items get removed
557  if (empty($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['keepItems'])
558  && $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['keepItems'] !== '0') {
559  return [];
560  }
561 
563  $items,
564  $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['keepItems'],
565  function ($value) {
566  return $value[1];
567  }
568  );
569  }
570 
581  protected function removeItemsByRemoveItemsPageTsConfig(array $result, $fieldName, array $items)
582  {
583  $table = $result['tableName'];
584  if (empty($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['removeItems'])
585  || !is_string($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['removeItems'])
586  ) {
587  return $items;
588  }
589 
590  $removeItems = GeneralUtility::trimExplode(
591  ',',
592  $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['removeItems'],
593  true
594  );
595  foreach ($items as $key => $itemValues) {
596  if (in_array($itemValues[1], $removeItems)) {
597  unset($items[$key]);
598  }
599  }
600 
601  return $items;
602  }
603 
614  protected function removeItemsByUserLanguageFieldRestriction(array $result, $fieldName, array $items)
615  {
616  // Guard clause returns if not a language field is handled
617  if (empty($result['processedTca']['ctrl']['languageField'])
618  || $result['processedTca']['ctrl']['languageField'] !== $fieldName
619  ) {
620  return $items;
621  }
622 
623  $backendUser = $this->getBackendUser();
624  foreach ($items as $key => $itemValues) {
625  if (!$backendUser->checkLanguageAccess($itemValues[1])) {
626  unset($items[$key]);
627  }
628  }
629 
630  return $items;
631  }
632 
643  protected function removeItemsByUserAuthMode(array $result, $fieldName, array $items)
644  {
645  // Guard clause returns early if no authMode field is configured
646  if (!isset($result['processedTca']['columns'][$fieldName]['config']['authMode'])
647  || !is_string($result['processedTca']['columns'][$fieldName]['config']['authMode'])
648  ) {
649  return $items;
650  }
651 
652  $backendUser = $this->getBackendUser();
653  $authMode = $result['processedTca']['columns'][$fieldName]['config']['authMode'];
654  foreach ($items as $key => $itemValues) {
655  // @todo: checkAuthMode() uses $GLOBAL access for "individual" authMode - get rid of this
656  if (!$backendUser->checkAuthMode($result['tableName'], $fieldName, $itemValues[1], $authMode)) {
657  unset($items[$key]);
658  }
659  }
660 
661  return $items;
662  }
663 
674  protected function removeItemsByDoktypeUserRestriction(array $result, $fieldName, array $items)
675  {
676  $table = $result['tableName'];
677  $backendUser = $this->getBackendUser();
678  // Guard clause returns if not correct table and field or if user is admin
679  if ($table !== 'pages' && $table !== 'pages_language_overlay'
680  || $fieldName !== 'doktype' || $backendUser->isAdmin()
681  ) {
682  return $items;
683  }
684 
685  $allowedPageTypes = $backendUser->groupData['pagetypes_select'];
686  foreach ($items as $key => $itemValues) {
687  if (!GeneralUtility::inList($allowedPageTypes, $itemValues[1])) {
688  unset($items[$key]);
689  }
690  }
691 
692  return $items;
693  }
694 
702  protected function getExcludeFields()
703  {
704  $languageService = $this->getLanguageService();
705  $finalExcludeArray = [];
706 
707  // Fetch translations for table names
708  $tableToTranslation = [];
709  // All TCA keys
710  foreach ($GLOBALS['TCA'] as $table => $conf) {
711  $tableToTranslation[$table] = $languageService->sL($conf['ctrl']['title']);
712  }
713  // Sort by translations
714  asort($tableToTranslation);
715  foreach ($tableToTranslation as $table => $translatedTable) {
716  $excludeArrayTable = [];
717 
718  // All field names configured and not restricted to admins
719  if (is_array($GLOBALS['TCA'][$table]['columns'])
720  && empty($GLOBALS['TCA'][$table]['ctrl']['adminOnly'])
721  && (empty($GLOBALS['TCA'][$table]['ctrl']['rootLevel']) || !empty($GLOBALS['TCA'][$table]['ctrl']['security']['ignoreRootLevelRestriction']))
722  ) {
723  foreach ($GLOBALS['TCA'][$table]['columns'] as $field => $_) {
724  if ($GLOBALS['TCA'][$table]['columns'][$field]['exclude']) {
725  // Get human readable names of fields
726  $translatedField = $languageService->sL($GLOBALS['TCA'][$table]['columns'][$field]['label']);
727  // Add entry, key 'labels' needed for sorting
728  $excludeArrayTable[] = [
729  'labels' => $translatedTable . ':' . $translatedField,
730  'sectionHeader' => $translatedTable,
731  'table' => $table,
732  'tableField' => $field,
733  'fieldName' => $field,
734  'fullField' => $field,
735  'fieldLabel' => $translatedField,
736  'origin' => 'tca',
737  ];
738  }
739  }
740  }
741  // All FlexForm fields
742  $flexFormArray = $this->getRegisteredFlexForms($table);
743  foreach ($flexFormArray as $tableField => $flexForms) {
744  // Prefix for field label, e.g. "Plugin Options:"
745  $labelPrefix = '';
746  if (!empty($GLOBALS['TCA'][$table]['columns'][$tableField]['label'])) {
747  $labelPrefix = $languageService->sL($GLOBALS['TCA'][$table]['columns'][$tableField]['label']);
748  }
749  // Get all sheets
750  foreach ($flexForms as $extIdent => $extConf) {
751  // Get all fields in sheet
752  foreach ($extConf['sheets'] as $sheetName => $sheet) {
753  if (empty($sheet['ROOT']['el']) || !is_array($sheet['ROOT']['el'])) {
754  continue;
755  }
756  foreach ($sheet['ROOT']['el'] as $pluginFieldName => $field) {
757  // Use only fields that have exclude flag set
758  if (empty($field['TCEforms']['exclude'])) {
759  continue;
760  }
761  $fieldLabel = !empty($field['TCEforms']['label'])
762  ? $languageService->sL($field['TCEforms']['label'])
763  : $pluginFieldName;
764  $excludeArrayTable[] = [
765  'labels' => trim($translatedTable . ' ' . $labelPrefix . ' ' . $extIdent, ': ') . ':' . $fieldLabel,
766  'sectionHeader' => trim(($translatedTable . ' ' . $labelPrefix . ' ' . $extIdent), ':'),
767  'table' => $table,
768  'tableField' => $tableField,
769  'extIdent' => $extIdent,
770  'fieldName' => $pluginFieldName,
771  'fullField' => $tableField . ';' . $extIdent . ';' . $sheetName . ';' . $pluginFieldName,
772  'fieldLabel' => $fieldLabel,
773  'origin' => 'flexForm',
774  ];
775  }
776  }
777  }
778  }
779  // Sort fields by the translated value
780  if (!empty($excludeArrayTable)) {
781  usort($excludeArrayTable, function (array $array1, array $array2) {
782  $array1 = reset($array1);
783  $array2 = reset($array2);
784  if (is_string($array1) && is_string($array2)) {
785  return strcasecmp($array1, $array2);
786  }
787  return 0;
788  });
789  $finalExcludeArray = array_merge($finalExcludeArray, $excludeArrayTable);
790  }
791  }
792 
793  return $finalExcludeArray;
794  }
795 
814  protected function getRegisteredFlexForms($table)
815  {
816  if (empty($table) || empty($GLOBALS['TCA'][$table]['columns'])) {
817  return [];
818  }
819  $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
820  $flexForms = [];
821  foreach ($GLOBALS['TCA'][$table]['columns'] as $tableField => $fieldConf) {
822  if (!empty($fieldConf['config']['type']) && !empty($fieldConf['config']['ds']) && $fieldConf['config']['type'] == 'flex') {
823  $flexForms[$tableField] = [];
824  foreach (array_keys($fieldConf['config']['ds']) as $flexFormKey) {
825  // Get extension identifier (uses second value if it's not empty, "list" or "*", else first one)
826  $identFields = GeneralUtility::trimExplode(',', $flexFormKey);
827  $extIdent = $identFields[0];
828  if (!empty($identFields[1]) && $identFields[1] !== 'list' && $identFields[1] !== '*') {
829  $extIdent = $identFields[1];
830  }
831  $flexFormDataStructureIdentifier = json_encode([
832  'type' => 'tca',
833  'tableName' => $table,
834  'fieldName' => $tableField,
835  'dataStructureKey' => $flexFormKey,
836  ]);
837  try {
838  $dataStructure = $flexFormTools->parseDataStructureByIdentifier($flexFormDataStructureIdentifier);
839  $flexForms[$tableField][$extIdent] = $dataStructure;
840  } catch (InvalidIdentifierException $e) {
841  // Deliberately empty: The DS identifier is guesswork and the flex ds parser throws
842  // this exception if it can not resolve to a valid data structure. This is "ok" here
843  // and the exception is just eaten.
844  }
845  }
846  }
847  }
848  return $flexForms;
849  }
850 
857  protected function getExplicitAuthFieldValues()
858  {
859  $languageService = static::getLanguageService();
860  $adLabel = [
861  'ALLOW' => $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.allow'),
862  'DENY' => $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.deny')
863  ];
864  $allowDenyOptions = [];
865  foreach ($GLOBALS['TCA'] as $table => $_) {
866  // All field names configured:
867  if (is_array($GLOBALS['TCA'][$table]['columns'])) {
868  foreach ($GLOBALS['TCA'][$table]['columns'] as $field => $__) {
869  $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
870  if ($fieldConfig['type'] === 'select' && $fieldConfig['authMode']) {
871  // Check for items
872  if (is_array($fieldConfig['items'])) {
873  // Get Human Readable names of fields and table:
874  $allowDenyOptions[$table . ':' . $field]['tableFieldLabel'] =
875  $languageService->sL($GLOBALS['TCA'][$table]['ctrl']['title']) . ': '
876  . $languageService->sL($GLOBALS['TCA'][$table]['columns'][$field]['label']);
877  foreach ($fieldConfig['items'] as $iVal) {
878  // Values '' is not controlled by this setting.
879  if ((string)$iVal[1] !== '') {
880  // Find iMode
881  $iMode = '';
882  switch ((string)$fieldConfig['authMode']) {
883  case 'explicitAllow':
884  $iMode = 'ALLOW';
885  break;
886  case 'explicitDeny':
887  $iMode = 'DENY';
888  break;
889  case 'individual':
890  if ($iVal[4] === 'EXPL_ALLOW') {
891  $iMode = 'ALLOW';
892  } elseif ($iVal[4] === 'EXPL_DENY') {
893  $iMode = 'DENY';
894  }
895  break;
896  }
897  // Set iMode
898  if ($iMode) {
899  $allowDenyOptions[$table . ':' . $field]['items'][$iVal[1]] = [
900  $iMode,
901  $languageService->sL($iVal[0]),
902  $adLabel[$iMode]
903  ];
904  }
905  }
906  }
907  }
908  }
909  }
910  }
911  }
912  return $allowDenyOptions;
913  }
914 
923  protected function buildForeignTableQueryBuilder(array $result, string $localFieldName): QueryBuilder
924  {
925  $backendUser = $this->getBackendUser();
926 
927  $foreignTableName = $result['processedTca']['columns'][$localFieldName]['config']['foreign_table'];
928  $foreignTableClauseArray = $this->processForeignTableClause($result, $foreignTableName, $localFieldName);
929 
930  $fieldList = BackendUtility::getCommonSelectFields($foreignTableName, $foreignTableName . '.');
931  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
932  ->getQueryBuilderForTable($foreignTableName);
933 
934  $queryBuilder->getRestrictions()
935  ->removeAll()
936  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
937 
938  $queryBuilder
939  ->select(...GeneralUtility::trimExplode(',', $fieldList, true))
940  ->from($foreignTableName)
941  ->where($foreignTableClauseArray['WHERE']);
942 
943  if (!empty($foreignTableClauseArray['GROUPBY'])) {
944  $queryBuilder->groupBy($foreignTableClauseArray['GROUPBY']);
945  }
946 
947  if (!empty($foreignTableClauseArray['ORDERBY'])) {
948  foreach ($foreignTableClauseArray['ORDERBY'] as $orderPair) {
949  list($fieldName, $order) = $orderPair;
950  $queryBuilder->addOrderBy($fieldName, $order);
951  }
952  }
953 
954  if (!empty($foreignTableClauseArray['LIMIT'])) {
955  if (!empty($foreignTableClauseArray['LIMIT'][1])) {
956  $queryBuilder->setMaxResults($foreignTableClauseArray['LIMIT'][1]);
957  $queryBuilder->setFirstResult($foreignTableClauseArray['LIMIT'][0]);
958  } elseif (!empty($foreignTableClauseArray['LIMIT'][0])) {
959  $queryBuilder->setMaxResults($foreignTableClauseArray['LIMIT'][0]);
960  }
961  }
962 
963  // rootLevel = -1 means that elements can be on the rootlevel OR on any page (pid!=-1)
964  // rootLevel = 0 means that elements are not allowed on root level
965  // rootLevel = 1 means that elements are only on the root level (pid=0)
966  $rootLevel = 0;
967  if (isset($GLOBALS['TCA'][$foreignTableName]['ctrl']['rootLevel'])) {
968  $rootLevel = (int)$GLOBALS['TCA'][$foreignTableName]['ctrl']['rootLevel'];
969  }
970 
971  if ($rootLevel === -1) {
972  $queryBuilder->andWhere(
973  $queryBuilder->expr()->neq(
974  $foreignTableName . '.pid',
975  $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
976  )
977  );
978  } elseif ($rootLevel === 1) {
979  $queryBuilder->andWhere(
980  $queryBuilder->expr()->eq(
981  $foreignTableName . '.pid',
982  $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
983  )
984  );
985  } else {
986  $queryBuilder->andWhere($backendUser->getPagePermsClause(1));
987  if ($foreignTableName !== 'pages') {
988  $queryBuilder
989  ->from('pages')
990  ->andWhere(
991  $queryBuilder->expr()->eq(
992  'pages.uid',
993  $queryBuilder->quoteIdentifier($foreignTableName . '.pid')
994  )
995  );
996  }
997  }
998 
999  return $queryBuilder;
1000  }
1001 
1018  protected function processForeignTableClause(array $result, $foreignTableName, $localFieldName)
1019  {
1020  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($foreignTableName);
1021  $localTable = $result['tableName'];
1022  $effectivePid = $result['effectivePid'];
1023 
1024  $foreignTableClause = '';
1025  if (!empty($result['processedTca']['columns'][$localFieldName]['config']['foreign_table_where'])
1026  && is_string($result['processedTca']['columns'][$localFieldName]['config']['foreign_table_where'])
1027  ) {
1028  $foreignTableClause = $result['processedTca']['columns'][$localFieldName]['config']['foreign_table_where'];
1029  // Replace possible markers in query
1030  if (strstr($foreignTableClause, '###REC_FIELD_')) {
1031  // " AND table.field='###REC_FIELD_field1###' AND ..." -> array(" AND table.field='", "field1###' AND ...")
1032  $whereClauseParts = explode('###REC_FIELD_', $foreignTableClause);
1033  foreach ($whereClauseParts as $key => $value) {
1034  if ($key !== 0) {
1035  // "field1###' AND ..." -> array("field1", "' AND ...")
1036  $whereClauseSubParts = explode('###', $value, 2);
1037  // @todo: Throw exception if there is no value? What happens for NEW records?
1038  $databaseRowKey = empty($result['flexParentDatabaseRow']) ? 'databaseRow' : 'flexParentDatabaseRow';
1039  $rowFieldValue = isset($result[$databaseRowKey][$whereClauseSubParts[0]]) ? $result[$databaseRowKey][$whereClauseSubParts[0]] : '';
1040  if (is_array($rowFieldValue)) {
1041  // If a select or group field is used here, it may have been processed already and
1042  // is now an array. Use first selected value in this case.
1043  $rowFieldValue = $rowFieldValue[0];
1044  }
1045  if (substr($whereClauseParts[0], -1) === '\'' && $whereClauseSubParts[1][0] === '\'') {
1046  $whereClauseParts[0] = substr($whereClauseParts[0], 0, -1);
1047  $whereClauseSubParts[1] = substr($whereClauseSubParts[1], 1);
1048  }
1049  $whereClauseParts[$key] = $connection->quote($rowFieldValue) . $whereClauseSubParts[1];
1050  }
1051  }
1052  $foreignTableClause = implode('', $whereClauseParts);
1053  }
1054  // Use pid from parent page clause if in flex flom context
1055  if (strpos($foreignTableClause, '###CURRENT_PID###') !== false
1056  && !empty($result['flexParentDatabaseRow']['pid'])
1057  ) {
1058  $effectivePid = $result['flexParentDatabaseRow']['pid'];
1059  }
1060 
1061  $siteRootUid = 0;
1062  foreach ($result['rootline'] as $rootlinePage) {
1063  if (!empty($rootlinePage['is_siteroot'])) {
1064  $siteRootUid = (int)$rootlinePage['uid'];
1065  break;
1066  }
1067  }
1068 
1069  $pageTsConfigId = 0;
1070  if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_ID']) {
1071  // @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess
1072  $pageTsConfigId = (int)$result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_ID'];
1073  }
1074  if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID']) {
1075  $pageTsConfigId = (int)$result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID'];
1076  }
1077 
1078  $pageTsConfigIdList = 0;
1079  if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_IDLIST']) {
1080  // @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess
1081  $pageTsConfigIdList = $result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_IDLIST'];
1082  }
1083  if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST']) {
1084  $pageTsConfigIdList = $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST'];
1085  }
1086  $pageTsConfigIdListArray = GeneralUtility::trimExplode(',', $pageTsConfigIdList, true);
1087  $pageTsConfigIdList = [];
1088  foreach ($pageTsConfigIdListArray as $pageTsConfigIdListElement) {
1089  if (MathUtility::canBeInterpretedAsInteger($pageTsConfigIdListElement)) {
1090  $pageTsConfigIdList[] = (int)$pageTsConfigIdListElement;
1091  }
1092  }
1093  $pageTsConfigIdList = implode(',', $pageTsConfigIdList);
1094 
1095  $pageTsConfigString = '';
1096  if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_STR']) {
1097  // @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess
1098  $pageTsConfigString = $connection->quote($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_STR']);
1099  }
1100  if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR']) {
1101  $pageTsConfigString = $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR'];
1102  $pageTsConfigString = $connection->quote($pageTsConfigString);
1103  }
1104 
1105  $foreignTableClause = str_replace(
1106  [
1107  '###CURRENT_PID###',
1108  '###THIS_UID###',
1109  '###SITEROOT###',
1110  '###PAGE_TSCONFIG_ID###',
1111  '###PAGE_TSCONFIG_IDLIST###',
1112  '\'###PAGE_TSCONFIG_STR###\'',
1113  '###PAGE_TSCONFIG_STR###'
1114  ],
1115  [
1116  (int)$effectivePid,
1117  (int)$result['databaseRow']['uid'],
1118  $siteRootUid,
1119  $pageTsConfigId,
1120  $pageTsConfigIdList,
1121  $pageTsConfigString,
1122  $pageTsConfigString
1123  ],
1124  $foreignTableClause
1125  );
1126  }
1127 
1128  // Split the clause into an array with keys WHERE, GROUPBY, ORDERBY, LIMIT
1129  // Prepend a space to make sure "[[:space:]]+" will find a space there for the first element.
1130  $foreignTableClause = ' ' . $foreignTableClause;
1131  $foreignTableClauseArray = [
1132  'WHERE' => '',
1133  'GROUPBY' => '',
1134  'ORDERBY' => '',
1135  'LIMIT' => '',
1136  ];
1137  // Find LIMIT
1138  $reg = [];
1139  if (preg_match('/^(.*)[[:space:]]+LIMIT[[:space:]]+([[:alnum:][:space:],._]+)$/i', $foreignTableClause, $reg)) {
1140  $foreignTableClauseArray['LIMIT'] = GeneralUtility::intExplode(',', trim($reg[2]), true);
1141  $foreignTableClause = $reg[1];
1142  }
1143  // Find ORDER BY
1144  $reg = [];
1145  if (preg_match('/^(.*)[[:space:]]+ORDER[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._]+)$/i', $foreignTableClause, $reg)) {
1146  $foreignTableClauseArray['ORDERBY'] = QueryHelper::parseOrderBy(trim($reg[2]));
1147  $foreignTableClause = $reg[1];
1148  }
1149  // Find GROUP BY
1150  $reg = [];
1151  if (preg_match('/^(.*)[[:space:]]+GROUP[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._]+)$/i', $foreignTableClause, $reg)) {
1152  $foreignTableClauseArray['GROUPBY'] = QueryHelper::parseGroupBy(trim($reg[2]));
1153  $foreignTableClause = $reg[1];
1154  }
1155  // Rest is assumed to be "WHERE" clause
1156  $foreignTableClauseArray['WHERE'] = QueryHelper::stripLogicalOperatorPrefix($foreignTableClause);
1157 
1158  return $foreignTableClauseArray;
1159  }
1160 
1168  protected function processDatabaseFieldValue(array $row, $fieldName)
1169  {
1170  $currentDatabaseValues = array_key_exists($fieldName, $row)
1171  ? $row[$fieldName]
1172  : '';
1173  return GeneralUtility::trimExplode(',', $currentDatabaseValues, true);
1174  }
1175 
1187  protected function processSelectFieldValue(array $result, $fieldName, array $staticValues)
1188  {
1189  $fieldConfig = $result['processedTca']['columns'][$fieldName];
1190 
1191  $currentDatabaseValueArray = array_key_exists($fieldName, $result['databaseRow']) ? $result['databaseRow'][$fieldName] : [];
1192  $newDatabaseValueArray = [];
1193 
1194  // Add all values that were defined by static methods and do not come from the relation
1195  // e.g. TCA, TSconfig, itemProcFunc etc.
1196  foreach ($currentDatabaseValueArray as $value) {
1197  if (isset($staticValues[$value])) {
1198  $newDatabaseValueArray[] = $value;
1199  }
1200  }
1201 
1202  if (isset($fieldConfig['config']['foreign_table']) && !empty($fieldConfig['config']['foreign_table'])) {
1204  $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
1205  $relationHandler->registerNonTableValues = !empty($fieldConfig['config']['allowNonIdValues']);
1206  if (!empty($fieldConfig['config']['MM']) && $result['command'] !== 'new') {
1207  // MM relation
1208  $relationHandler->start(
1209  implode(',', $currentDatabaseValueArray),
1210  $fieldConfig['config']['foreign_table'],
1211  $fieldConfig['config']['MM'],
1212  $result['databaseRow']['uid'],
1213  $result['tableName'],
1214  $fieldConfig['config']
1215  );
1216  } else {
1217  // Non MM relation
1218  // If not dealing with MM relations, use default live uid, not versioned uid for record relations
1219  $relationHandler->start(
1220  implode(',', $currentDatabaseValueArray),
1221  $fieldConfig['config']['foreign_table'],
1222  '',
1223  $this->getLiveUid($result),
1224  $result['tableName'],
1225  $fieldConfig['config']
1226  );
1227  }
1228  $newDatabaseValueArray = array_merge($newDatabaseValueArray, $relationHandler->getValueArray());
1229  }
1230 
1231  if ($fieldConfig['config']['multiple']) {
1232  return $newDatabaseValueArray;
1233  }
1234  return array_unique($newDatabaseValueArray);
1235  }
1236 
1248  public function translateLabels(array $result, array $itemArray, $table, $fieldName)
1249  {
1250  $languageService = $this->getLanguageService();
1251 
1252  foreach ($itemArray as $key => $item) {
1253  if (!isset($dynamicItems[$key])) {
1254  $staticValues[$item[1]] = $item;
1255  }
1256  if (isset($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['altLabels.'][$item[1]])
1257  && !empty($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['altLabels.'][$item[1]])
1258  ) {
1259  $label = $languageService->sL($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['altLabels.'][$item[1]]);
1260  } else {
1261  $label = $languageService->sL(trim($item[0]));
1262  }
1263  $value = strlen((string)$item[1]) > 0 ? $item[1] : '';
1264  $icon = $item[2] ?: null;
1265  $helpText = $item[3] ?: null;
1266  $itemArray[$key] = [
1267  $label,
1268  $value,
1269  $icon,
1270  $helpText
1271  ];
1272  }
1273 
1274  return $itemArray;
1275  }
1276 
1288  public function sanitizeItemArray($itemArray, $tableName, $fieldName)
1289  {
1290  if (!is_array($itemArray)) {
1291  $itemArray = [];
1292  }
1293  foreach ($itemArray as $item) {
1294  if (!is_array($item)) {
1295  throw new \UnexpectedValueException(
1296  'An item in field ' . $fieldName . ' of table ' . $tableName . ' is not an array as expected',
1297  1439288036
1298  );
1299  }
1300  }
1301 
1302  return $itemArray;
1303  }
1304 
1313  public function sanitizeMaxItems($maxItems)
1314  {
1315  if (!empty($maxItems)
1316  && (int)$maxItems > 1
1317  ) {
1318  $maxItems = (int)$maxItems;
1319  } else {
1320  $maxItems = 1;
1321  }
1322 
1323  return $maxItems;
1324  }
1325 
1334  protected function getLiveUid(array $result)
1335  {
1336  $table = $result['tableName'];
1337  $row = $result['databaseRow'];
1338  $uid = $row['uid'];
1339  if (!empty($result['processedTca']['ctrl']['versioningWS'])
1340  && $result['pid'] === -1
1341  ) {
1342  if (empty($row['t3ver_oid'])) {
1343  throw new \UnexpectedValueException(
1344  'No t3ver_oid found for record ' . $row['uid'] . ' on table ' . $table,
1345  1440066481
1346  );
1347  }
1348  $uid = $row['t3ver_oid'];
1349  }
1350  return $uid;
1351  }
1352 
1363  protected function getStaticValues($itemArray, $dynamicItemArray)
1364  {
1365  $staticValues = [];
1366  foreach ($itemArray as $key => $item) {
1367  if (!isset($dynamicItemArray[$key])) {
1368  $staticValues[$item[1]] = $item;
1369  }
1370  }
1371  return $staticValues;
1372  }
1373 
1377  protected function getLanguageService()
1378  {
1379  return $GLOBALS['LANG'];
1380  }
1381 
1385  protected function getBackendUser()
1386  {
1387  return $GLOBALS['BE_USER'];
1388  }
1389 }
removeItemsByRemoveItemsPageTsConfig(array $result, $fieldName, array $items)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static keepItemsInArray(array $array, $keepItems, $getValueFunc=null)
removeItemsByKeepItemsPageTsConfig(array $result, $fieldName, array $items)
static getRecordTitle($table, $row, $prep=false, $forceResult=true)
static removePrefixPathFromList(array $fileArr, $prefixToRemove)
removeItemsByUserLanguageFieldRestriction(array $result, $fieldName, array $items)
static workspaceOL($table, &$row, $wsid=-99, $unsetMovePointers=false)
static getCommonSelectFields($table, $prefix= '', $fields=[])
buildForeignTableQueryBuilder(array $result, string $localFieldName)
processForeignTableClause(array $result, $foreignTableName, $localFieldName)
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static makeInstance($className,...$constructorArguments)
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
static stripLogicalOperatorPrefix(string $constraint)
static getFileAbsFileName($filename, $_=null, $_2=null)
translateLabels(array $result, array $itemArray, $table, $fieldName)
static intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
addItemsFromPageTsConfig(array $result, $fieldName, array $items)
static callUserFunction($funcName, &$params, &$ref, $_= '', $errorMode=0)
removeItemsByDoktypeUserRestriction(array $result, $fieldName, array $items)
removeItemsByUserAuthMode(array $result, $fieldName, array $items)
static getAllFilesAndFoldersInPath(array $fileArr, $path, $extList= '', $regDirs=false, $recursivityLevels=99, $excludePattern= '')