‪TYPO3CMS  10.4
TcaSelectTreeItems.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 
26 
39 {
47  public function ‪addData(array $result)
48  {
49  $table = $result['tableName'];
50 
51  foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
52  if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'select') {
53  continue;
54  }
55 
56  // Make sure we are only processing supported renderTypes
57  if (!$this->‪isTargetRenderType($fieldConfig)) {
58  continue;
59  }
60 
61  $fieldConfig['config']['maxitems'] = ‪MathUtility::forceIntegerInRange($fieldConfig['config']['maxitems'], 0, 99999);
62  if ($fieldConfig['config']['maxitems'] === 0) {
63  $fieldConfig['config']['maxitems'] = 99999;
64  }
65 
66  // A couple of tree specific config parameters can be overwritten via page TS.
67  // Pick those that influence the data fetching and write them into the config
68  // given to the tree data provider. This is additionally used in SelectTreeElement, so always do that.
69  if (isset($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['config.']['treeConfig.'])) {
70  $pageTsConfig = $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['config.']['treeConfig.'];
71  // If rootUid is set in pageTsConfig, use it
72  if (isset($pageTsConfig['rootUid'])) {
73  $fieldConfig['config']['treeConfig']['rootUid'] = (int)$pageTsConfig['rootUid'];
74  }
75  if (isset($pageTsConfig['appearance.']['expandAll'])) {
76  $fieldConfig['config']['treeConfig']['appearance']['expandAll'] = (bool)$pageTsConfig['appearance.']['expandAll'];
77  }
78  if (isset($pageTsConfig['appearance.']['maxLevels'])) {
79  $fieldConfig['config']['treeConfig']['appearance']['maxLevels'] = (int)$pageTsConfig['appearance.']['maxLevels'];
80  }
81  if (isset($pageTsConfig['appearance.']['nonSelectableLevels'])) {
82  $fieldConfig['config']['treeConfig']['appearance']['nonSelectableLevels'] = $pageTsConfig['appearance.']['nonSelectableLevels'];
83  }
84  }
85 
86  // Prepare the list of currently selected nodes using RelationHandler
87  // This is needed to ensure a correct value initialization before the actual tree is loaded
88  $result['databaseRow'][$fieldName] = $this->‪processDatabaseFieldValue($result['databaseRow'], $fieldName);
89  $result['databaseRow'][$fieldName] = $this->‪processSelectFieldValue($result, $fieldName, []);
90 
91  if ($result['selectTreeCompileItems']) {
92  $finalItems = [];
93 
94  // Prepare the list of "static" items if there are any.
95  // "static" and "dynamic" is separated since the tree code only copes with "real" existing foreign nodes,
96  // so this "static" stuff allows defining tree items that don't really exist in the tree.
97  $itemsFromTca = $this->‪sanitizeItemArray($fieldConfig['config']['items'], $table, $fieldName);
98 
99  // List of additional items defined by page ts config "addItems"
100  $itemsFromPageTsConfig = $this->‪addItemsFromPageTsConfig($result, $fieldName, []);
101  // Resolve pageTsConfig item icons to markup
102  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
103  $finalPageTsConfigItems = [];
104  foreach ($itemsFromPageTsConfig as $item) {
105  if ($item[2] !== null) {
106  $item[2] = $iconFactory->getIcon($item[2], ‪Icon::SIZE_SMALL)->getMarkup('inline');
107  }
108  $finalPageTsConfigItems[] = $item;
109  }
110 
111  if (!empty($itemsFromTca) || !empty($finalPageTsConfigItems)) {
112  // First apply "keepItems" to $itemsFromTca, this will restrict the tca item list to only
113  // those items that are defined in page ts "keepItems" if given
114  $itemsFromTca = $this->‪removeItemsByKeepItemsPageTsConfig($result, $fieldName, $itemsFromTca);
115  // Then, merge the items from page ts "addItems" into item list, since "addItems" should
116  // add additional items even if they are not in the "keepItems" list
117  $staticItems = array_merge($itemsFromTca, $finalPageTsConfigItems);
118  // Now apply page ts config "removeItems", so this is *after* addItems, so "removeItems" could
119  // possibly remove items again that were added via "addItems"
120  $staticItems = $this->‪removeItemsByRemoveItemsPageTsConfig($result, $fieldName, $staticItems);
121  // Now, apply user and access right restrictions to this item list
122  $staticItems = $this->‪removeItemsByUserLanguageFieldRestriction($result, $fieldName, $staticItems);
123  $staticItems = $this->‪removeItemsByUserAuthMode($result, $fieldName, $staticItems);
124  $staticItems = $this->‪removeItemsByDoktypeUserRestriction($result, $fieldName, $staticItems);
125  // Call itemsProcFunc if given. Note this function does *not* see the "dynamic" list of items
126  if (!empty($fieldConfig['config']['itemsProcFunc'])) {
127  $staticItems = $this->‪resolveItemProcessorFunction($result, $fieldName, $staticItems);
128  // itemsProcFunc must not be used anymore
129  unset($fieldConfig['config']['itemsProcFunc']);
130  }
131  // translate any labels
132  $staticItems = $this->‪translateLabels($result, $staticItems, $table, $fieldName);
133  // and add icons from the static list
134  $staticItems = $this->‪addIconFromAltIcons($result, $staticItems, $table, $fieldName);
135  // Now compile the target items using the same array structure as the "dynamic" list below
136  foreach ($staticItems as $item) {
137  if ($item[1] === '--div--') {
138  // Skip divs that may occur here for whatever reason
139  continue;
140  }
141  $finalItems[] = [
142  'identifier' => $item[1],
143  'name' => $item[0],
144  'icon' => $item[2] ?? '',
145  'iconOverlay' => '',
146  'depth' => 0,
147  'hasChildren' => false,
148  'selectable' => true,
149  'checked' => in_array($item[1], $result['databaseRow'][$fieldName]),
150  ];
151  }
152  }
153 
154  // Fetch the list of all possible "related" items (yuk!) and apply a similar processing as with the "static" list
155  $dynamicItems = $this->‪addItemsFromForeignTable($result, $fieldName, []);
156  $dynamicItems = $this->‪removeItemsByKeepItemsPageTsConfig($result, $fieldName, $dynamicItems);
157  $dynamicItems = $this->‪removeItemsByRemoveItemsPageTsConfig($result, $fieldName, $dynamicItems);
158  $dynamicItems = $this->‪removeItemsByUserLanguageFieldRestriction($result, $fieldName, $dynamicItems);
159  $dynamicItems = $this->‪removeItemsByUserAuthMode($result, $fieldName, $dynamicItems);
160  $dynamicItems = $this->‪removeItemsByDoktypeUserRestriction($result, $fieldName, $dynamicItems);
161  // Funnily, the only data needed for the tree code are the uids of the possible records (yuk!) - get them
162  $uidListOfAllDynamicItems = [];
163  foreach ($dynamicItems as $item) {
164  if ((int)$item[1] > 0) {
165  $uidListOfAllDynamicItems[] = (int)$item[1];
166  }
167  }
168  // Now kick in this tree stuff
170  $fieldConfig['config'],
171  $table,
172  $fieldName,
173  $result['databaseRow']
174  );
175  $treeDataProvider->setSelectedList(implode(',', $result['databaseRow'][$fieldName]));
176  // Basically the tree foo fetches all tree nodes again (aaargs), then verifies if
177  // a given rows uid is within this "list of allowed uids". It then creates an object
178  // tree representing the nested tree, just to collapse all that to a flat array again. Yay ...
179  $treeDataProvider->setItemWhiteList($uidListOfAllDynamicItems);
180  $treeDataProvider->initializeTreeData();
181  $treeRenderer = GeneralUtility::makeInstance(ArrayTreeRenderer::class);
182  $tree = GeneralUtility::makeInstance(TableConfigurationTree::class);
183  $tree->setDataProvider($treeDataProvider);
184  $tree->setNodeRenderer($treeRenderer);
185 
186  // Merge tree nodes after calculated nodes from static items
187  $fieldConfig['config']['items'] = array_merge($finalItems, $tree->render());
188  }
189 
190  $result['processedTca']['columns'][$fieldName] = $fieldConfig;
191  }
192 
193  return $result;
194  }
195 
202  protected function ‪isTargetRenderType(array $fieldConfig)
203  {
204  return $fieldConfig['config']['renderType'] === 'selectTree';
205  }
206 }
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:30
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\sanitizeItemArray
‪array sanitizeItemArray($itemArray, $tableName, $fieldName)
Definition: AbstractItemProvider.php:1424
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\addItemsFromPageTsConfig
‪array addItemsFromPageTsConfig(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:140
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:26
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByUserLanguageFieldRestriction
‪array removeItemsByUserLanguageFieldRestriction(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:652
‪TYPO3\CMS\Core\Tree\TableConfiguration\TableConfigurationTree
Definition: TableConfigurationTree.php:24
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:32
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\addIconFromAltIcons
‪array addIconFromAltIcons(array $result, array $items, string $table, string $fieldName)
Definition: AbstractItemProvider.php:1400
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\translateLabels
‪array translateLabels(array $result, array $itemArray, $table, $fieldName)
Definition: AbstractItemProvider.php:1355
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:33
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectTreeItems\addData
‪array addData(array $result)
Definition: TcaSelectTreeItems.php:47
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\addItemsFromForeignTable
‪array addItemsFromForeignTable(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:479
‪TYPO3\CMS\Core\Tree\TableConfiguration\TreeDataProviderFactory\getDataProvider
‪static DatabaseTreeDataProvider getDataProvider(array $tcaConfiguration, $table, $field, $currentValue)
Definition: TreeDataProviderFactory.php:37
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectTreeItems
Definition: TcaSelectTreeItems.php:39
‪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:712
‪TYPO3\CMS\Backend\Form\FormDataProvider
Definition: AbstractDatabaseRecordProvider.php:16
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectTreeItems\isTargetRenderType
‪bool isTargetRenderType(array $fieldConfig)
Definition: TcaSelectTreeItems.php:202
‪TYPO3\CMS\Backend\Form\FormDataProviderInterface
Definition: FormDataProviderInterface.php:23
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByKeepItemsPageTsConfig
‪array removeItemsByKeepItemsPageTsConfig(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:585
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\processDatabaseFieldValue
‪array processDatabaseFieldValue(array $row, $fieldName)
Definition: AbstractItemProvider.php:1267
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\processSelectFieldValue
‪array processSelectFieldValue(array $result, $fieldName, array $staticValues)
Definition: AbstractItemProvider.php:1289
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22
‪TYPO3\CMS\Core\Tree\TableConfiguration\ArrayTreeRenderer
Definition: ArrayTreeRenderer.php:27
‪TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider\removeItemsByUserAuthMode
‪array removeItemsByUserAuthMode(array $result, $fieldName, array $items)
Definition: AbstractItemProvider.php:681
‪TYPO3\CMS\Core\Tree\TableConfiguration\TreeDataProviderFactory
Definition: TreeDataProviderFactory.php:26
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪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:618