‪TYPO3CMS  ‪main
TcaSelectItems.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 
23 
28 {
35  public function ‪addData(array $result)
36  {
37  $selectItemProcessor = GeneralUtility::makeInstance(SelectItemProcessor::class);
38  $table = $result['tableName'];
39 
40  foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
41  if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'select') {
42  continue;
43  }
44 
45  // Make sure we are only processing supported renderTypes
46  if (!$this->‪isTargetRenderType($fieldConfig)) {
47  continue;
48  }
49 
50  $fieldConfig['config']['items'] = $this->‪sanitizeItemArray($fieldConfig['config']['items'] ?? [], $table, $fieldName);
51 
52  $fieldConfig['config']['maxitems'] = ‪MathUtility::forceIntegerInRange($fieldConfig['config']['maxitems'] ?? 0, 0, 99999);
53  if ($fieldConfig['config']['maxitems'] === 0) {
54  $fieldConfig['config']['maxitems'] = 99999;
55  }
56 
57  $fieldConfig['config']['items'] = $this->‪addItemsFromFolder($result, $fieldName, $fieldConfig['config']['items']);
58 
59  $fieldConfig['config']['items'] = $this->‪addItemsFromForeignTable($result, $fieldName, $fieldConfig['config']['items']);
60 
61  // Resolve "itemsProcFunc"
62  if (!empty($fieldConfig['config']['itemsProcFunc'])) {
63  $fieldConfig['config']['items'] = $this->‪resolveItemProcessorFunction($result, $fieldName, $fieldConfig['config']['items']);
64  // itemsProcFunc must not be used anymore
65  unset($fieldConfig['config']['itemsProcFunc']);
66  }
67 
68  // removing items before $dynamicItems and $removedItems have been built results in having them
69  // not populated to the dynamic database row and displayed as "invalid value" in the forms view
70  $fieldConfig['config']['items'] = $this->‪removeItemsByUserStorageRestriction($result, $fieldName, $fieldConfig['config']['items']);
71 
72  $removedItems = $fieldConfig['config']['items'];
73 
74  $fieldConfig['config']['items'] = $this->‪removeItemsByKeepItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
75  $fieldConfig['config']['items'] = $this->‪addItemsFromPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
76  $fieldConfig['config']['items'] = $this->‪removeItemsByRemoveItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
77 
78  $fieldConfig['config']['items'] = $this->‪removeItemsByUserLanguageFieldRestriction($result, $fieldName, $fieldConfig['config']['items']);
79  $fieldConfig['config']['items'] = $this->‪removeItemsByUserAuthMode($result, $fieldName, $fieldConfig['config']['items']);
80  $fieldConfig['config']['items'] = $this->‪removeItemsByDoktypeUserRestriction($result, $fieldName, $fieldConfig['config']['items']);
81 
82  $removedItems = array_diff_key($removedItems, $fieldConfig['config']['items']);
83 
84  $currentDatabaseValuesArray = $this->‪processDatabaseFieldValue($result['databaseRow'], $fieldName);
85  // Check if it's a new record to respect TCAdefaults
86  if (!empty($fieldConfig['config']['MM']) && $result['command'] !== 'new') {
87  // Getting the current database value on a mm relation doesn't make sense since the amount of selected
88  // relations is stored in the field and not the uids of the items
89  $currentDatabaseValuesArray = [];
90  }
91 
92  $result['databaseRow'][$fieldName] = $currentDatabaseValuesArray;
93 
94  // add item values as keys to determine which items are stored in the database and should be preselected
95  $itemArrayValues = array_column(
96  array_map(fn(‪SelectItem|array $item): array => $item instanceof ‪SelectItem ? $item->‪toArray() : $item, $fieldConfig['config']['items']),
97  'value'
98  );
99  $itemArray = array_fill_keys(
100  $itemArrayValues,
101  $fieldConfig['config']['items']
102  );
103  $result['databaseRow'][$fieldName] = $this->‪processSelectFieldValue($result, $fieldName, $itemArray);
104 
105  $fieldConfig['config']['items'] = $this->‪addInvalidItemsFromDatabase(
106  $result,
107  $table,
108  $fieldName,
109  $fieldConfig,
110  $currentDatabaseValuesArray,
111  $removedItems
112  );
113 
114  // Translate labels and add icons
115  // skip file of sys_file_metadata which is not rendered anyway but can use all memory
116  if (!($table === 'sys_file_metadata' && $fieldName === 'file')) {
117  $fieldConfig['config']['items'] = $this->‪translateLabels($result, $fieldConfig['config']['items'], $table, $fieldName);
118  $fieldConfig['config']['items'] = $this->‪addIconFromAltIcons($result, $fieldConfig['config']['items'], $table, $fieldName);
119  }
120 
121  // Keys may contain table names, so a numeric array is created
122  $fieldConfig['config']['items'] = array_values($fieldConfig['config']['items']);
123 
124  $fieldConfig['config']['items'] = $selectItemProcessor->groupAndSortItems(
125  $fieldConfig['config']['items'],
126  $fieldConfig['config']['itemGroups'] ?? [],
127  $fieldConfig['config']['sortItems'] ?? []
128  );
129 
130  $result['processedTca']['columns'][$fieldName] = $fieldConfig;
131  }
132 
133  return $result;
134  }
135 
148  public function ‪addInvalidItemsFromDatabase(array $result, $table, $fieldName, array $fieldConf, array $databaseValues, array $removedItems)
149  {
150  // Early return if there are no items or invalid values should not be displayed
151  if (empty($fieldConf['config']['items'])
152  || $fieldConf['config']['renderType'] !== 'selectSingle'
153  || ($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['disableNoMatchingValueElement'] ?? false)
154  || ($fieldConf['config']['disableNoMatchingValueElement'] ?? false)
155  ) {
156  return $fieldConf['config']['items'];
157  }
158 
159  $languageService = $this->‪getLanguageService();
160  $noMatchingLabel = isset($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['noMatchingValue_label'])
161  ? $languageService->sL(trim($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['noMatchingValue_label']))
162  : '[ ' . $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue') . ' ]';
163 
164  $unmatchedValues = array_diff(
165  array_values($databaseValues),
166  array_column(
167  array_map(
168  fn(‪SelectItem|array $item): array => $item instanceof ‪SelectItem ? $item->‪toArray() : $item,
169  $fieldConf['config']['items']
170  ),
171  'value'
172  ),
173  array_column(
174  array_map(
175  fn(‪SelectItem|array $item): array => $item instanceof ‪SelectItem ? $item->‪toArray() : $item,
176  $removedItems
177  ),
178  'value'
179  )
180  );
181 
182  foreach ($unmatchedValues as $unmatchedValue) {
183  $invalidItem = [
184  'label' => @sprintf($noMatchingLabel, $unmatchedValue),
185  'value' => $unmatchedValue,
186  'icon' => null,
187  'group' => 'none', // put it in the very first position in the "none" group
188  ];
189  array_unshift($fieldConf['config']['items'], $invalidItem);
190  }
191 
192  return $fieldConf['config']['items'];
193  }
194 
200  protected function ‪isTargetRenderType(array $fieldConfig)
201  {
202  return $fieldConfig['config']['renderType'] !== 'selectTree';
203  }
204 }
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\sanitizeItemArray
‪array sanitizeItemArray($itemArray, $tableName, $fieldName)
Definition: AbstractItemProvider.php:1104
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\addItemsFromPageTsConfig
‪array addItemsFromPageTsConfig(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:147
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems\addData
‪array addData(array $result)
Definition: TcaSelectItems.php:35
‪TYPO3\CMS\Core\Schema\Struct\SelectItem\toArray
‪toArray()
Definition: SelectItem.php:62
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByUserLanguageFieldRestriction
‪array removeItemsByUserLanguageFieldRestriction(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:448
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\addIconFromAltIcons
‪addIconFromAltIcons(array $result, array $items, string $table, string $fieldName)
Definition: AbstractItemProvider.php:1080
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\translateLabels
‪array translateLabels(array $result, array $itemArray, $table, $fieldName)
Definition: AbstractItemProvider.php:1040
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\addItemsFromForeignTable
‪array addItemsFromForeignTable(array $result, $fieldName, array $items, bool $includeFullRows=false)
Definition: AbstractItemProvider.php:266
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems\isTargetRenderType
‪bool isTargetRenderType(array $fieldConfig)
Definition: TcaSelectItems.php:200
‪TYPO3\CMS\Core\Schema\Struct\SelectItem
Definition: SelectItem.php:21
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByUserStorageRestriction
‪array removeItemsByUserStorageRestriction(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:536
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\resolveItemProcessorFunction
‪array resolveItemProcessorFunction(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:59
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByDoktypeUserRestriction
‪array removeItemsByDoktypeUserRestriction(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:506
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems
Definition: TcaSelectItems.php:28
‪TYPO3\CMS\Backend\Form\FormDataProvider
Definition: AbstractDatabaseRecordProvider.php:16
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor
Definition: SelectItemProcessor.php:33
‪TYPO3\CMS\Backend\Form\FormDataProviderInterface
Definition: FormDataProviderInterface.php:23
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\getLanguageService
‪getLanguageService()
Definition: AbstractItemProvider.php:1140
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByKeepItemsPageTsConfig
‪array removeItemsByKeepItemsPageTsConfig(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:381
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\processDatabaseFieldValue
‪array processDatabaseFieldValue(array $row, $fieldName)
Definition: AbstractItemProvider.php:953
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\processSelectFieldValue
‪array processSelectFieldValue(array $result, $fieldName, array $staticValues)
Definition: AbstractItemProvider.php:975
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems\addInvalidItemsFromDatabase
‪array addInvalidItemsFromDatabase(array $result, $table, $fieldName, array $fieldConf, array $databaseValues, array $removedItems)
Definition: TcaSelectItems.php:148
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByUserAuthMode
‪array removeItemsByUserAuthMode(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:477
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange(mixed $theInt, int $min, int $max=2000000000, int $defaultValue=0)
Definition: MathUtility.php:34
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\addItemsFromFolder
‪array addItemsFromFolder(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:194
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider
Definition: AbstractItemProvider.php:50
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByRemoveItemsPageTsConfig
‪array removeItemsByRemoveItemsPageTsConfig(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:414