ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilDashboardBlockGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
31 
32 abstract class ilDashboardBlockGUI extends ilBlockGUI implements ilDesktopItemHandling
33 {
34  private string $content;
36  private string $parent;
38  protected int $requested_item_ref_id;
39  private mixed $object_cache;
40  private ilTree $tree;
41  private mixed $objDefinition;
42  protected ilSetting $settings;
43  protected ilLogger $logging;
44  protected Services $http;
45  private Factory $refinery;
48  protected array $data;
49 
50  public function __construct()
51  {
53  global $DIC;
54  $this->http = $DIC->http();
55  $this->refinery = $DIC->refinery();
56  $this->logging = $DIC->logger()->root();
57  $this->settings = $DIC->settings();
58  $this->object_cache = $DIC['ilObjDataCache'];
59  $this->tree = $DIC->repositoryTree();
60  $this->objDefinition = $DIC['objDefinition'];
61  $this->rbacsystem = $DIC->rbac()->system();
62  $this->favourites_manager = new ilFavouritesManager();
63  $this->parent = $this->ctrl->getCurrentClassPath()[0] ?? '';
64  $this->init();
65  }
66 
67  abstract public function initViewSettings(): void;
68 
69  abstract public function initData(): void;
70 
71  abstract public function emptyHandling(): string;
72 
73  public function addCustomCommandsToActionMenu(ilObjectListGUI $itemListGui, int $ref_id): void
74  {
75  }
76 
77  protected function getCardForData(BlockDTO $data): ?RepositoryObject
78  {
79  $itemListGui = $this->byType($data->getType());
80  $this->addCustomCommandsToActionMenu($itemListGui, $data->getRefId());
81  $card = $itemListGui->getAsCard(
82  $data->getRefId(),
83  $data->getObjId(),
84  $data->getType(),
85  $data->getTitle(),
86  $data->getDescription()
87  );
88 
89  return $card;
90  }
91 
92  protected function getListItemGroups(): array
93  {
94  $data = $this->loadData();
95  $groupedCards = [];
96  $obj_ids = [];
97  foreach ($data as $group) {
98  foreach ($group as $datum) {
99  $obj_ids[] = $datum->getObjId();
100  }
101  }
103 
104  foreach ($data as $title => $group) {
105  $items = [];
106  foreach ($group as $datum) {
107  $item = $this->getListItemForDataDTO($datum);
108  if ($item !== null) {
109  $items[] = $item;
110  }
111  }
112  $groupedCards[] = $this->factory->item()->group((string) $title, $items);
113  }
114 
115  return $groupedCards;
116  }
117 
118  protected function getListItemForDataDTO(BlockDTO $data): ?Item
119  {
120  $itemListGui = $this->byType($data->getType());
121  $this->addCustomCommandsToActionMenu($itemListGui, $data->getRefId());
122  $list_item = $itemListGui->getAsListItem(
123  $data->getRefId(),
124  $data->getObjId(),
125  $data->getType(),
126  $data->getTitle(),
127  $data->getDescription()
128  );
129 
130  $list_item = $list_item->withProperties($list_item->getProperties() + $data->getAdditionalData());
131 
132  return $list_item;
133  }
134 
135  protected function isRepositoryObject(): bool
136  {
137  return false;
138  }
139 
140  protected function getLegacyContent(): string
141  {
142  $groupedCards = [];
143  foreach ($this->loadData() as $title => $group) {
144  $cards = array_filter(array_map($this->getCardForData(...), $group));
145  if ($cards) {
146  $groupedCards[] = $this->ui->factory()->panel()->sub(
147  (string) $title,
148  $this->factory->deck($cards)->withNormalCardsSize()
149  );
150  }
151  }
152 
153  if ($groupedCards) {
154  return $this->renderer->render($groupedCards);
155  }
156 
157  return $this->getNoItemFoundContent();
158  }
159 
160  public function getNoItemFoundContent(): string
161  {
162  return $this->emptyHandling();
163  }
164 
166  {
167  return $this->viewSettings;
168  }
169 
170  public function init(): void
171  {
172  $this->lng->loadLanguageModule('dash');
173  $this->lng->loadLanguageModule('rep');
174  $this->lng->loadLanguageModule('pd');
175  $this->initViewSettings();
176  $this->viewSettings->parse();
177  $this->requested_item_ref_id = (int) ($this->http->request()->getQueryParams()['item_ref_id'] ?? 0);
178  $this->initData();
179 
180  $this->ctrl->setParameter($this, 'view', $this->viewSettings->getCurrentView());
181  if ($this->viewSettings->isTilePresentation()) {
182  $this->setPresentation(self::PRES_MAIN_LEG);
183  } else {
184  $this->setPresentation(self::PRES_SEC_LIST);
185  }
186  }
187 
188  protected function initAndShow(): string
189  {
190  $this->init();
191  if ($this->parent === ilDashboardGUI::class) {
192  $this->ctrl->redirectByClass(ilDashboardGUI::class, 'show');
193  }
194 
195  return $this->getHTML();
196  }
197 
198  public function getHTML(): string
199  {
200  $this->setTitle(
201  $this->lng->txt('dash_' . $this->viewSettings->getViewName($this->viewSettings->getCurrentView()))
202  );
203 
204  if (!$this->data) {
205  return $this->emptyHandling();
206  }
207 
208  $this->addCommandActions();
209  $this->setData($this->getItemGroups());
210 
211  return parent::getHTML();
212  }
213 
217  public function setData(array $a_data): void
218  {
219  $this->data = array_filter(
220  array_map(
221  static fn($group) => array_filter($group, static fn($item) => $item instanceof BlockDTO),
222  $a_data
223  )
224  );
225  }
226 
230  public function getData(): array
231  {
232  return parent::getData();
233  }
234 
238  public function groupItemsByStartDate(): array
239  {
240  $data = $this->getData();
242  $items = array_merge(...array_values($data));
243 
244  $groups = [
245  'upcoming' => [],
246  'ongoing' => [],
247  'ended' => [],
248  'not_dated' => []
249  ];
250  foreach ($items as $item) {
251  if ($item->isDated()) {
252  if ($item->hasNotStarted()) {
253  $groups['upcoming'][] = $item;
254  } elseif ($item->isRunning()) {
255  $groups['ongoing'][] = $item;
256  } else {
257  $groups['ended'][] = $item;
258  }
259  } else {
260  $groups['not_dated'][] = $item;
261  }
262  }
263 
264  foreach ($groups as $key => $group) {
265  $group = $this->sortByTitle($group);
266  if ($key !== 'not_dated') {
267  $group = $this->sortByDate($group, $key === 'upcoming');
268  }
269  $groups[$this->lng->txt('pd_' . $key)] = $group;
270  unset($groups[$key]);
271  }
272  return $groups;
273  }
274 
278  protected function groupItemsByType(): array
279  {
280  $object_types_by_container = $this->objDefinition->getGroupedRepositoryObjectTypes(
281  ['cat', 'crs', 'grp', 'fold']
282  );
283  $grouped_items = [];
284  $data = $this->getData();
286  $data = array_merge(...array_values($data));
287 
288  foreach ($object_types_by_container as $type_title => $type) {
289  if (!$this->objDefinition->isPlugin($type_title)) {
290  $title = $this->lng->txt('objs_' . $type_title);
291  } else {
292  $pl = ilObjectPlugin::getPluginObjectByType($type_title);
293  $title = $pl->txt('objs_' . $type_title);
294  }
295 
296  foreach ($data as $item) {
297  if (in_array($item->getType(), $type['objs'])) {
298  $grouped_items[$title][] = $item;
299  }
300  }
301  }
302 
303  foreach ($grouped_items as $key => $group) {
304  $grouped_items[$key] = $this->sortByTitle($group);
305  }
306 
307  return $grouped_items;
308  }
309 
313  protected function groupItemsByLocation(): array
314  {
315  $grouped_items = [];
316  $data = $this->getData();
318  $data = array_merge(...array_values($data));
319 
320  $parent_ref_ids = array_values(array_unique(
321  array_map(fn(BlockDTO $item): ?int => $this->tree->getParentId($item->getRefId()), $data)
322  ));
323  $this->object_cache->preloadReferenceCache($parent_ref_ids);
324 
325  foreach ($data as $item) {
326  $parent_ref = $this->tree->getParentId($item->getRefId());
327  if ($this->isRootNode($parent_ref)) {
328  $title = $this->getRepositoryTitle();
329  } else {
330  $title = $this->object_cache->lookupTitle($this->object_cache->lookupObjId($parent_ref));
331  }
332  $grouped_items[$title][] = $item;
333  }
334  ksort($grouped_items);
335  $grouped_items = array_map($this->sortByTitle(...), $grouped_items);
336  return $grouped_items;
337  }
338 
339  protected function isRootNode(int $refId): bool
340  {
341  return $this->tree->getRootId() === $refId;
342  }
343 
344  protected function getRepositoryTitle(): string
345  {
346  $nd = $this->tree->getNodeData($this->tree->getRootId());
347  $title = $nd['title'];
348 
349  if ($title === 'ILIAS') {
350  $title = $this->lng->txt('repository');
351  }
352 
353  return $title;
354  }
355 
356  public function addCommandActions(): void
357  {
358  $sortings = $this->viewSettings->getSelectableSortingModes();
359  if (count($sortings) > 1) {
360  foreach ($sortings as $sorting) {
361  $this->addSortOption(
362  $sorting,
363  $this->lng->txt(ilObjDashboardSettingsGUI::DASH_SORT_PREFIX . $sorting),
364  $sorting === $this->viewSettings->getEffectiveSortingMode()
365  );
366  }
367  $this->setSortTarget($this->ctrl->getLinkTarget($this, 'changePDItemSorting'));
368  }
369 
370  $presentations = $this->viewSettings->getSelectablePresentationModes();
371  foreach ($presentations as $presentation) {
372  $this->ctrl->setParameter($this, 'presentation', $presentation);
373  $this->addPresentation(
374  $this->ui->renderer()->render($this->ui->factory()->symbol()->glyph()->{$presentation . 'View'}()),
375  $this->ctrl->getLinkTarget($this, 'changePDItemPresentation'),
376  $presentation === $this->viewSettings->getEffectivePresentationMode()
377  );
378  $this->ctrl->setParameter($this, 'presentation', null);
379  }
380 
381  if ($this->removeMultipleEnabled()) {
382  $this->addBlockCommand(
383  $this->ctrl->getLinkTarget($this, 'manage'),
385  '',
386  $this->getRemoveModal()
387  );
388  }
389  }
390 
391  public function getRemoveModal(): RoundTrip
392  {
393  $items = $this->getManageFields();
394  if ($items !== []) {
395  if ($this->viewSettings->isSelectedItemsViewActive()) {
396  $question = $this->lng->txt('dash_info_sure_remove_from_favs');
397  } else {
398  $question = $this->lng->txt('mmbr_info_delete_sure_unsubscribe');
399  }
400  $modal = $this->ui->factory()->modal()->roundtrip(
402  [
403  $this->ui->factory()->messageBox()->confirmation($question),
404  $this->ui->factory()->messageBox()->info($this->lng->txt('select_one')),
405  ],
406  $items,
407  $this->ctrl->getLinkTargetByClass([ilDashboardGUI::class, $this::class], 'confirmedRemove')
408  )->withSubmitLabel($this->getRemoveMultipleActionText());
409 
410  $modal = $modal->withOnLoadCode(static fn($id) => "il.Dashboard.confirmModal($id)");
411  } else {
412  $modal = $this->ui->factory()->modal()->roundtrip(
414  $this->ui->factory()->messageBox()->info($this->lng->txt('pd_no_items_to_manage'))
415  );
416  }
417 
418  return $modal;
419  }
420 
421  protected function getManageFields(): array
422  {
423  $inputs = [];
424  foreach ($this->getItemGroups() as $key => $item_group) {
425  $options = [];
426  foreach ($item_group as $item) {
427  $icon = $this->ui->renderer()->render($this->ui->factory()->symbol()->icon()->custom(ilObject::_getIcon($item->getObjId()), ''));
428  if ($this instanceof ilMembershipBlockGUI) {
429  if ($this->rbacsystem->checkAccess('leave', $item->getRefId())) {
430  if ($item->getType() === 'crs' || $item->getType() === 'grp') {
431  $members_obj = ilParticipants::getInstance($item->getRefId());
432  if (!$members_obj->checkLastAdmin([$this->user->getId()])) {
433  continue;
434  }
435  }
436  $options[$item->getRefId()] = $icon . $item->getTitle();
437  }
438  } else {
439  $options[$item->getRefId()] = $icon . $item->getTitle();
440  }
441  }
442  if ($options !== []) {
443  $inputs[] = $this->ui->factory()->input()->field()->multiSelect((string) $key, $options)
444  ->withAdditionalTransformation($this->refinery->to()->listOf($this->refinery->kindlyTo()->int()));
445  }
446  }
447 
448  return $inputs;
449  }
450 
451  public function executeCommand(): string
452  {
453  $next_class = $this->ctrl->getNextClass();
454  $cmd = $this->ctrl->getCmd('getHTML');
455 
456  switch ($next_class) {
457  case strtolower(ilCommonActionDispatcherGUI::class):
459  if ($gui instanceof ilCommonActionDispatcherGUI) {
460  $this->ctrl->forwardCommand($gui);
461  }
462  break;
463 
464  default:
465  switch ($cmd) {
466  case 'confirmedRemove':
467  $form = $this->ui->factory()->input()->container()->form()->standard('', $this->getManageFields())->withRequest($this->http->request());
468  $this->confirmedRemove(array_merge(...array_filter($form->getData())));
469  // no break
470  default:
471  if (method_exists($this, $cmd . 'Object')) {
472  return $this->{$cmd . 'Object'}();
473  }
474  }
475  }
476  return '';
477  }
478 
479  public function viewDashboardObject(): void
480  {
481  $this->initAndShow();
482  }
483 
484  public function changePDItemSortingObject(): string
485  {
486  $this->viewSettings->storeActorSortingMode(
487  ilUtil::stripSlashes((string) ($this->http->request()->getQueryParams()['sorting'] ?? ''))
488  );
489 
490  return $this->initAndShow();
491  }
492 
493  public function changePDItemPresentationObject(): string
494  {
495  $this->viewSettings->storeActorPresentationMode(
496  ilUtil::stripSlashes((string) ($this->http->request()->getQueryParams()['presentation'] ?? ''))
497  );
498  return $this->initAndShow();
499  }
500 
504  public function getItemGroups(): array
505  {
506  switch ($this->viewSettings->getEffectiveSortingMode()) {
508  $data = $this->getData();
509  $data = array_merge(...array_values($data));
510  $data = $this->sortByTitle($data);
511  return ['' => $data];
513  return $this->groupItemsByStartDate();
515  return $this->groupItemsByType();
517  default:
518  return $this->groupItemsByLocation();
519  }
520  }
521 
522  public function addToDeskObject(): void
523  {
524  $this->favourites_manager->add($this->user->getId(), $this->requested_item_ref_id);
525  $this->main_tpl->setOnScreenMessage('success', $this->lng->txt('rep_added_to_favourites'), true);
526  $this->ctrl->redirectByClass(ilDashboardGUI::class, 'show');
527  }
528 
529  public function removeFromDeskObject(): void
530  {
531  $this->favourites_manager->remove($this->user->getId(), $this->requested_item_ref_id);
532  $this->main_tpl->setOnScreenMessage('success', $this->lng->txt('rep_removed_from_favourites'), true);
533  $this->ctrl->redirectByClass(ilDashboardGUI::class, 'show');
534  }
535 
536  abstract public function removeMultipleEnabled(): bool;
537 
538  abstract public function getRemoveMultipleActionText(): string;
539 
543  public function confirmedRemove(array $ids): void
544  {
545  }
546 
547  public function byType(string $a_type): ilObjectListGUI
548  {
549  $class = $this->objDefinition->getClassName($a_type);
550  if (!$class) {
551  throw new ilException(sprintf('Could not find a class for object type: %s', $a_type));
552  }
553 
554  $location = $this->objDefinition->getLocation($a_type);
555  if (!$location) {
556  throw new ilException(sprintf('Could not find a class location for object type: %s', $a_type));
557  }
558 
559  $full_class = 'ilObj' . $class . 'ListGUI';
560  $item_list_gui = new $full_class();
561 
562  $item_list_gui->setContainerObject($this);
563  $item_list_gui->enableNotes(false);
564  $item_list_gui->enableComments(false);
565  $item_list_gui->enableTags(false);
566 
567  $item_list_gui->enableIcon(true);
568  $item_list_gui->enableDelete(false);
569  $item_list_gui->enableCut(false);
570  $item_list_gui->enableCopy(false);
571  $item_list_gui->enableLink(false);
572  $item_list_gui->enableInfoScreen(true);
573 
574  $item_list_gui->enableCommands(true, true);
575 
576  return $item_list_gui;
577  }
578 
582  private function sortByDate(array $data, bool $asc = true): array
583  {
584  usort(
585  $data,
586  static fn(BlockDTO $left, BlockDTO $right): int =>
587  ($asc ? -1 : 1) *
588  (($right->getStartDate()?->get(IL_CAL_UNIX) ?? 0) - ($left->getStartDate()?->get(IL_CAL_UNIX) ?? 0))
589  );
590  return $data;
591  }
592 
596  private function sortByTitle(array $data): array
597  {
598  usort(
599  $data,
600  static fn(BlockDTO $left, BlockDTO $right): int => strcmp($left->getTitle(), $right->getTitle())
601  );
602  return $data;
603  }
604 }
ilFavouritesManager $favourites_manager
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
addPresentation(string $label, string $target, bool $active)
$location
Definition: buildRTE.php:22
factory()
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
array $presentations
static getInstance(int $a_ref_id)
renderer()
static preloadListGUIData(array $a_obj_ids)
setSortTarget(string $target)
$refId
Definition: xapitoken.php:58
const IL_CAL_UNIX
Manages favourites, currently the interface for other components, needs discussion.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$ref_id
Definition: ltiauth.php:65
static http()
Fetches the global http state from ILIAS.
$nd
Definition: error.php:30
addCustomCommandsToActionMenu(ilObjectListGUI $itemListGui, int $ref_id)
Common interface to all items.
Definition: Item.php:31
global $DIC
Definition: shib_login.php:22
static getPluginObjectByType(string $type)
Return either a repoObject plugin or a orgunit extension plugin or null if the type is not a plugin...
sortByDate(array $data, bool $asc=true)
loadData()
Load data for current page.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
__construct(Container $dic, ilPlugin $plugin)
setTitle(string $a_title)
This class represents a block method of a block.
addBlockCommand(string $a_href, string $a_text, string $a_onclick="", ?RoundTrip $modal=null)
addSortOption(string $option, string $label, bool $active)
setPresentation(int $type)
Class ilCommonActionDispatcherGUI.
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
ilPDSelectedItemsBlockViewSettings $viewSettings