‪TYPO3CMS  ‪main
SelectItemProcessor.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 
25 
33 {
34  public function ‪__construct(protected readonly ‪LanguageServiceFactory $languageServiceFactory) {}
35 
54  public function ‪groupAndSortItems(array $allItems, array $definedGroups, array $sortOrders): array
55  {
56  $allItems = $this->‪transformArrayToSelectItems($allItems);
57  $groupedItems = [];
58  // Append defined groups at first, as their order is prioritized
59  $itemGroups = ['none' => ''];
60  foreach ($definedGroups as $groupId => $groupLabel) {
61  $itemGroups[$groupId] = $this->‪getLanguageService()->sL($groupLabel);
62  }
63  $currentGroup = 'none';
64  // Extract --div-- into itemGroups
65  foreach ($allItems as $item) {
66  if ($item->isDivider()) {
67  // A divider is added as a group (existing groups will get their label overridden)
68  if ($item->hasGroup()) {
69  $currentGroup = $item->getGroup();
70  $itemGroups[$currentGroup] = $item->getLabel();
71  } else {
72  $currentGroup = 'none';
73  }
74  continue;
75  }
76  // Put the given item in the currentGroup if no group has been given already
77  if (!$item->hasGroup()) {
78  $item = $item->withGroup($currentGroup);
79  }
80  $groupIdOfItem = $item->hasGroup() ? $item->getGroup() : 'none';
81  // It is still possible to have items that have an "unassigned" group, so they are moved to the "none" group
82  if (!isset($itemGroups[$groupIdOfItem])) {
83  $itemGroups[$groupIdOfItem] = '';
84  }
85 
86  // Put the item in its corresponding group (and create it if it does not exist yet)
87  if (!is_array($groupedItems[$groupIdOfItem] ?? null)) {
88  $groupedItems[$groupIdOfItem] = [];
89  }
90  $groupedItems[$groupIdOfItem][] = $item;
91  }
92  // Only "none" = no grouping used explicitly via "itemGroups" or via "--div--"
93  if (count($itemGroups) === 1) {
94  if (!empty($sortOrders)) {
95  $allItems = $this->‪sortItems($allItems, $sortOrders);
96  }
97  return $this->‪transformSelectItemsToArray($allItems);
98  }
99 
100  // $groupedItems contains all items per group
101  // $itemGroups contains all groups in order of each group
102 
103  // Let's add the --div-- items again ("unpacking")
104  // And use the group ordering given by the itemGroups
105  $finalItems = [];
106  foreach ($itemGroups as $groupId => $groupLabel) {
107  $itemsInGroup = $groupedItems[$groupId] ?? [];
108  if (empty($itemsInGroup)) {
109  continue;
110  }
111  // If sorting is defined, sort within each group now
112  if (!empty($sortOrders)) {
113  $itemsInGroup = $this->‪sortItems($itemsInGroup, $sortOrders);
114  }
115  // Add the --div-- if it is not the "none" default item
116  if ($groupId !== 'none') {
117  // Fall back to the groupId, if there is no label for it
118  $groupLabel = $groupLabel ?: $groupId;
119  $finalItems[] = ['label' => $groupLabel, 'value' => '--div--', 'group' => $groupId];
120  }
121  $finalItems = array_merge($finalItems, $itemsInGroup);
122  }
123  return $this->‪transformSelectItemsToArray($finalItems);
124  }
125 
129  public function ‪transformArrayToSelectItems(array $items, string $type = 'select'): array
130  {
131  return array_map(static function (array|‪SelectItem $item) use ($type): ‪SelectItem {
132  if ($item instanceof ‪SelectItem) {
133  return $item;
134  }
135  return ‪SelectItem::fromTcaItemArray($item, $type);
136  }, $items);
137  }
138 
139  public function ‪transformSelectItemsToArray(array $items): array
140  {
141  return array_map(static function (array|‪SelectItem $item): array {
142  if (!$item instanceof ‪SelectItem) {
143  return $item;
144  }
145  return $item->‪toArray();
146  }, $items);
147  }
148 
157  protected function ‪sortItems(array $items, array $sortOrders): array
158  {
159  foreach ($sortOrders as $order => $direction) {
160  switch ($order) {
161  case 'label':
162  $direction = strtolower($direction);
163  @usort(
164  $items,
165  static function (‪SelectItem $item1, ‪SelectItem $item2) use ($direction) {
166  if ($direction === 'desc') {
167  return (strcasecmp($item1->‪getLabel(), $item2->‪getLabel()) <= 0) ? 1 : 0;
168  }
169  return strcasecmp($item1->‪getLabel(), $item2->‪getLabel());
170  }
171  );
172  break;
173  case 'value':
174  $direction = strtolower($direction);
175  @usort(
176  $items,
177  static function (‪SelectItem $item1, ‪SelectItem $item2) use ($direction) {
178  if ($direction === 'desc') {
179  return (strcasecmp((string)$item1->‪getValue(), (string)$item2->‪getValue()) <= 0) ? 1 : 0;
180  }
181  return strcasecmp((string)$item1->‪getValue(), (string)$item2->‪getValue());
182  }
183  );
184  break;
185  default:
186  $reference = null;
187  GeneralUtility::callUserFunction($direction, $items, $reference);
188  }
189  }
190  return $items;
191  }
192 
194  {
195  return ‪$GLOBALS['LANG'] ?? $this->languageServiceFactory->createFromUserPreferences($this->‪getBackendUser());
196  }
197 
199  {
200  return ‪$GLOBALS['BE_USER'];
201  }
202 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor\transformSelectItemsToArray
‪transformSelectItemsToArray(array $items)
Definition: SelectItemProcessor.php:139
‪TYPO3\CMS\Core\Schema\Struct\SelectItem\toArray
‪toArray()
Definition: SelectItem.php:62
‪TYPO3\CMS\Core\Schema\Struct\SelectItem
Definition: SelectItem.php:21
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor\getLanguageService
‪getLanguageService()
Definition: SelectItemProcessor.php:193
‪TYPO3\CMS\Core\Schema\Struct\SelectItem\fromTcaItemArray
‪static fromTcaItemArray(array $item, string $type='select')
Definition: SelectItem.php:45
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor\transformArrayToSelectItems
‪SelectItem[] transformArrayToSelectItems(array $items, string $type='select')
Definition: SelectItemProcessor.php:129
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor\groupAndSortItems
‪groupAndSortItems(array $allItems, array $definedGroups, array $sortOrders)
Definition: SelectItemProcessor.php:54
‪TYPO3\CMS\Core\Schema\Struct\SelectItem\getValue
‪getValue()
Definition: SelectItem.php:104
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Schema\Struct\SelectItem\getLabel
‪getLabel()
Definition: SelectItem.php:92
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor
Definition: SelectItemProcessor.php:33
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor\getBackendUser
‪getBackendUser()
Definition: SelectItemProcessor.php:198
‪TYPO3\CMS\Backend\Form\Processor
Definition: SelectItemProcessor.php:18
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor\sortItems
‪SelectItem[] sortItems(array $items, array $sortOrders)
Definition: SelectItemProcessor.php:157
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Form\Processor\SelectItemProcessor\__construct
‪__construct(protected readonly LanguageServiceFactory $languageServiceFactory)
Definition: SelectItemProcessor.php:34