ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
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  $groupedCards = [];
95  foreach ($this->loadData() as $title => $group) {
96  $items = [];
97  foreach ($group as $datum) {
98  $item = $this->getListItemForDataDTO($datum);
99  if ($item !== null) {
100  $items[] = $item;
101  }
102  }
103  $groupedCards[] = $this->factory->item()->group((string) $title, $items);
104  }
105 
106  return $groupedCards;
107  }
108 
109  protected function getListItemForDataDTO(BlockDTO $data): ?Item
110  {
111  $itemListGui = $this->byType($data->getType());
112  $this->addCustomCommandsToActionMenu($itemListGui, $data->getRefId());
113  $list_item = $itemListGui->getAsListItem(
114  $data->getRefId(),
115  $data->getObjId(),
116  $data->getType(),
117  $data->getTitle(),
118  $data->getDescription()
119  );
120 
121  $list_item = $list_item->withProperties($list_item->getProperties() + $data->getAdditionalData());
122 
123  return $list_item;
124  }
125 
126  protected function isRepositoryObject(): bool
127  {
128  return false;
129  }
130 
131  protected function getLegacyContent(): string
132  {
133  $groupedCards = [];
134  foreach ($this->loadData() as $title => $group) {
135  $cards = array_filter(array_map($this->getCardForData(...), $group));
136  if ($cards) {
137  $groupedCards[] = $this->ui->factory()->panel()->sub(
138  (string) $title,
139  $this->factory->deck($cards)->withNormalCardsSize()
140  );
141  }
142  }
143 
144  if ($groupedCards) {
145  return $this->renderer->render($groupedCards);
146  }
147 
148  return $this->getNoItemFoundContent();
149  }
150 
151  protected function preloadData(array $data): void
152  {
153  $obj_ids = [];
154  foreach ($data as $group) {
155  foreach ($group as $datum) {
156  $obj_ids[] = $datum->getObjId();
157  }
158  }
160  parent::preloadData($data);
161  }
162 
163  public function getNoItemFoundContent(): string
164  {
165  return $this->emptyHandling();
166  }
167 
169  {
170  return $this->viewSettings;
171  }
172 
173  public function init(): void
174  {
175  $this->lng->loadLanguageModule('dash');
176  $this->lng->loadLanguageModule('rep');
177  $this->lng->loadLanguageModule('pd');
178  $this->initViewSettings();
179  $this->viewSettings->parse();
180  $this->requested_item_ref_id = (int) ($this->http->request()->getQueryParams()['item_ref_id'] ?? 0);
181  $this->initData();
182 
183  $this->ctrl->setParameter($this, 'view', $this->viewSettings->getCurrentView());
184  if ($this->viewSettings->isTilePresentation()) {
185  $this->setPresentation(self::PRES_MAIN_LEG);
186  } else {
187  $this->setPresentation(self::PRES_SEC_LIST);
188  }
189  }
190 
191  protected function initAndShow(): string
192  {
193  $this->init();
194  if ($this->parent === ilDashboardGUI::class) {
195  $this->ctrl->redirectByClass(ilDashboardGUI::class, 'show');
196  }
197 
198  return $this->getHTML();
199  }
200 
201  public function getHTML(): string
202  {
203  $this->setTitle(
204  $this->lng->txt('dash_' . $this->viewSettings->getViewName($this->viewSettings->getCurrentView()))
205  );
206 
207  if (!$this->data) {
208  return $this->emptyHandling();
209  }
210 
211  $this->addCommandActions();
212  $this->setData($this->getItemGroups());
213 
214  return parent::getHTML();
215  }
216 
220  public function setData(array $a_data): void
221  {
222  $this->data = array_filter(
223  array_map(
224  static fn($group) => array_filter($group, static fn($item) => $item instanceof BlockDTO),
225  $a_data
226  )
227  );
228  }
229 
233  public function getData(): array
234  {
235  return parent::getData();
236  }
237 
241  public function groupItemsByStartDate(): array
242  {
243  $data = $this->getData();
245  $items = array_merge(...array_values($data));
246 
247  $groups = [
248  'upcoming' => [],
249  'ongoing' => [],
250  'ended' => [],
251  'not_dated' => []
252  ];
253  foreach ($items as $item) {
254  if ($item->isDated()) {
255  if ($item->hasNotStarted()) {
256  $groups['upcoming'][] = $item;
257  } elseif ($item->isRunning()) {
258  $groups['ongoing'][] = $item;
259  } else {
260  $groups['ended'][] = $item;
261  }
262  } else {
263  $groups['not_dated'][] = $item;
264  }
265  }
266 
267  foreach ($groups as $key => $group) {
268  $group = $this->sortByTitle($group);
269  if ($key !== 'not_dated') {
270  $group = $this->sortByDate($group, $key === 'upcoming');
271  }
272  $groups[$this->lng->txt('pd_' . $key)] = $group;
273  unset($groups[$key]);
274  }
275  return $groups;
276  }
277 
281  protected function groupItemsByType(): array
282  {
283  $object_types_by_container = $this->objDefinition->getGroupedRepositoryObjectTypes(
284  ['cat', 'crs', 'grp', 'fold']
285  );
286  $grouped_items = [];
287  $data = $this->getData();
289  $data = array_merge(...array_values($data));
290 
291  foreach ($object_types_by_container as $type_title => $type) {
292  if (!$this->objDefinition->isPlugin($type_title)) {
293  $title = $this->lng->txt('objs_' . $type_title);
294  } else {
295  $pl = ilObjectPlugin::getPluginObjectByType($type_title);
296  $title = $pl->txt('objs_' . $type_title);
297  }
298 
299  foreach ($data as $item) {
300  if (in_array($item->getType(), $type['objs'])) {
301  $grouped_items[$title][] = $item;
302  }
303  }
304  }
305 
306  foreach ($grouped_items as $key => $group) {
307  $grouped_items[$key] = $this->sortByTitle($group);
308  }
309 
310  return $grouped_items;
311  }
312 
316  protected function groupItemsByLocation(): array
317  {
318  $grouped_items = [];
319  $data = $this->getData();
321  $data = array_merge(...array_values($data));
322 
323  $parent_ref_ids = array_values(array_unique(
324  array_map(fn(BlockDTO $item): ?int => $this->tree->getParentId($item->getRefId()), $data)
325  ));
326  $this->object_cache->preloadReferenceCache($parent_ref_ids);
327 
328  foreach ($data as $item) {
329  $parent_ref = $this->tree->getParentId($item->getRefId());
330  if ($this->isRootNode($parent_ref)) {
331  $title = $this->getRepositoryTitle();
332  } else {
333  $title = $this->object_cache->lookupTitle($this->object_cache->lookupObjId($parent_ref));
334  }
335  $grouped_items[$title][] = $item;
336  }
337  ksort($grouped_items);
338  $grouped_items = array_map($this->sortByTitle(...), $grouped_items);
339  return $grouped_items;
340  }
341 
342  protected function isRootNode(int $refId): bool
343  {
344  return $this->tree->getRootId() === $refId;
345  }
346 
347  protected function getRepositoryTitle(): string
348  {
349  $nd = $this->tree->getNodeData($this->tree->getRootId());
350  $title = $nd['title'];
351 
352  if ($title === 'ILIAS') {
353  $title = $this->lng->txt('repository');
354  }
355 
356  return $title;
357  }
358 
359  public function addCommandActions(): void
360  {
361  $sortings = $this->viewSettings->getSelectableSortingModes();
362  if (count($sortings) > 1) {
363  foreach ($sortings as $sorting) {
364  $this->addSortOption(
365  $sorting,
366  $this->lng->txt(ilObjDashboardSettingsGUI::DASH_SORT_PREFIX . $sorting),
367  $sorting === $this->viewSettings->getEffectiveSortingMode()
368  );
369  }
370  $this->setSortTarget($this->ctrl->getLinkTarget($this, 'changePDItemSorting'));
371  }
372 
373  $presentations = $this->viewSettings->getSelectablePresentationModes();
374  foreach ($presentations as $presentation) {
375  $this->ctrl->setParameter($this, 'presentation', $presentation);
376  $this->addPresentation(
377  $this->ui->renderer()->render($this->ui->factory()->symbol()->glyph()->{$presentation . 'View'}()),
378  $this->ctrl->getLinkTarget($this, 'changePDItemPresentation'),
379  $presentation === $this->viewSettings->getEffectivePresentationMode()
380  );
381  $this->ctrl->setParameter($this, 'presentation', null);
382  }
383 
384  if ($this->removeMultipleEnabled()) {
385  $this->addBlockCommand(
386  $this->ctrl->getLinkTarget($this, 'manage'),
388  '',
389  $this->getRemoveModal()
390  );
391  }
392  }
393 
394  public function getRemoveModal(): RoundTrip
395  {
396  $items = $this->getManageFields();
397  if ($items !== []) {
398  if ($this->viewSettings->isSelectedItemsViewActive()) {
399  $question = $this->lng->txt('dash_info_sure_remove_from_favs');
400  } else {
401  $this->lng->loadLanguageModule('mmbr');
402  $question = $this->lng->txt('mmbr_info_delete_sure_unsubscribe');
403  }
404  $modal = $this->ui->factory()->modal()->roundtrip(
406  [
407  $this->ui->factory()->messageBox()->confirmation($question),
408  $this->ui->factory()->messageBox()->info($this->lng->txt('select_one')),
409  ],
410  $items,
411  $this->ctrl->getLinkTargetByClass([ilDashboardGUI::class, $this::class], 'confirmedRemove')
412  )->withSubmitLabel($this->getRemoveMultipleActionText());
413 
414  $modal = $modal->withOnLoadCode(static fn($id) => "il.Dashboard.confirmModal($id)");
415  } else {
416  $modal = $this->ui->factory()->modal()->roundtrip(
418  $this->ui->factory()->messageBox()->info($this->lng->txt('pd_no_items_to_manage'))
419  );
420  }
421 
422  return $modal;
423  }
424 
425  protected function getManageFields(): array
426  {
427  $inputs = [];
428  foreach ($this->getItemGroups() as $key => $item_group) {
429  $options = [];
430  foreach ($item_group as $item) {
431  $icon = $this->ui->renderer()->render($this->ui->factory()->symbol()->icon()->custom(ilObject::_getIcon($item->getObjId()), ''));
432  if ($this instanceof ilMembershipBlockGUI) {
433  if ($this->rbacsystem->checkAccess('leave', $item->getRefId())) {
434  if ($item->getType() === 'crs' || $item->getType() === 'grp') {
435  $members_obj = ilParticipants::getInstance($item->getRefId());
436  if (!$members_obj->checkLastAdmin([$this->user->getId()])) {
437  continue;
438  }
439  }
440  $options[$item->getRefId()] = $icon . $item->getTitle();
441  }
442  } else {
443  $options[$item->getRefId()] = $icon . $item->getTitle();
444  }
445  }
446  if ($options !== []) {
447  $inputs[] = $this->ui->factory()->input()->field()->multiSelect((string) $key, $options)
448  ->withAdditionalTransformation($this->refinery->to()->listOf($this->refinery->kindlyTo()->int()));
449  }
450  }
451 
452  return $inputs;
453  }
454 
455  public function executeCommand(): string
456  {
457  $next_class = $this->ctrl->getNextClass();
458  $cmd = $this->ctrl->getCmd('getHTML');
459 
460  switch ($next_class) {
461  case strtolower(ilCommonActionDispatcherGUI::class):
463  if ($gui instanceof ilCommonActionDispatcherGUI) {
464  $this->ctrl->forwardCommand($gui);
465  }
466  break;
467 
468  default:
469  switch ($cmd) {
470  case 'confirmedRemove':
471  $form = $this->ui->factory()->input()->container()->form()->standard('', $this->getManageFields())->withRequest($this->http->request());
472  $this->confirmedRemove(array_merge(...array_filter($form->getData())));
473  // no break
474  default:
475  if (method_exists($this, $cmd . 'Object')) {
476  return $this->{$cmd . 'Object'}();
477  }
478  }
479  }
480  return '';
481  }
482 
483  public function viewDashboardObject(): void
484  {
485  $this->initAndShow();
486  }
487 
488  public function changePDItemSortingObject(): string
489  {
490  $this->viewSettings->storeActorSortingMode(
491  ilUtil::stripSlashes((string) ($this->http->request()->getQueryParams()['sorting'] ?? ''))
492  );
493 
494  return $this->initAndShow();
495  }
496 
497  public function changePDItemPresentationObject(): string
498  {
499  $this->viewSettings->storeActorPresentationMode(
500  ilUtil::stripSlashes((string) ($this->http->request()->getQueryParams()['presentation'] ?? ''))
501  );
502  return $this->initAndShow();
503  }
504 
508  public function getItemGroups(): array
509  {
510  switch ($this->viewSettings->getEffectiveSortingMode()) {
512  $data = $this->getData();
513  $data = array_merge(...array_values($data));
514  $data = $this->sortByTitle($data);
515  return ['' => $data];
517  return $this->groupItemsByStartDate();
519  return $this->groupItemsByType();
521  default:
522  return $this->groupItemsByLocation();
523  }
524  }
525 
526  public function addToDeskObject(): void
527  {
528  $this->favourites_manager->add($this->user->getId(), $this->requested_item_ref_id);
529  $this->main_tpl->setOnScreenMessage('success', $this->lng->txt('rep_added_to_favourites'), true);
530  $this->ctrl->redirectByClass(ilDashboardGUI::class, 'show');
531  }
532 
533  public function removeFromDeskObject(): void
534  {
535  $this->favourites_manager->remove($this->user->getId(), $this->requested_item_ref_id);
536  $this->main_tpl->setOnScreenMessage('success', $this->lng->txt('rep_removed_from_favourites'), true);
537  $this->ctrl->redirectByClass(ilDashboardGUI::class, 'show');
538  }
539 
540  abstract public function removeMultipleEnabled(): bool;
541 
542  abstract public function getRemoveMultipleActionText(): string;
543 
547  public function confirmedRemove(array $ids): void
548  {
549  }
550 
551  public function byType(string $a_type): ilObjectListGUI
552  {
553  $class = $this->objDefinition->getClassName($a_type);
554  if (!$class) {
555  throw new ilException(sprintf('Could not find a class for object type: %s', $a_type));
556  }
557 
558  $location = $this->objDefinition->getLocation($a_type);
559  if (!$location) {
560  throw new ilException(sprintf('Could not find a class location for object type: %s', $a_type));
561  }
562 
563  $full_class = 'ilObj' . $class . 'ListGUI';
564  $item_list_gui = new $full_class();
565 
566  $item_list_gui->setContainerObject($this);
567  $item_list_gui->enableNotes(false);
568  $item_list_gui->enableComments(false);
569  $item_list_gui->enableTags(false);
570 
571  $item_list_gui->enableIcon(true);
572  $item_list_gui->enableDelete(false);
573  $item_list_gui->enableCut(false);
574  $item_list_gui->enableCopy(false);
575  $item_list_gui->enableLink(false);
576  $item_list_gui->enableInfoScreen(true);
577 
578  $item_list_gui->enableCommands(true, true);
579 
580  return $item_list_gui;
581  }
582 
586  private function sortByDate(array $data, bool $asc = true): array
587  {
588  usort(
589  $data,
590  static fn(BlockDTO $left, BlockDTO $right): int =>
591  ($asc ? -1 : 1) *
592  (($right->getStartDate()?->get(IL_CAL_UNIX) ?? 0) - ($left->getStartDate()?->get(IL_CAL_UNIX) ?? 0))
593  );
594  return $data;
595  }
596 
600  private function sortByTitle(array $data): array
601  {
602  usort(
603  $data,
604  static fn(BlockDTO $left, BlockDTO $right): int => strcmp($left->getTitle(), $right->getTitle())
605  );
606  return $data;
607  }
608 }
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
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:26
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