ILIAS  trunk Revision v12.0_alpha-1227-g7ff6d300864
class.ilObjDashboardSettingsGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
29
36{
37 public const VIEW_MODE_SETTINGS = 'Settings';
38 public const VIEW_MODE_PRESENTATION = 'Presentation';
39 public const VIEW_MODE_SORTING = 'Sorting';
40 public const DASH_SORT_PREFIX = 'dash_sort_by_';
41 public const DASH_ENABLE_PREFIX = 'dash_enable_';
42
44 protected readonly UIServices $ui;
46 protected readonly GUIService $style_gui;
47
48 public function __construct(
49 $a_data,
50 int $a_id,
51 bool $a_call_by_reference = true,
52 bool $a_prepare_output = true
53 ) {
54 global $DIC;
55
56 $this->ui = $DIC->ui();
57 $this->style_gui = $DIC->contentStyle()->gui();
58
59 parent::__construct($a_data, $a_id, $a_call_by_reference, $a_prepare_output);
60
61 $this->lng->loadLanguageModule('dash');
62 $this->view_settings = new ilPDSelectedItemsBlockViewSettings($this->user);
63 $this->side_panel_settings = new ilDashboardSidePanelSettingsRepository();
64 }
65
66 public function executeCommand(): void
67 {
68 $cmd = $this->ctrl->getCmd();
69
70 $this->prepareOutput();
71
72 if (!$this->rbac_system->checkAccess('read', $this->object->getRefId())) {
73 throw new ilPermissionException($this->lng->txt('no_permission'));
74 }
75
76 switch ($this->ctrl->getNextClass($this)) {
77 case strtolower(ilPermissionGUI::class):
78 $this->tabs_gui->activateTab('perm_settings');
79 $perm_gui = new ilPermissionGUI($this);
80 $this->ctrl->forwardCommand($perm_gui);
81 break;
82 case strtolower(ilDashboardPageLanguageSelectGUI::class):
83 $this->tabs_gui->activateTab('dash_customization');
84 $this->ctrl->forwardCommand(new ilDashboardPageLanguageSelectGUI());
85 break;
86 case strtolower(ilObjectContentStyleSettingsGUI::class):
87 $this->tabs_gui->clearTargets();
88 $this->ctrl->setParameterByClass(ilDashboardPageGUI::class, 'dshs_lang', $this->request->getQueryParams()['dshs_lang']);
89 $this->tabs_gui->setBackTarget($this->lng->txt('back'), $this->ctrl->getLinkTargetByClass(
90 [ilDashboardPageLanguageSelectGUI::class, ilDashboardPageGUI::class],
91 'edit'
92 ));
93 $gui = $this->style_gui->objectSettingsGUIForRefId(null, $this->getRefId());
94 $this->ctrl->setParameter($gui, 'dshs_lang', $this->request->getQueryParams()['dshs_lang']);
95 $this->ctrl->forwardCommand($gui);
96 break;
97 default:
98 $this->tabs_gui->activateTab('settings');
99 if (!$cmd || $cmd === 'view') {
100 $cmd = 'editSettings';
101 }
102
103 $this->$cmd();
104 break;
105 }
106 }
107
108 public function getAdminTabs(): void
109 {
110 if ($this->rbac_system->checkAccess('read', $this->object->getRefId())) {
111 $this->tabs_gui->addTarget(
112 'settings',
113 $this->ctrl->getLinkTarget($this, 'editSettings'),
114 ['editSettings', 'view']
115 );
116 $this->tabs_gui->addTarget(
117 'dash_customization',
118 $this->ctrl->getLinkTargetByClass(ilDashboardPageLanguageSelectGUI::class)
119 );
120 }
121
122 if ($this->rbac_system->checkAccess('edit_permission', $this->object->getRefId())) {
123 $this->tabs_gui->addTarget(
124 'perm_settings',
125 $this->ctrl->getLinkTargetByClass(ilPermissionGUI::class, 'perm'),
126 [],
127 ilPermissionGUI::class
128 );
129 }
130 }
131
132 public function editSettings(): void
133 {
134 if ($this->settings->get('rep_favourites', '0') !== '1') {
135 $content[] = $this->ui_factory->messageBox()->info($this->lng->txt('favourites_disabled_info'));
136 }
137
138 if ($this->settings->get('mmbr_my_crs_grp', '0') !== '1') {
139 $content[] = $this->ui_factory->messageBox()->info($this->lng->txt('memberships_disabled_info'));
140 }
141 $this->setSettingsSubTabs('general');
142 $table = new ilDashboardSortationTableGUI($this, 'editSettings', !$this->canWrite());
143 $this->tpl->setContent($table->getHTML());
144 }
145
146 public function editSorting(?StandardForm $form = null): void
147 {
148 $this->tabs_gui->activateTab('settings');
149 $this->setSettingsSubTabs('sorting');
150 $form = $form ?? $this->getViewForm(self::VIEW_MODE_SORTING);
151 $this->tpl->setContent($this->ui_renderer->renderAsync($form));
152 }
153
154 public function getViewForm(string $mode): ?StandardForm
155 {
156 switch ($mode) {
159 return $this->ui_factory->input()->container()->form()->standard(
160 $this->ctrl->getFormAction($this, 'save' . $mode),
161 array_map(
162 fn(int $view): Section => $this->getViewByMode($mode, $view),
163 $this->view_settings->getPresentationViews()
164 )
165 );
166 }
167 return null;
168 }
169
170 public function getViewSectionSorting(int $view, string $title): Section
171 {
172 if ($this->canWrite()) {
173 $this->tpl->addJavaScript("assets/js/SortationUserInputHandler.js");
174 }
175 $available = $this->view_settings->getAvailableSortOptionsByView($view);
176 $options = array_combine($available, $available);
177 $select_options = array_map(fn($s) => $this->lng->txt(self::DASH_SORT_PREFIX . $s), $options);
178 $available_sorting = array_map($this->sortingInputs($view), $options);
179 $default_sorting = $this->ui_factory
180 ->input()
181 ->field()
182 ->select($this->lng->txt('dash_default_sortation'), $select_options)
183 ->withValue($this->view_settings->getDefaultSortingByView($view))
184 ->withAdditionalOnLoadCode(
185 static fn(string $id) => "
186 document.getElementById('$id').setAttribute('data-select', 'sorting$view');
187 window.addEventListener('DOMContentLoaded', () => il.Dashboard.handleUserInputForSortationsByView($view));
188 "
189 );
190
191 return $this->ui_factory->input()->field()->section(
192 $this->maybeDisable([...$available_sorting, 'default_sorting' => $default_sorting]),
193 $title
194 );
195 }
196
197 public function getViewByMode(string $mode, int $view): Section
198 {
199 switch ($mode) {
201 return $this->getViewSectionSorting(
202 $view,
203 $this->lng->txt('dash_' . $this->view_settings->getViewName($view))
204 );
206 default:
207 return $this->getViewSectionPresentation(
208 $view,
209 $this->lng->txt('dash_' . $this->view_settings->getViewName($view))
210 );
211 }
212 }
213
214 public function saveSettings(): void
215 {
216 if ($this->canWrite()) {
217 $form_data = $this->request->getParsedBody();
218 foreach ($this->view_settings->getPresentationViews() as $presentation_view) {
219 if (isset($form_data['main_panel']['enable'][$presentation_view])) {
220 $this->view_settings->enableView(
221 $presentation_view,
222 (bool) $form_data['main_panel']['enable'][$presentation_view]
223 );
224 } elseif ($presentation_view !== ilPDSelectedItemsBlockConstants::VIEW_RECOMMENDED_CONTENT) {
225 $this->view_settings->enableView($presentation_view, false);
226 }
227 }
228
229 $positions = $form_data['main_panel']['position'];
230 asort($positions);
231 $this->view_settings->setViewPositions(array_keys($positions));
232
233 foreach ($this->side_panel_settings->getValidModules() as $mod) {
234 $this->side_panel_settings->enable($mod, (bool) ($form_data['side_panel']['enable'][$mod] ?? false));
235 }
236
237 $positions = $form_data['side_panel']['position'];
238 asort($positions);
239 $this->side_panel_settings->setPositions(array_keys($positions));
240
241 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_SUCCESS, $this->lng->txt('settings_saved'), true);
242 } else {
243 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_FAILURE, $this->lng->txt('no_permission'), true);
244 }
245 $this->ctrl->redirect($this, 'editSettings');
246 }
247
248 public function setSettingsSubTabs(string $a_active): void
249 {
250 $tabs = $this->tabs_gui;
253
254 if ($this->rbac_system->checkAccess('read', $this->object->getRefId())) {
255 $tabs->addSubTab(
256 'general',
257 $lng->txt('general_settings'),
258 $ctrl->getLinkTarget($this, 'editSettings')
259 );
260
261 $tabs->addSubTab(
262 'presentation',
263 $lng->txt('dash_presentation'),
264 $ctrl->getLinkTarget($this, 'editPresentation')
265 );
266
267 $tabs->addSubTab(
268 'sorting',
269 $lng->txt('dash_sortation'),
270 $ctrl->getLinkTarget($this, 'editSorting')
271 );
272 }
273
274 $tabs->activateSubTab($a_active);
275 }
276
277 public function editPresentation(): void
278 {
279 $this->tabs_gui->activateTab('settings');
280 $this->setSettingsSubTabs('presentation');
281
282 $form = $this->getViewForm(self::VIEW_MODE_PRESENTATION);
283
284 $this->tpl->setContent($this->ui_renderer->renderAsync($form));
285 }
286
287 public function editCustomization(): void
288 {
289 $this->ui->mainTemplate()->setOnScreenMessage(
290 $this->ui->mainTemplate()::MESSAGE_TYPE_INFO,
291 $this->lng->txt('dash_page_edit_info'),
292 true
293 );
294
295 $this->tabs_gui->activateTab('dash_customization');
296
297 $content = $this->ui->renderer()->render(
298 $this->ui->factory()->button()->standard(
299 $this->lng->txt('customize_page'),
300 $this->ctrl->getLinkTargetByClass([self::class, ilDashboardPageLanguageSelectGUI::class], 'select')
301 )
302 );
303
304 if (ilDashboardPageGUI::isLanguageAvailable($this->user->getLanguage())) {
305 $content .= (new ilDashboardPageGUI($this->user->getLanguage()))->showPage();
306 } elseif (ilDashboardPageGUI::isLanguageAvailable($this->lng->getContentLanguage())) {
307 $content .= (new ilDashboardPageGUI($this->lng->getDefaultLanguage()))->showPage();
308 }
309
310 $this->tpl->setContent($content);
311 }
312
313 public function getViewSectionPresentation(int $view, string $title): Section
314 {
316 $ops = $this->view_settings->getAvailablePresentationsByView($view);
317 $pres_options = array_column(
318 array_map(
319 static fn(int $k, string $v): array => [$v, $lng->txt('dash_' . $v)],
320 array_keys($ops),
321 $ops
322 ),
323 1,
324 0
325 );
326 $avail_pres = $this->ui_factory->input()->field()->multiSelect(
327 $lng->txt('dash_avail_presentation'),
328 $pres_options
329 )
330 ->withValue($this->view_settings->getActivePresentationsByView($view));
331 $default_pres = $this->ui_factory->input()->field()->radio($lng->txt('dash_default_presentation'))
332 ->withOption('list', $lng->txt('dash_list'))
333 ->withOption('tile', $lng->txt('dash_tile'));
334 $default_pres = $default_pres->withValue($this->view_settings->getDefaultPresentationByView($view));
335 return $this->ui_factory->input()->field()->section(
336 $this->maybeDisable(['avail_pres' => $avail_pres, 'default_pres' => $default_pres]),
337 $title
338 );
339 }
340
341 protected function savePresentation(): void
342 {
343 if ($this->canWrite()) {
344 $data = $this->getViewForm(self::VIEW_MODE_PRESENTATION)->withRequest($this->request)->getData();
345
346 foreach ($data as $view => $view_data) {
347 $this->view_settings->storeViewPresentation(
348 $view,
349 $view_data['default_pres'],
350 $view_data['avail_pres'] ?? []
351 );
352 }
353 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_SUCCESS, $this->lng->txt('msg_obj_modified'), true);
354 } else {
355 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_FAILURE, $this->lng->txt('no_permission'), true);
356 }
357 $this->ctrl->redirect($this, 'editPresentation');
358 }
359
360 public function saveSorting(): void
361 {
362 $form = null;
363 if ($this->canWrite()) {
364 $form = $this->getViewForm(self::VIEW_MODE_SORTING)->withRequest($this->request);
365 $data = $form->getData();
366 if ($data) {
367 foreach ($data as $view => $view_data) {
368 $avail_sorting = array_keys(array_filter($view_data));
369 $saved = array_filter($view_data, fn($x) => !is_bool($x));
370 if (isset($view_data['default_sorting'])) {
371 $this->view_settings->storeViewSorting(
372 $view,
373 $view_data['default_sorting'],
374 $avail_sorting
375 );
376 $this->view_settings->storeViewSortingOptions($view, $saved);
377 }
378 }
379 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_SUCCESS, $this->lng->txt('msg_obj_modified'), true);
380 } else {
381 $this->editSorting($form);
382 return;
383 }
384 } else {
385 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_FAILURE, $this->lng->txt('no_permission'), true);
386 }
387 $this->ctrl->redirect($this, 'editSorting');
388 }
389
394 private function maybeDisable(array $fields): array
395 {
396 if ($this->canWrite()) {
397 return $fields;
398 }
399
400 return array_map(static fn(FormInput $field): FormInput => $field->withDisabled(true), $fields);
401 }
402
403 private function canWrite(): bool
404 {
405 return $this->rbac_system->checkAccess('write', $this->object->getRefId());
406 }
407
411 private function manuallySortingSettings(int $view, string $name, array $saved): Input
412 {
413 $options = $this->view_settings->getSortingOptionsByView($view);
414 $sort_options = $this->view_settings->getAvailableOptionsBySortation($name);
415 $value = isset($saved[$name]) ?
416 ['new_items' => ($options[$name]['new_items'] ?? null) ?: 'top'] :
417 null;
418
419 return $this->ui_factory->input()->field()->optionalGroup([
420 'new_items' => array_reduce(
421 $sort_options,
422 fn($r, $o) => $r->withOption($o, $this->lng->txt('dash_manual_new_item_pos_' . $o)),
423 $this->ui_factory->input()->field()->radio($this->lng->txt('dash_manual_new_item_pos'), '')
424 )
425 ], $this->lng->txt(self::DASH_SORT_PREFIX . $name))
426 ->withValue($value);
427 }
428
432 private function sortingCheckbox(int $view, string $name, array $saved): Input
433 {
434 return $this->ui_factory->input()->field()
435 ->checkbox($this->lng->txt(self::DASH_SORT_PREFIX . $name))
436 ->withAdditionalOnLoadCode(fn(string $id) => "
437 document.getElementById('$id').closest('form').addEventListener('submit', e => (
438 e.target.querySelectorAll('input[disabled]').forEach(x => {x.disabled = false;})
439 ));
440 ")
441 ->withValue(isset($saved[$name]));
442 }
443
444 private function sortingInputs(int $view): Closure
445 {
446 $saved = array_flip($this->view_settings->getActiveSortingsByView($view));
447 $with_js = fn($name, $check) => $check->withAdditionalOnLoadCode(fn($id) => "
448 document.getElementById('$id').setAttribute('data-checkbox', 'activeSorting$view');
449 document.querySelector('#$id input').setAttribute('data-value', '$name')
450 ");
451
452 $special_settings = ['manually'];
453 $method_for = fn($name) => in_array($name, $special_settings, true) ?
454 $name . 'SortingSettings' :
455 'sortingCheckbox';
456
457 return fn(string $name) => $with_js($name, $this->{$method_for($name)}($view, $name, $saved));
458 }
459}
$check
Definition: buildRTE.php:81
Provides fluid interface to RBAC services.
Definition: UIServices.php:25
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Facade for consumer gui interface.
withDisabled(bool $is_disabled)
Get an input like this, but set it to a disabled state.static
Definition: FormInput.php:139
getLinkTarget(object $a_gui_obj, ?string $a_cmd=null, ?string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
@inheritDoc
@ilCtrl_Calls ilDashboardPageGUI: ilPageEditorGUI, ilEditClipboardGUI, ilMDEditorGUI @ilCtrl_isCalled...
static isLanguageAvailable(string $lang)
@ilCtrl_isCalledBy ilDashboardPageLanguageSelectGUI: ilObjDashboardSettingsGUI
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
@ilCtrl_Calls ilObjDashboardSettingsGUI: ilPermissionGUI @ilCtrl_Calls ilObjDashboardSettingsGUI: ilD...
getViewSectionPresentation(int $view, string $title)
manuallySortingSettings(int $view, string $name, array $saved)
getAdminTabs()
administration tabs show only permissions and trash folder
sortingCheckbox(int $view, string $name, array $saved)
readonly ilDashboardSidePanelSettingsRepository $side_panel_settings
readonly ilPDSelectedItemsBlockViewSettings $view_settings
__construct( $a_data, int $a_id, bool $a_call_by_reference=true, bool $a_prepare_output=true)
getViewSectionSorting(int $view, string $title)
Class ilObjectGUI Basic methods of all Output classes.
ilTabsGUI $tabs_gui
prepareOutput(bool $show_sub_objects=true)
ilLanguage $lng
This describes inputs that can be used in forms.
Definition: FormInput.php:33
This describes a standard form.
Definition: Standard.php:30
This describes section inputs.
Definition: Section.php:29
This describes commonalities between all inputs.
Definition: Input.php:47
withValue($value)
Get an input like this with another value displayed on the client side.
An entity that renders components to a string output.
Definition: Renderer.php:31
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Group.php:61
global $DIC
Definition: shib_login.php:26