ILIAS  trunk Revision v12.0_alpha-1338-g8f7e531aa3c
class.ilCourseContentGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=0);
20
23use ILIAS\UI\Factory as UIFactory;
24use ILIAS\UI\Renderer as UIRenderer;
26
34{
39
42 protected ilLanguage $lng;
43 protected ilTabsGUI $tabs;
47 protected ilObjUser $user;
49 protected ilTree $tree;
51 protected Factory $refinery;
52 protected UIFactory $ui_factory;
53 protected UIRenderer $ui_renderer;
54 protected LOMServices $lom_services;
55
56 public function __construct(ilContainerGUI $container_gui_obj)
57 {
58 global $DIC;
59
60 $this->main_tpl = $DIC->ui()->mainTemplate();
61 $this->tpl = $DIC->ui()->mainTemplate();
62 $this->ctrl = $DIC->ctrl();
63 $this->lng = $DIC->language();
64 $this->tabs = $DIC->tabs();
65 $this->fav_manager = new ilFavouritesManager();
66 $this->access = $DIC->access();
67 $this->error = $DIC['ilErr'];
68 $this->user = $DIC->user();
69 $this->objectDataCache = $DIC['ilObjDataCache'];
70 $this->tree = $DIC->repositoryTree();
71 $this->http = $DIC->http();
72 $this->refinery = $DIC->refinery();
73 $this->ui_factory = $DIC->ui()->factory();
74 $this->ui_renderer = $DIC->ui()->renderer();
75 $this->lom_services = $DIC->learningObjectMetadata();
76
77 $this->container_gui = $container_gui_obj;
78 $this->container_obj = $this->container_gui->getObject();
79 $this->initCourseObject();
80 }
81
82 public function executeCommand(): void
83 {
84 if (!$this->access->checkAccess('read', '', $this->container_obj->getRefId())) {
85 $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->WARNING);
86 }
87
88 $this->__setSubTabs();
89 $this->tabs->setTabActive('view_content');
90 $cmd = $this->ctrl->getCmd();
91
92 switch ($this->ctrl->getNextClass($this)) {
93 default:
94 $start = $this->initStartObjects();
95 if ($start instanceof ilCourseStart) {
96 $this->showStartObjects($start);
97 break;
98 }
99 if (!$cmd) {
100 throw new RuntimeException('Missing ctrl command.');
101 }
102 $this->$cmd();
103 break;
104 }
105 }
106
107 protected function initMemberIdFromQuery(): int
108 {
109 if ($this->http->wrapper()->query()->has('member_id')) {
110 return $this->http->wrapper()->query()->retrieve(
111 'member_id',
112 $this->refinery->kindlyTo()->int()
113 );
114 }
115 return 0;
116 }
117
119 {
121 }
122
123 public function initStartObjects(): ?ilCourseStart
124 {
125 if ($this->access->checkAccess('write', '', $this->course_obj->getRefId())) {
126 return null;
127 }
128 $start_obj = new ilCourseStart($this->course_obj->getRefId(), $this->course_obj->getId());
129 if (count($start_obj->getStartObjects()) && !$start_obj->allFullfilled($this->user->getId())) {
130 return $start_obj;
131 }
132 return null;
133 }
134
135 public function showStartObjects(ilCourseStart $start_obj): void
136 {
137 $this->tabs->setSubTabActive('crs_content');
138
139 $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.crs_start_view.html", 'components/ILIAS/Course');
140 $this->tpl->setVariable("INFO_STRING", $this->lng->txt('crs_info_start'));
141 $this->tpl->setVariable("TBL_TITLE_START", $this->lng->txt('crs_table_start_objects'));
142 $this->tpl->setVariable("HEADER_NR", $this->lng->txt('crs_nr'));
143 $this->tpl->setVariable("HEADER_DESC", $this->lng->txt('description'));
144 $this->tpl->setVariable("HEADER_EDITED", $this->lng->txt('crs_objective_accomplished'));
145
146 $lm_continue = new ilCourseLMHistory($this->course_obj->getRefId(), $this->user->getId());
147 $continue_data = $lm_continue->getLMHistory();
148
149 $counter = 0;
150 foreach ($start_obj->getStartObjects() as $start) {
151 $obj_id = $this->objectDataCache->lookupObjId((int) $start['item_ref_id']);
152 $ref_id = $start['item_ref_id'];
153 $type = $this->objectDataCache->lookupType($obj_id);
154
156
157 $obj_link = ilLink::_getLink($ref_id, $type);
158 $obj_frame = '';
159
160 // Tmp fix for tests
161 $obj_frame = $type == 'tst' ? '' : $obj_frame;
162
163 if ($this->access->checkAccess('read', '', $ref_id)) {
164 $this->tpl->setCurrentBlock("start_read");
165 $this->tpl->setVariable("READ_TITLE_START", $this->objectDataCache->lookupTitle($obj_id));
166 $this->tpl->setVariable("READ_TARGET_START", $obj_frame);
167 $this->tpl->setVariable(
168 "READ_LINK_START",
169 $obj_link . '&crs_show_result=' . $this->course_obj->getRefId()
170 );
171 $this->tpl->parseCurrentBlock();
172 } else {
173 $this->tpl->setCurrentBlock("start_visible");
174 $this->tpl->setVariable("VISIBLE_LINK_START", $this->objectDataCache->lookupTitle($obj_id));
175 $this->tpl->parseCurrentBlock();
176 }
177
178 // CONTINUE LINK
179 if (isset($continue_data[$ref_id])) {
180 $this->tpl->setCurrentBlock("link");
181 $this->tpl->setVariable("LINK_HREF", ilLink::_getLink($ref_id, '', array('obj_id',
182 $continue_data[$ref_id]['lm_page_id']
183 )));
184 #$this->tpl->setVariable("CONTINUE_LINK_TARGET",$target);
185 $this->tpl->setVariable("LINK_NAME", $this->lng->txt('continue_work'));
186 $this->tpl->parseCurrentBlock();
187 }
188
189 // add to desktop link
190 $this->lng->loadLanguageModule('dash');
191 if ($this->course_obj->getAboStatus()) {
192 if (!$this->fav_manager->ifIsFavourite($this->user->getId(), $ref_id)) {
193 if ($this->access->checkAccess('read', '', $ref_id)) {
194 $this->tpl->setCurrentBlock("link");
195 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'item_ref_id', $ref_id);
196 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'item_id', $ref_id);
197 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'type', $type);
198
199 $this->tpl->setVariable(
200 "LINK_HREF",
201 $this->ctrl->getLinkTarget($this->container_gui, 'addToDesk')
202 );
203 $this->tpl->setVariable("LINK_NAME", $this->lng->txt("add_to_favourites"));
204 $this->tpl->parseCurrentBlock();
205 }
206 } else {
207 $this->tpl->setCurrentBlock("link");
208 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'item_ref_id', $ref_id);
209 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'item_id', $ref_id);
210 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'type', $type);
211
212 $this->tpl->setVariable(
213 "LINK_HREF",
214 $this->ctrl->getLinkTarget($this->container_gui, 'removeFromDesk')
215 );
216 $this->tpl->setVariable("LINK_NAME", $this->lng->txt("remove_from_favourites"));
217 $this->tpl->parseCurrentBlock();
218 }
219 }
220
221 // Description
222 if (strlen($this->objectDataCache->lookupDescription($obj_id))) {
223 $this->tpl->setCurrentBlock("start_description");
224 $this->tpl->setVariable("DESCRIPTION_START", $this->objectDataCache->lookupDescription($obj_id));
225 $this->tpl->parseCurrentBlock();
226 }
227
228 if ($start_obj->isFullfilled($this->user->getId(), $ref_id)) {
229 $accomplished = 'accomplished';
230 $icon = ilUtil::getImagePath("standard/icon_ok.svg");
231 } else {
232 $accomplished = 'not_accomplished';
233 $icon = ilUtil::getImagePath("standard/icon_not_ok.svg");
234 }
235 $this->tpl->setCurrentBlock("start_row");
236 $this->tpl->setVariable("EDITED_IMG", $icon);
237 $this->tpl->setVariable("EDITED_ALT", $this->lng->txt('crs_objective_' . $accomplished));
238 $this->tpl->setVariable("ROW_CLASS", 'option_value');
239 $this->tpl->setVariable("ROW_CLASS_CENTER", 'option_value_center');
240 $this->tpl->setVariable("OBJ_NR_START", ++$counter . '.');
241 $this->tpl->parseCurrentBlock();
242 }
243 }
244
248 protected function manageTimings(array $failed_items = []): void
249 {
250 if (!$this->access->checkAccess('write', '', $this->container_obj->getRefId())) {
251 $this->error->raiseError($this->lng->txt('msg_no_perm_write'), $this->error->WARNING);
252 }
253 $this->tabs->setTabActive('timings_timings');
254 $this->tabs->clearSubTabs();
255
256 $table = new ilTimingsManageTableGUI(
257 $this,
258 'manageTimings',
259 $this->getContainerObject(),
260 $this->course_obj
261 );
262 if ($failed_items !== []) {
263 $table->setFailureStatus(true);
264 }
265 $table->init();
266 $table->parse(
268 $failed_items
269 );
270 $this->tpl->setContent($table->getHTML());
271 }
272
276 protected function managePersonalTimings(array $failed = []): void
277 {
278 global $ilErr, $ilAccess;
279
280 if (!$this->access->checkAccess('read', '', $this->container_obj->getRefId())) {
281 $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $ilErr->WARNING);
282 }
283 $this->tabs->setTabActive('timings_timings');
284 $this->tabs->clearSubTabs();
285
286 $table = new ilTimingsPersonalTableGUI(
287 $this,
288 'managePersonalTimings',
289 $this->getContainerObject(),
290 $this->course_obj
291 );
292 $table->setFailureStatus((bool) count($failed));
293 $table->setUserId($this->user->getId());
294 $table->init();
295 $table->parse(
297 $this->getContainerObject()->getRefId(),
298 false
299 ),
300 $failed
301 );
302 $this->tpl->setContent($table->getHTML());
303 }
304
308 protected function updatePersonalTimings(): bool
309 {
310 if (!$this->access->checkAccess('read', '', $this->container_obj->getRefId())) {
311 $this->error->raiseError($this->lng->txt('msg_no_perm_write'), $this->error->WARNING);
312 }
313 $this->tabs->clearSubTabs();
314 $failed = array();
315
316 $post_item = (array) ($this->http->request()->getParsedBody()['item'] ?? []);
317 foreach ($post_item as $ref_id => $data) {
318 $sug_start_dt = ilCalendarUtil::parseIncomingDate($data['sug_start']);
319 $sug_end_dt = ilCalendarUtil::parseIncomingDate($data['sug_end']);
320
321 if ($sug_start_dt instanceof ilDate && $sug_end_dt instanceof ilDate) {
322 if (ilDateTime::_after($sug_start_dt, $sug_end_dt)) {
323 $failed[$ref_id] = 'crs_timing_err_start_end';
324 continue;
325 }
326 // update user date
327 $tu = new ilTimingUser($ref_id, $GLOBALS['ilUser']->getId());
328 $tu->getStart()->setDate($sug_start_dt->get(IL_CAL_UNIX), IL_CAL_UNIX);
329 $tu->getEnd()->setDate($sug_end_dt->get(IL_CAL_UNIX), IL_CAL_UNIX);
330 $tu->update();
331 } else {
332 $failed['ref_id'] = 'crs_timing_err_valid_dates';
333 }
334 }
335 if ($failed === []) {
336 $this->main_tpl->setOnScreenMessage('success', $GLOBALS['lng']->txt('settings_saved'));
337 $this->managePersonalTimings();
338 return true;
339 } else {
340 $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'));
341 $this->managePersonalTimings($failed);
342 return true;
343 }
344 }
345
346 public function returnToMembers(): void
347 {
348 $this->ctrl->returnToParent($this);
349 }
350
355 public function showUserTimings(): void
356 {
357 $this->tpl->addBlockfile('ADM_CONTENT', 'adm_content', 'tpl.crs_user_timings.html', 'components/ILIAS/Course');
358 $this->tabs->clearSubTabs();
359 $this->tabs->setTabActive('members');
360
361 if (!$this->initMemberIdFromQuery()) {
362 $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('no_checkbox'), true);
363 $this->ctrl->returnToParent($this);
364 }
365
366 // Back button
367 $this->tpl->addBlockfile("BUTTONS", "buttons", "tpl.buttons.html");
368 $this->tpl->setCurrentBlock("btn_cell");
369 $this->tpl->setVariable("BTN_LINK", $this->ctrl->getLinkTarget($this, 'returnToMembers'));
370 $this->tpl->setVariable("BTN_TXT", $this->lng->txt("back"));
371 $this->tpl->parseCurrentBlock();
372
373 $usr_icon = $this->ui_factory->symbol()->icon()->standard(
374 'usr',
375 $this->lng->txt('obj_usr'),
376 'large'
377 );
378 $this->tpl->setVariable("HEADER_IMG", $this->ui_renderer->render($usr_icon));
379 $this->tpl->setVariable("TABLE_HEADER", $this->lng->txt('timings_of'));
381 $this->tpl->setVariable("USER_NAME", $name['lastname'] . ', ' . $name['firstname']);
382
383 $this->tpl->setVariable("TXT_TITLE", $this->lng->txt('title'));
384 $this->tpl->setVariable("TXT_START_END", $this->lng->txt('crs_timings_short_start_end'));
385 $this->tpl->setVariable("TXT_INFO_START_END", $this->lng->txt('crs_timings_start_end_info'));
386 $this->tpl->setVariable("TXT_CHANGED", $this->lng->txt('crs_timings_changed'));
387 $this->tpl->setVariable("TXT_OWN_PRESETTING", $this->lng->txt('crs_timings_planed_start'));
388 $this->tpl->setVariable("TXT_INFO_OWN_PRESETTING", $this->lng->txt('crs_timings_from_until'));
389
390 $items = ilObjectActivation::getTimingsAdministrationItems($this->course_obj->getRefId());
391 foreach ($items as $item) {
392 if (($item['timing_type'] == ilObjectActivation::TIMINGS_PRESETTING) or
394 $this->__renderUserItem($item, 0);
395 }
396 }
397 }
398
403 public function __renderUserItem(array $item, int $level): void
404 {
405 $this->lng->loadLanguageModule('meta');
406
407 $usr_planed = new ilTimingUser($item['ref_id'], $this->initMemberIdFromQuery());
408
409 for ($i = 0; $i < $level; $i++) {
410 $this->tpl->touchBlock('start_indent');
411 $this->tpl->touchBlock('end_indent');
412 }
413 if (strlen($item['description'])) {
414 $this->tpl->setCurrentBlock("item_description");
415 $this->tpl->setVariable("DESC", $item['description']);
416 $this->tpl->parseCurrentBlock();
417 }
418
419 $tlt_data = $this->lom_services->read(
420 ilObject::_lookupObjId($item['ref_id']),
421 0,
422 $item['type'],
423 $this->lom_services->paths()->firstTypicalLearningTime()
424 )->firstData($this->lom_services->paths()->firstTypicalLearningTime());
425
426 if ($tlt = $this->lom_services->dataHelper()->durationToSeconds($tlt_data->value())) {
427 $this->tpl->setCurrentBlock("tlt");
428 $this->tpl->setVariable("TXT_TLT", $this->lng->txt('meta_typical_learning_time'));
429 $this->tpl->setVariable("TLT_VAL", ilDatePresentation::secondsToString($tlt));
430 $this->tpl->parseCurrentBlock();
431 }
432
433 if (!$item['title'] &&
434 $item['type'] == 'sess') {
437 $app_info['start'],
438 $app_info['end'],
439 (bool) $app_info['fullday']
440 );
441 }
442
443 $this->tpl->setCurrentBlock("title_plain");
444 $this->tpl->setVariable("TITLE", $item['title']);
445 $this->tpl->parseCurrentBlock();
446
447 $this->tpl->setCurrentBlock("container_standard_row");
448
449 $this->tpl->setVariable('TYPE_IMG', ilObject::_getIcon($item['obj_id'], 'tiny', $item['type']));
450 $this->tpl->setVariable("TYPE_ALT_IMG", $this->lng->txt('obj_' . $item['type']));
451
452 if ($item['timing_type'] == ilObjectActivation::TIMINGS_PRESETTING) {
453 if ($usr_planed->getStart()->get(IL_CAL_UNIX)) {
454 $this->tpl->setVariable('SUG_START', $usr_planed->getStart()->get(IL_CAL_DATE));
455 }
456 if ($usr_planed->getEnd()->get(IL_CAL_UNIX)) {
457 $this->tpl->setVariable('SUG_END', $usr_planed->getEnd()->get(IL_CAL_DATE));
458 }
459 }
460 $this->tpl->parseCurrentBlock();
461 foreach (ilObjectActivation::getTimingsAdministrationItems($item['ref_id']) as $item_data) {
462 if (($item_data['timing_type'] == ilObjectActivation::TIMINGS_PRESETTING) or
463 ilObjectActivation::hasChangeableTimings($item_data['ref_id'])) {
464 $this->__renderUserItem($item_data, $level + 1);
465 }
466 }
467 }
468
469 protected function updateManagedTimings(): bool
470 {
471 if (!$this->access->checkAccess('write', '', $this->container_obj->getRefId())) {
472 $this->error->raiseError($this->lng->txt('msg_no_perm_write'), $this->error->WARNING);
473 }
474
475 $this->tabs->clearSubTabs();
476
477 $failed = array();
478 $post_item = (array) ($this->http->request()->getParsedBody()['item']) ?? [];
479 foreach ($post_item as $ref_id => $data) {
480 $item_obj = new ilObjectActivation();
481 $item_obj->read($ref_id);
482
483 $data['active'] = $data['active'] ?? 0;
485 $item_obj->toggleChangeable((bool) ($data['change'] ?? false));
486
487 if ($this->course_obj->getTimingMode() == ilCourseConstants::IL_CRS_VIEW_TIMING_ABSOLUTE) {
488 $sug_start_dt = ilCalendarUtil::parseIncomingDate($data['sug_start'] ?? '');
489 $sug_end_dt = ilCalendarUtil::parseIncomingDate($data['sug_end'] ?? '');
490
491 if ($sug_start_dt instanceof ilDate && $sug_end_dt instanceof ilDate) {
492 if (ilDateTime::_after($sug_start_dt, $sug_end_dt)) {
493 $failed[$ref_id] = 'crs_timing_err_start_end';
494 continue;
495 }
496 $item_obj->setSuggestionStart($sug_start_dt->get(IL_CAL_UNIX));
497 $item_obj->setSuggestionEnd($sug_end_dt->get(IL_CAL_UNIX));
498 } else {
499 $failed['ref_id'] = 'crs_timing_err_valid_dates';
500 continue;
501 }
502 } else {
503 if (
504 (int) $data['sug_start_rel'] < 0 || (int) $data['duration_a'] < 0
505 ) {
506 $failed[$ref_id] = 'crs_timing_err_start_dur_rel';
507 continue;
508 }
509 $item_obj->setSuggestionStartRelative($data['sug_start_rel']);
510 $item_obj->setSuggestionEndRelative($data['sug_start_rel'] + $data['duration_a']);
511
512 // add default values for start/end (relative to now)
513 $start = new ilDate(time(), IL_CAL_UNIX);
514 $start->increment(IL_CAL_DAY, $data['sug_start_rel']);
515 $item_obj->setSuggestionStart($start->get(IL_CAL_UNIX));
516
517 $start->increment(IL_CAL_DAY, $data['duration_a']);
518 $item_obj->setSuggestionEnd($start->get(IL_CAL_UNIX));
519 }
520
521 $item_obj->update($ref_id);
522 }
523 if ($failed === []) {
524 // update course => create calendar entries
525 $this->course_obj->update();
526 $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'));
527 $this->manageTimings();
528 return true;
529 } else {
530 $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'));
531 $this->manageTimings($failed);
532 return true;
533 }
534 }
535
536 public function __setSubTabs(): void
537 {
538 if ($this->container_obj->getType() == 'crs') {
539 $this->container_gui->setContentSubTabs();
540 }
541 }
542
543 public function initCourseObject(): bool
544 {
545 if ($this->container_obj instanceof ilObjCourse) {
546 $this->course_obj = $this->container_obj;
547 } else {
548 $course_ref_id = $this->tree->checkForParentType($this->container_obj->getRefId(), 'crs');
549 $course = ilObjectFactory::getInstanceByRefId($course_ref_id, false);
550 if ($course instanceof ilObjCourse) {
551 $this->course_obj = $course;
552 }
553 }
554 return true;
555 }
556} // END class.ilCourseContentGUI
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
const IL_CAL_DATE
const IL_CAL_UNIX
const IL_CAL_DAY
error(string $a_errmsg)
static parseIncomingDate($value, bool $add_time=false)
Try to parse incoming value to date object.
static _checkAllConditionsOfTarget(int $a_target_ref_id, int $a_target_id, string $a_target_type="", int $a_usr_id=0)
checks wether all conditions of a target object are fulfilled
Class ilContainerGUI This is a base GUI class for all container objects in ILIAS: root folder,...
Class ilContainer.
Class ilCourseContentGUI.
ilFavouritesManager $fav_manager
ilObjectDataCache $objectDataCache
ilGlobalTemplateInterface $main_tpl
managePersonalTimings(array $failed=[])
Manage personal timings.
showStartObjects(ilCourseStart $start_obj)
updatePersonalTimings()
Update personal timings.
__renderUserItem(array $item, int $level)
__construct(ilContainerGUI $container_gui_obj)
ilGlobalTemplateInterface $tpl
manageTimings(array $failed_items=[])
Manage timings.
class ilCourseLMHistory
isFullfilled(int $user_id, int $item_id)
static secondsToString(int $seconds, bool $force_with_seconds=false, ?ilLanguage $a_lng=null)
converts seconds to string: Long: 7 days 4 hour(s) ...
static _after(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
Class for single dates.
Error Handling & global info handling.
Manages favourites, currently the interface for other components, needs discussion.
language handling
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
User class.
static _lookupName(int $a_user_id)
Class ilObjectActivation.
static hasChangeableTimings(int $ref_id)
Check if there is any active changeable timing (in subtree)
static getTimingsAdministrationItems(int $parent_id)
Get (sub) item data for timings administration view (active/inactive)
static getItems(int $parent_id, bool $with_list_data=true)
Get sub item data.
class ilObjectDataCache
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
static _lookupObjId(int $ref_id)
static _lookupAppointment(int $a_obj_id)
static _appointmentToString(int $start, int $end, bool $fulltime)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
TableGUI class for timings administration.
TableGUI class for timings administration.
TableGUI class for editing personal timings.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
Interface GlobalHttpState.
An entity that renders components to a string output.
Definition: Renderer.php:31
Interface ilAccessHandler This interface combines all available interfaces which can be called via gl...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static http()
Fetches the global http state from ILIAS.
$ilErr
Definition: raiseError.php:33
global $DIC
Definition: shib_login.php:26
$counter
$GLOBALS["DIC"]
Definition: wac.php:54