ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
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 if ($this->course_obj->getAboStatus()) {
191 if (!$this->fav_manager->ifIsFavourite($this->user->getId(), $ref_id)) {
192 if ($this->access->checkAccess('read', '', $ref_id)) {
193 $this->tpl->setCurrentBlock("link");
194 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'item_ref_id', $ref_id);
195 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'item_id', $ref_id);
196 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'type', $type);
197
198 $this->tpl->setVariable(
199 "LINK_HREF",
200 $this->ctrl->getLinkTarget($this->container_gui, 'addToDesk')
201 );
202 $this->tpl->setVariable("LINK_NAME", $this->lng->txt("rep_add_to_favourites"));
203 $this->tpl->parseCurrentBlock();
204 }
205 } else {
206 $this->tpl->setCurrentBlock("link");
207 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'item_ref_id', $ref_id);
208 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'item_id', $ref_id);
209 $this->ctrl->setParameterByClass(get_class($this->container_gui), 'type', $type);
210
211 $this->tpl->setVariable(
212 "LINK_HREF",
213 $this->ctrl->getLinkTarget($this->container_gui, 'removeFromDesk')
214 );
215 $this->tpl->setVariable("LINK_NAME", $this->lng->txt("rep_remove_from_favourites"));
216 $this->tpl->parseCurrentBlock();
217 }
218 }
219
220 // Description
221 if (strlen($this->objectDataCache->lookupDescription($obj_id))) {
222 $this->tpl->setCurrentBlock("start_description");
223 $this->tpl->setVariable("DESCRIPTION_START", $this->objectDataCache->lookupDescription($obj_id));
224 $this->tpl->parseCurrentBlock();
225 }
226
227 if ($start_obj->isFullfilled($this->user->getId(), $ref_id)) {
228 $accomplished = 'accomplished';
229 $icon = ilUtil::getImagePath("standard/icon_ok.svg");
230 } else {
231 $accomplished = 'not_accomplished';
232 $icon = ilUtil::getImagePath("standard/icon_not_ok.svg");
233 }
234 $this->tpl->setCurrentBlock("start_row");
235 $this->tpl->setVariable("EDITED_IMG", $icon);
236 $this->tpl->setVariable("EDITED_ALT", $this->lng->txt('crs_objective_' . $accomplished));
237 $this->tpl->setVariable("ROW_CLASS", 'option_value');
238 $this->tpl->setVariable("ROW_CLASS_CENTER", 'option_value_center');
239 $this->tpl->setVariable("OBJ_NR_START", ++$counter . '.');
240 $this->tpl->parseCurrentBlock();
241 }
242 }
243
247 protected function manageTimings(array $failed_items = []): void
248 {
249 if (!$this->access->checkAccess('write', '', $this->container_obj->getRefId())) {
250 $this->error->raiseError($this->lng->txt('msg_no_perm_write'), $this->error->WARNING);
251 }
252 $this->tabs->setTabActive('timings_timings');
253 $this->tabs->clearSubTabs();
254
255 $table = new ilTimingsManageTableGUI(
256 $this,
257 'manageTimings',
258 $this->getContainerObject(),
259 $this->course_obj
260 );
261 if ($failed_items !== []) {
262 $table->setFailureStatus(true);
263 }
264 $table->init();
265 $table->parse(
267 $failed_items
268 );
269 $this->tpl->setContent($table->getHTML());
270 }
271
275 protected function managePersonalTimings(array $failed = []): void
276 {
277 global $ilErr, $ilAccess;
278
279 if (!$this->access->checkAccess('read', '', $this->container_obj->getRefId())) {
280 $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $ilErr->WARNING);
281 }
282 $this->tabs->setTabActive('timings_timings');
283 $this->tabs->clearSubTabs();
284
285 $table = new ilTimingsPersonalTableGUI(
286 $this,
287 'managePersonalTimings',
288 $this->getContainerObject(),
289 $this->course_obj
290 );
291 $table->setFailureStatus((bool) count($failed));
292 $table->setUserId($this->user->getId());
293 $table->init();
294 $table->parse(
296 $this->getContainerObject()->getRefId(),
297 false
298 ),
299 $failed
300 );
301 $this->tpl->setContent($table->getHTML());
302 }
303
307 protected function updatePersonalTimings(): bool
308 {
309 if (!$this->access->checkAccess('read', '', $this->container_obj->getRefId())) {
310 $this->error->raiseError($this->lng->txt('msg_no_perm_write'), $this->error->WARNING);
311 }
312 $this->tabs->clearSubTabs();
313 $failed = array();
314
315 $post_item = (array) ($this->http->request()->getParsedBody()['item'] ?? []);
316 foreach ($post_item as $ref_id => $data) {
317 $sug_start_dt = ilCalendarUtil::parseIncomingDate($data['sug_start']);
318 $sug_end_dt = ilCalendarUtil::parseIncomingDate($data['sug_end']);
319
320 if ($sug_start_dt instanceof ilDate && $sug_end_dt instanceof ilDate) {
321 if (ilDateTime::_after($sug_start_dt, $sug_end_dt)) {
322 $failed[$ref_id] = 'crs_timing_err_start_end';
323 continue;
324 }
325 // update user date
326 $tu = new ilTimingUser($ref_id, $GLOBALS['ilUser']->getId());
327 $tu->getStart()->setDate($sug_start_dt->get(IL_CAL_UNIX), IL_CAL_UNIX);
328 $tu->getEnd()->setDate($sug_end_dt->get(IL_CAL_UNIX), IL_CAL_UNIX);
329 $tu->update();
330 } else {
331 $failed['ref_id'] = 'crs_timing_err_valid_dates';
332 }
333 }
334 if ($failed === []) {
335 $this->main_tpl->setOnScreenMessage('success', $GLOBALS['lng']->txt('settings_saved'));
336 $this->managePersonalTimings();
337 return true;
338 } else {
339 $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'));
340 $this->managePersonalTimings($failed);
341 return true;
342 }
343 }
344
345 public function returnToMembers(): void
346 {
347 $this->ctrl->returnToParent($this);
348 }
349
354 public function showUserTimings(): void
355 {
356 $this->tpl->addBlockfile('ADM_CONTENT', 'adm_content', 'tpl.crs_user_timings.html', 'components/ILIAS/Course');
357 $this->tabs->clearSubTabs();
358 $this->tabs->setTabActive('members');
359
360 if (!$this->initMemberIdFromQuery()) {
361 $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('no_checkbox'), true);
362 $this->ctrl->returnToParent($this);
363 }
364
365 // Back button
366 $this->tpl->addBlockfile("BUTTONS", "buttons", "tpl.buttons.html");
367 $this->tpl->setCurrentBlock("btn_cell");
368 $this->tpl->setVariable("BTN_LINK", $this->ctrl->getLinkTarget($this, 'returnToMembers'));
369 $this->tpl->setVariable("BTN_TXT", $this->lng->txt("back"));
370 $this->tpl->parseCurrentBlock();
371
372 $usr_icon = $this->ui_factory->symbol()->icon()->standard(
373 'usr',
374 $this->lng->txt('obj_usr'),
375 'large'
376 );
377 $this->tpl->setVariable("HEADER_IMG", $this->ui_renderer->render($usr_icon));
378 $this->tpl->setVariable("TABLE_HEADER", $this->lng->txt('timings_of'));
380 $this->tpl->setVariable("USER_NAME", $name['lastname'] . ', ' . $name['firstname']);
381
382 $this->tpl->setVariable("TXT_TITLE", $this->lng->txt('title'));
383 $this->tpl->setVariable("TXT_START_END", $this->lng->txt('crs_timings_short_start_end'));
384 $this->tpl->setVariable("TXT_INFO_START_END", $this->lng->txt('crs_timings_start_end_info'));
385 $this->tpl->setVariable("TXT_CHANGED", $this->lng->txt('crs_timings_changed'));
386 $this->tpl->setVariable("TXT_OWN_PRESETTING", $this->lng->txt('crs_timings_planed_start'));
387 $this->tpl->setVariable("TXT_INFO_OWN_PRESETTING", $this->lng->txt('crs_timings_from_until'));
388
389 $items = ilObjectActivation::getTimingsAdministrationItems($this->course_obj->getRefId());
390 foreach ($items as $item) {
391 if (($item['timing_type'] == ilObjectActivation::TIMINGS_PRESETTING) or
393 $this->__renderUserItem($item, 0);
394 }
395 }
396 }
397
402 public function __renderUserItem(array $item, int $level): void
403 {
404 $this->lng->loadLanguageModule('meta');
405
406 $usr_planed = new ilTimingUser($item['ref_id'], $this->initMemberIdFromQuery());
407
408 for ($i = 0; $i < $level; $i++) {
409 $this->tpl->touchBlock('start_indent');
410 $this->tpl->touchBlock('end_indent');
411 }
412 if (strlen($item['description'])) {
413 $this->tpl->setCurrentBlock("item_description");
414 $this->tpl->setVariable("DESC", $item['description']);
415 $this->tpl->parseCurrentBlock();
416 }
417
418 $tlt_data = $this->lom_services->read(
419 ilObject::_lookupObjId($item['ref_id']),
420 0,
421 $item['type'],
422 $this->lom_services->paths()->firstTypicalLearningTime()
423 )->firstData($this->lom_services->paths()->firstTypicalLearningTime());
424
425 if ($tlt = $this->lom_services->dataHelper()->durationToSeconds($tlt_data->value())) {
426 $this->tpl->setCurrentBlock("tlt");
427 $this->tpl->setVariable("TXT_TLT", $this->lng->txt('meta_typical_learning_time'));
428 $this->tpl->setVariable("TLT_VAL", ilDatePresentation::secondsToString($tlt));
429 $this->tpl->parseCurrentBlock();
430 }
431
432 if (!$item['title'] &&
433 $item['type'] == 'sess') {
436 $app_info['start'],
437 $app_info['end'],
438 (bool) $app_info['fullday']
439 );
440 }
441
442 $this->tpl->setCurrentBlock("title_plain");
443 $this->tpl->setVariable("TITLE", $item['title']);
444 $this->tpl->parseCurrentBlock();
445
446 $this->tpl->setCurrentBlock("container_standard_row");
447
448 $this->tpl->setVariable('TYPE_IMG', ilObject::_getIcon($item['obj_id'], 'tiny', $item['type']));
449 $this->tpl->setVariable("TYPE_ALT_IMG", $this->lng->txt('obj_' . $item['type']));
450
451 if ($item['timing_type'] == ilObjectActivation::TIMINGS_PRESETTING) {
452 if ($usr_planed->getStart()->get(IL_CAL_UNIX)) {
453 $this->tpl->setVariable('SUG_START', $usr_planed->getStart()->get(IL_CAL_DATE));
454 }
455 if ($usr_planed->getEnd()->get(IL_CAL_UNIX)) {
456 $this->tpl->setVariable('SUG_END', $usr_planed->getEnd()->get(IL_CAL_DATE));
457 }
458 }
459 $this->tpl->parseCurrentBlock();
460 foreach (ilObjectActivation::getTimingsAdministrationItems($item['ref_id']) as $item_data) {
461 if (($item_data['timing_type'] == ilObjectActivation::TIMINGS_PRESETTING) or
462 ilObjectActivation::hasChangeableTimings($item_data['ref_id'])) {
463 $this->__renderUserItem($item_data, $level + 1);
464 }
465 }
466 }
467
468 protected function updateManagedTimings(): bool
469 {
470 if (!$this->access->checkAccess('write', '', $this->container_obj->getRefId())) {
471 $this->error->raiseError($this->lng->txt('msg_no_perm_write'), $this->error->WARNING);
472 }
473
474 $this->tabs->clearSubTabs();
475
476 $failed = array();
477 $post_item = (array) ($this->http->request()->getParsedBody()['item']) ?? [];
478 foreach ($post_item as $ref_id => $data) {
479 $item_obj = new ilObjectActivation();
480 $item_obj->read($ref_id);
481
482 $data['active'] = $data['active'] ?? 0;
484 $item_obj->toggleChangeable((bool) ($data['change'] ?? false));
485
486 if ($this->course_obj->getTimingMode() == ilCourseConstants::IL_CRS_VIEW_TIMING_ABSOLUTE) {
487 $sug_start_dt = ilCalendarUtil::parseIncomingDate($data['sug_start'] ?? '');
488 $sug_end_dt = ilCalendarUtil::parseIncomingDate($data['sug_end'] ?? '');
489
490 if ($sug_start_dt instanceof ilDate && $sug_end_dt instanceof ilDate) {
491 if (ilDateTime::_after($sug_start_dt, $sug_end_dt)) {
492 $failed[$ref_id] = 'crs_timing_err_start_end';
493 continue;
494 }
495 $item_obj->setSuggestionStart($sug_start_dt->get(IL_CAL_UNIX));
496 $item_obj->setSuggestionEnd($sug_end_dt->get(IL_CAL_UNIX));
497 } else {
498 $failed['ref_id'] = 'crs_timing_err_valid_dates';
499 continue;
500 }
501 } else {
502 if (
503 (int) $data['sug_start_rel'] < 0 || (int) $data['duration_a'] < 0
504 ) {
505 $failed[$ref_id] = 'crs_timing_err_start_dur_rel';
506 continue;
507 }
508 $item_obj->setSuggestionStartRelative($data['sug_start_rel']);
509 $item_obj->setSuggestionEndRelative($data['sug_start_rel'] + $data['duration_a']);
510
511 // add default values for start/end (relative to now)
512 $start = new ilDate(time(), IL_CAL_UNIX);
513 $start->increment(IL_CAL_DAY, $data['sug_start_rel']);
514 $item_obj->setSuggestionStart($start->get(IL_CAL_UNIX));
515
516 $start->increment(IL_CAL_DAY, $data['duration_a']);
517 $item_obj->setSuggestionEnd($start->get(IL_CAL_UNIX));
518 }
519
520 $item_obj->update($ref_id);
521 }
522 if ($failed === []) {
523 // update course => create calendar entries
524 $this->course_obj->update();
525 $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'));
526 $this->manageTimings();
527 return true;
528 } else {
529 $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'));
530 $this->manageTimings($failed);
531 return true;
532 }
533 }
534
535 public function __setSubTabs(): void
536 {
537 if ($this->container_obj->getType() == 'crs') {
538 $this->container_gui->setContentSubTabs();
539 }
540 }
541
542 public function initCourseObject(): bool
543 {
544 if ($this->container_obj instanceof ilObjCourse) {
545 $this->course_obj = $this->container_obj;
546 } else {
547 $course_ref_id = $this->tree->checkForParentType($this->container_obj->getRefId(), 'crs');
548 $course = ilObjectFactory::getInstanceByRefId($course_ref_id, false);
549 if ($course instanceof ilObjCourse) {
550 $this->course_obj = $course;
551 }
552 }
553 return true;
554 }
555} // 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