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