ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
MainMenuMainCollector.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
43 use Iterator;
44 use Throwable;
45 use Generator;
48 
57 {
59  private readonly Map $map;
60 
61  private bool $default_topics = false;
62 
63  public function __construct(protected array $providers, MainMenuItemFactory $factory, private readonly ?ItemInformation $information = null)
64  {
65  $this->type_information_collection = new TypeInformationCollection();
66  $this->map = new Map($factory);
67  }
68 
72  private function getProvidersFromList(): Iterator
73  {
74  yield from $this->providers;
75  }
76 
77  public function collectStructure(): void
78  {
79  foreach ($this->getProvidersFromList() as $provider) {
80  $this->type_information_collection->append($provider->provideTypeInformation());
81  $this->map->addMultiple(...$provider->getStaticTopItems());
82  $this->map->addMultiple(...$provider->getStaticSubItems());
83  }
84  }
85 
86  public function filterItemsByVisibilty(bool $async_only = false): void
87  {
88  // apply filter
89  $this->map->filter(function (isItem $item) use ($async_only): bool {
90  if ($async_only && !$item instanceof supportsAsynchronousLoading) {
91  return false;
92  }
93  if (!$item->isAvailable()) {
94  return false;
95  }
96 
97  // make parent available if one child is always available
98  if ($item instanceof isParent) {
99  foreach ($item->getChildren() as $child) {
100  if ($child->isAlwaysAvailable()) {
101  return true;
102  }
103  }
104  }
105 
106  // Always avaiable must be delivered when visible
107  if ($item->isAlwaysAvailable()) {
108  return $item->isVisible();
109  }
110  // All other cases
111  return $item->isAvailable() && $item->isVisible() && $this->information->isItemActive($item);
112  });
113  }
114 
115  public function prepareItemsForUIRepresentation(): void
116  {
117  if ($this->default_topics) {
118  $this->map->walk(function (isItem &$item): isItem {
119  if ($item instanceof isDecorateable) {
120  $item = $item->withTopics(new Topic($item->getProviderIdentification()->getInternalIdentifier()));
121  }
122  return $item;
123  });
124  }
125 
126  $this->map->walk(function (isItem &$item): isItem {
127  if (is_null($item->getTypeInformation())) {
128  $item->setTypeInformation(
129  $this->getTypeInformationForItem($item)
130  );
131  }
132 
133  // Apply the TypeHandler
134  $item = $this->getTypeHandlerForItem($item)->enrichItem($item);
135  // Translate Item
136  if ($item instanceof hasTitle) {
137  $item = $this->getItemInformation()->customTranslationForUser($item);
138  }
139  // Custom Symbol
140  if ($item instanceof hasSymbol) {
141  $item = $this->getItemInformation()->customSymbol($item);
142  }
143  // Custom Position
144  $item = $this->getItemInformation()->customPosition($item);
145 
146  return $item;
147  });
148 
149  // Override parent from configuration
150  $this->map->walk(function (isItem $item): isItem {
151  if ($item instanceof isChild || $item instanceof isInterchangeableItem) {
152  $parent = $this->map->getSingleItemFromFilter($this->information->getParent($item));
153  if ($parent instanceof isParent) {
154  $parent->appendChild($item);
155  $item->overrideParent($parent->getProviderIdentification());
156  }
157  }
158 
159  return $item;
160  });
161  }
162 
163  public function cleanupItemsForUIRepresentation(): void
164  {
165  // Remove not visible children
166  $this->map->walk(function (isItem &$item): isItem {
167  if ($item instanceof isParent) {
168  foreach ($item->getChildren() as $child) {
169  if (!$this->map->existsInFilter($child->getProviderIdentification())) {
170  $item->removeChild($child);
171  }
172  }
173  }
174  return $item;
175  });
176 
177  $this->map->walk(static function (isItem &$i): void {
178  if ($i instanceof isParent && $i->getChildren() === []) {
179  $i = $i->withAvailableCallable(static fn(): bool => false)->withVisibilityCallable(static fn(): bool => false);
180  }
181  });
182 
183  // filter empty slates
184  $this->map->filter(static function (isItem $i): bool {
185  if ($i instanceof isParent) {
186  return $i->getChildren() !== [];
187  }
188 
189  return true;
190  });
191  }
192 
193  public function sortItemsForUIRepresentation(): void
194  {
195  $this->map->sort();
196  }
197 
205  {
206  foreach ($this->map->getAllFromFilter() as $item) {
207  if ($item->isTop()) {
208  yield $item;
209  }
210  }
211  }
212 
216  public function getRawItems(): Iterator
217  {
218  yield from $this->map->getAllFromFilter();
219  }
220 
224  public function getRawUnfilteredItems(): Iterator
225  {
226  yield from $this->map->getAllFromRaw();
227  }
228 
229 
230  public function hasItems(): bool
231  {
232  return $this->map->has();
233  }
234 
235  public function hasVisibleItems(): bool
236  {
237  if (!$this->hasItems()) {
238  return false;
239  }
240  foreach ($this->getItemsForUIRepresentation() as $item) {
241  return $item instanceof isItem;
242  }
243  return false;
244  }
245 
251  public function getSingleItemFromFilter(IdentificationInterface $identification): isItem
252  {
253  return $this->map->getSingleItemFromFilter($identification);
254  }
255 
261  public function getSingleItemFromRaw(IdentificationInterface $identification): isItem
262  {
263  return $this->map->getSingleItemFromRaw($identification);
264  }
265 
270  public function getTypeHandlerForItem(isItem $item): TypeHandler
271  {
272  $type_information = $this->getTypeInformationForItem($item);
273  if ($type_information === null) {
274  return new BaseTypeHandler();
275  }
276 
277  return $type_information->getTypeHandler();
278  }
279 
284  {
285  return $this->information;
286  }
287 
293  {
294  return $this->getTypeInformationCollection()->get($item::class);
295  }
296 
301  {
303  }
304 }
Class MainMenuMainCollector This Collector will collect and then provide all available slates from th...
This is just a class that marks a string as a help topic.
Definition: Topic.php:26
getItemsForUIRepresentation()
This will return all available isTopItem (and moved isInterchangeableItem), stacked based on the conf...
setTypeInformation(TypeInformation $information)
$provider
Definition: ltitoken.php:80
Class MainMenuItemFactory This factory provides you all available types for MainMenu GlobalScreen Ite...
withAvailableCallable(callable $is_available)
Pass a callable which can decide whether your element is available in general, e.g.
Interface supportsAsynchronousLoading Types, which implement this interface, can load their content a...
__construct(protected array $providers, MainMenuItemFactory $factory, private readonly ?ItemInformation $information=null)