ILIAS  release_8 Revision v8.24
class.ilExAssignmentGUI.php
Go to the documentation of this file.
1<?php
2
22
29{
30 protected \ILIAS\MediaObjects\MediaType\MediaTypeManager $media_type;
31 protected ilLanguage $lng;
32 protected ilObjUser $user;
33 protected ilCtrl $ctrl;
35 protected int $current_ass_id;
38 protected UIServices $ui;
39 protected int $requested_ass_id;
40
41
45 public function __construct(
46 ilObjExercise $a_exc,
48 ) {
50 global $DIC;
51
52 $request = $DIC->exercise()->internal()->gui()->request();
53 $this->requested_ass_id = $request->getAssId();
54
55 $this->lng = $DIC->language();
56 $this->user = $DIC->user();
57 $this->ctrl = $DIC->ctrl();
58 $this->ui = $DIC->ui();
59
60 $this->exc = $a_exc;
61 $this->service = $service;
62 $this->mandatory_manager = $service->domain()->assignment()->mandatoryAssignments($this->exc);
63 $this->media_type = $DIC->mediaObjects()->internal()->domain()->mediaType();
64 }
65
70 public function getOverviewHeader(ilExAssignment $a_ass): string
71 {
74
76
77 $state = ilExcAssMemberState::getInstanceByIds($a_ass->getId(), $ilUser->getId());
78
79 $tpl = new ilTemplate("tpl.assignment_head.html", true, true, "Modules/Exercise");
80
81 // we are completely ignoring the extended deadline here
82
83 // :TODO: meaning of "ended on"
84 if ($state->exceededOfficialDeadline()) {
85 $tpl->setCurrentBlock("prop");
86 $tpl->setVariable("PROP", $lng->txt("exc_ended_on"));
87 $tpl->setVariable("PROP_VAL", $state->getCommonDeadlinePresentation());
88 $tpl->parseCurrentBlock();
89
90 // #14077 // this currently shows the feedback deadline during grace period
91 if ($state->getPeerReviewDeadline()) {
92 $tpl->setCurrentBlock("prop");
93 $tpl->setVariable("PROP", $lng->txt("exc_peer_review_deadline"));
94 $tpl->setVariable("PROP_VAL", $state->getPeerReviewDeadlinePresentation());
95 $tpl->parseCurrentBlock();
96 }
97 } elseif (!$state->hasGenerallyStarted()) {
98 $tpl->setCurrentBlock("prop");
99 if ($state->getRelativeDeadline()) {
100 $tpl->setVariable("PROP", $lng->txt("exc_earliest_start_time"));
101 } else {
102 $tpl->setVariable("PROP", $lng->txt("exc_starting_on"));
103 }
104 $tpl->setVariable("PROP_VAL", $state->getGeneralStartPresentation());
105 $tpl->parseCurrentBlock();
106 } else {
107 if ($state->getCommonDeadline() > 0) {
108 $tpl->setCurrentBlock("prop");
109 $tpl->setVariable("PROP", $lng->txt("exc_time_to_send"));
110 $tpl->setVariable("PROP_VAL", $state->getRemainingTimePresentation());
111 $tpl->parseCurrentBlock();
112
113 $tpl->setCurrentBlock("prop");
114 $tpl->setVariable("PROP", $lng->txt("exc_edit_until"));
115 $tpl->setVariable("PROP_VAL", $state->getCommonDeadlinePresentation());
116 $tpl->parseCurrentBlock();
117 } elseif ($state->getRelativeDeadline()) { // if we only have a relative deadline (not started yet)
118 $tpl->setCurrentBlock("prop");
119 $tpl->setVariable("PROP", $lng->txt("exc_rem_time_after_start"));
120 $tpl->setVariable("PROP_VAL", $state->getRelativeDeadlinePresentation());
121 $tpl->parseCurrentBlock();
122
123 if ($state->getLastSubmissionOfRelativeDeadline()) { // if we only have a relative deadline (not started yet)
124 $tpl->setCurrentBlock("prop");
125 $tpl->setVariable("PROP", $lng->txt("exc_rel_last_submission"));
126 $tpl->setVariable("PROP_VAL", $state->getLastSubmissionOfRelativeDeadlinePresentation());
127 $tpl->parseCurrentBlock();
128 }
129 }
130
131
132 if ($state->getIndividualDeadline() > 0) {
133 $tpl->setCurrentBlock("prop");
134 $tpl->setVariable("PROP", $lng->txt("exc_individual_deadline"));
135 $tpl->setVariable("PROP_VAL", $state->getIndividualDeadlinePresentation());
136 $tpl->parseCurrentBlock();
137 }
138 }
139
140 $mand = "";
141 if ($this->mandatory_manager->isMandatoryForUser($a_ass->getId(), $this->user->getId())) {
142 $mand = " (" . $lng->txt("exc_mandatory") . ")";
143 }
144 $tpl->setVariable("TITLE", $a_ass->getTitle() . $mand);
145
146 // status icon
147 $tpl->setVariable(
148 "ICON_STATUS",
149 $this->getIconForStatus(
150 $a_ass->getMemberStatus()->getStatus(),
152 )
153 );
154
155 return $tpl->get();
156 }
157
165 public function getOverviewBody(ilExAssignment $a_ass): string
166 {
167 global $DIC;
168
169 $ilUser = $DIC->user();
170
171 $this->current_ass_id = $a_ass->getId();
172
173 $tpl = new ilTemplate("tpl.assignment_body.html", true, true, "Modules/Exercise");
174
175 $state = ilExcAssMemberState::getInstanceByIds($a_ass->getId(), $ilUser->getId());
176
177 $info = new ilInfoScreenGUI(null);
178 $info->setTableClass("");
179 if ($state->areInstructionsVisible()) {
180 $this->addInstructions($info, $a_ass);
181 $this->addFiles($info, $a_ass);
182 }
183
184 $this->addSchedule($info, $a_ass);
185
186 if ($state->hasSubmissionStarted()) {
187 $this->addSubmission($info, $a_ass);
188 }
189
190 $tpl->setVariable("CONTENT", $info->getHTML());
191
192 return $tpl->get();
193 }
194
195
196 protected function addInstructions(
197 ilInfoScreenGUI $a_info,
198 ilExAssignment $a_ass
199 ): void {
200 $ilUser = $this->user;
201 $info = new ilExAssignmentInfo($a_ass->getId(), $ilUser->getId());
202 $inst = $info->getInstructionInfo();
203 if (count($inst) > 0) {
204 $a_info->addSection($inst["instruction"]["txt"]);
205 $a_info->addProperty("", $inst["instruction"]["value"]);
206 }
207 }
208
212 protected function addSchedule(
213 ilInfoScreenGUI $a_info,
214 ilExAssignment $a_ass
215 ): void {
216 $lng = $this->lng;
217 $ilUser = $this->user;
218 $ilCtrl = $this->ctrl;
219
220 $info = new ilExAssignmentInfo($a_ass->getId(), $ilUser->getId());
221 $schedule = $info->getScheduleInfo();
222
223 $state = ilExcAssMemberState::getInstanceByIds($a_ass->getId(), $ilUser->getId());
224
225 $a_info->addSection($lng->txt("exc_schedule"));
226 if ($state->getGeneralStart() > 0) {
227 $a_info->addProperty($schedule["start_time"]["txt"], $schedule["start_time"]["value"]);
228 }
229
230
231 if ($state->getCommonDeadline()) { // if we have a common deadline (target timestamp)
232 $a_info->addProperty($schedule["until"]["txt"], $schedule["until"]["value"]);
233 } elseif ($state->getRelativeDeadline()) { // if we only have a relative deadline (not started yet)
234 $but = "";
235 if ($state->hasGenerallyStarted()) {
236 $ilCtrl->setParameterByClass("ilobjexercisegui", "ass_id", $a_ass->getId());
237 $but = $this->ui->factory()->button()->primary($lng->txt("exc_start_assignment"), $ilCtrl->getLinkTargetByClass("ilobjexercisegui", "startAssignment"));
238 $ilCtrl->setParameterByClass("ilobjexercisegui", "ass_id", $this->requested_ass_id);
239 $but = $this->ui->renderer()->render($but);
240 }
241
242 $a_info->addProperty($schedule["time_after_start"]["txt"], $schedule["time_after_start"]["value"] . " " . $but);
243 if ($state->getLastSubmissionOfRelativeDeadline()) { // if we only have a relative deadline (not started yet)
244 $a_info->addProperty(
245 $lng->txt("exc_rel_last_submission"),
246 $state->getLastSubmissionOfRelativeDeadlinePresentation()
247 );
248 }
249 }
250
251 if ($state->getOfficialDeadline() > $state->getCommonDeadline()) {
252 $a_info->addProperty($schedule["individual_deadline"]["txt"], $schedule["individual_deadline"]["value"]);
253 }
254
255 if ($state->hasSubmissionStarted()) {
256 $a_info->addProperty($schedule["time_to_send"]["txt"], $schedule["time_to_send"]["value"]);
257 }
258 }
259
260 protected function addPublicSubmissions(
261 ilInfoScreenGUI $a_info,
262 ilExAssignment $a_ass
263 ): void {
264 $lng = $this->lng;
265 $ilUser = $this->user;
266
267 $state = ilExcAssMemberState::getInstanceByIds($a_ass->getId(), $ilUser->getId());
268
269 // submissions are visible, even if other users may still have a larger individual deadline
270 if ($state->hasSubmissionEnded()) {
271 $button = ilLinkButton::getInstance();
272 $button->setCaption("exc_list_submission");
273 $button->setUrl($this->getSubmissionLink("listPublicSubmissions"));
274
275 $a_info->addProperty($lng->txt("exc_public_submission"), $button->render());
276 } else {
277 $a_info->addProperty(
278 $lng->txt("exc_public_submission"),
279 $lng->txt("exc_msg_public_submission")
280 );
281 }
282 }
283
284 protected function addFiles(
285 ilInfoScreenGUI $a_info,
286 ilExAssignment $a_ass
287 ): void {
288 $lng = $this->lng;
289 $lng->loadLanguageModule("exc");
290 $files = $a_ass->getFiles();
291 if (count($files) > 0) {
292 $a_info->addSection($lng->txt("exc_files"));
293
294 global $DIC;
295
296 //file has -> name,fullpath,size,ctime
297 $cnt = 0;
298 foreach ($files as $file) {
299 $cnt++;
300 // get mime type
301 $mime = ilObjMediaObject::getMimeType($file['fullpath']);
302
303 $ui_factory = $DIC->ui()->factory();
304 $ui_renderer = $DIC->ui()->renderer();
305
306 $output_filename = htmlspecialchars($file['name']);
307
308 if ($this->media_type->isImage($mime)) {
309 $item_id = "il-ex-modal-img-" . $a_ass->getId() . "-" . $cnt;
310
311
312 $image = $ui_renderer->render($ui_factory->image()->responsive($file['fullpath'], $output_filename));
313 $image_lens = ilUtil::getImagePath("enlarge.svg");
314
315 $modal = ilModalGUI::getInstance();
316 $modal->setId($item_id);
317 $modal->setType(ilModalGUI::TYPE_LARGE);
318 $modal->setBody($image);
319 $modal->setHeading($output_filename);
320 $modal = $modal->getHTML();
321
322 $img_tpl = new ilTemplate("tpl.image_file.html", true, true, "Modules/Exercise");
323 $img_tpl->setCurrentBlock("image_content");
324 $img_tpl->setVariable("MODAL", $modal);
325 $img_tpl->setVariable("ITEM_ID", $item_id);
326 $img_tpl->setVariable("IMAGE", $image);
327 $img_tpl->setvariable("IMAGE_LENS", $image_lens);
328 $img_tpl->setvariable("ALT_LENS", $lng->txt("exc_fullscreen"));
329 $img_tpl->parseCurrentBlock();
330
331 $a_info->addProperty($output_filename, $img_tpl->get());
332 } elseif ($this->media_type->isAudio($mime) || $this->media_type->isVideo($mime)) {
333 $media_tpl = new ilTemplate("tpl.media_file.html", true, true, "Modules/Exercise");
334
335 if ($this->media_type->isAudio($mime)) {
336 $p = $ui_factory->player()->audio($file['fullpath']);
337 } else {
338 $p = $ui_factory->player()->video($file['fullpath']);
339 }
340 $media_tpl->setVariable("MEDIA", $ui_renderer->render($p));
341
342 $but = $ui_factory->button()->shy(
343 $lng->txt("download"),
344 $this->getSubmissionLink("downloadFile", array("file" => urlencode($file["name"])))
345 );
346 $media_tpl->setVariable("DOWNLOAD_BUTTON", $ui_renderer->render($but));
347 $a_info->addProperty($output_filename, $media_tpl->get());
348 } else {
349 $a_info->addProperty($output_filename, $lng->txt("download"), $this->getSubmissionLink("downloadFile", array("file" => urlencode($file["name"]))));
350 }
351 }
352 }
353 }
354
359 protected function addSubmission(
360 ilInfoScreenGUI $a_info,
361 ilExAssignment $a_ass
362 ): void {
363 $lng = $this->lng;
364 $ilUser = $this->user;
365
366 $state = ilExcAssMemberState::getInstanceByIds($a_ass->getId(), $ilUser->getId());
367
368 $a_info->addSection($lng->txt("exc_your_submission"));
369
370 $submission = new ilExSubmission($a_ass, $ilUser->getId());
371
372 ilExSubmissionGUI::getOverviewContent($a_info, $submission, $this->exc);
373
374 $last_sub = null;
375 if ($submission->hasSubmitted()) {
376 $last_sub = $submission->getLastSubmission();
377 if ($last_sub) {
378 $last_sub = ilDatePresentation::formatDate(new ilDateTime($last_sub, IL_CAL_DATETIME));
379 $a_info->addProperty($lng->txt("exc_last_submission"), $last_sub);
380 }
381 }
382
383 if ($this->exc->getShowSubmissions()) {
384 $this->addPublicSubmissions($a_info, $a_ass);
385 }
386
387 ilExPeerReviewGUI::getOverviewContent($a_info, $submission);
388
389 // global feedback / sample solution
391 $show_global_feedback = ($state->hasSubmissionEndedForAllUsers() && $a_ass->getFeedbackFile());
392 }
393 //If it is not well configured...(e.g. show solution before deadline)
394 //the user can get the solution before he summit it.
395 //we can check in the elseif $submission->hasSubmitted()
397 $show_global_feedback = ($a_ass->afterCustomDate() && $a_ass->getFeedbackFile());
398 } else {
399 $show_global_feedback = ($last_sub && $a_ass->getFeedbackFile());
400 }
401 $this->addSubmissionFeedback($a_info, $a_ass, $submission->getFeedbackId(), $show_global_feedback);
402 }
403
404 protected function addSubmissionFeedback(
405 ilInfoScreenGUI $a_info,
406 ilExAssignment $a_ass,
407 string $a_feedback_id,
408 bool $a_show_global_feedback
409 ): void {
410 $lng = $this->lng;
411
412 $storage = new ilFSStorageExercise($a_ass->getExerciseId(), $a_ass->getId());
413 $cnt_files = $storage->countFeedbackFiles($a_feedback_id);
414
415 $lpcomment = $a_ass->getMemberStatus()->getComment();
416 $mark = $a_ass->getMemberStatus()->getMark();
417 $status = $a_ass->getMemberStatus()->getStatus();
418
419 if ($lpcomment != "" ||
420 $mark != "" ||
421 $status != "notgraded" ||
422 $cnt_files > 0 ||
423 $a_show_global_feedback) {
424 $a_info->addSection($lng->txt("exc_feedback_from_tutor"));
425 if ($lpcomment != "") {
426 $a_info->addProperty(
427 $lng->txt("exc_comment"),
428 nl2br($lpcomment)
429 );
430 }
431 if ($mark != "") {
432 $a_info->addProperty(
433 $lng->txt("exc_mark"),
434 $mark
435 );
436 }
437
438 if ($status != "" && $status != "notgraded") {
439 $img = $this->getIconForStatus($status);
440 $a_info->addProperty(
441 $lng->txt("status"),
442 $img . " " . $lng->txt("exc_" . $status)
443 );
444 }
445
446 if ($cnt_files > 0) {
447 $a_info->addSection($lng->txt("exc_fb_files") .
448 '<a id="fb' . $a_ass->getId() . '"></a>');
449
450 if ($cnt_files > 0) {
451 $files = $storage->getFeedbackFiles($a_feedback_id);
452 foreach ($files as $file) {
453 $a_info->addProperty(
454 $file,
455 $lng->txt("download"),
456 $this->getSubmissionLink("downloadFeedbackFile", array("file" => urlencode($file)))
457 );
458 }
459 }
460 }
461
462 // #15002 - global feedback
463 if ($a_show_global_feedback) {
464 $a_info->addSection($lng->txt("exc_global_feedback_file"));
465
466 $a_info->addProperty(
467 $a_ass->getFeedbackFile(),
468 $lng->txt("download"),
469 $this->getSubmissionLink("downloadGlobalFeedbackFile")
470 );
471 }
472 }
473 }
474
479 public function getTimeString(int $a_deadline): string
480 {
482
483 if ($a_deadline == 0) {
484 return $lng->txt("exc_submit_convenience_no_deadline");
485 }
486
487 if ($a_deadline - time() <= 0) {
488 $time_str = $lng->txt("exc_time_over_short");
489 } else {
491 }
492
493 return $time_str;
494 }
495
496 protected function getSubmissionLink(
497 string $a_cmd,
498 array $a_params = null
499 ): string {
500 $ilCtrl = $this->ctrl;
501
502 if (is_array($a_params)) {
503 foreach ($a_params as $name => $value) {
504 $ilCtrl->setParameterByClass("ilexsubmissiongui", $name, $value);
505 }
506 }
507
508 $ilCtrl->setParameterByClass("ilexsubmissiongui", "ass_id", $this->current_ass_id);
509 $url = $ilCtrl->getLinkTargetByClass("ilexsubmissiongui", $a_cmd);
510 $ilCtrl->setParameterByClass("ilexsubmissiongui", "ass_id", "");
511
512 if (is_array($a_params)) {
513 foreach ($a_params as $name => $value) {
514 $ilCtrl->setParameterByClass("ilexsubmissiongui", $name, "");
515 }
516 }
517
518 return $url;
519 }
520
524 protected function getIconForStatus(string $status, int $variant = ilLPStatusIcons::ICON_VARIANT_LONG): string
525 {
526 $icons = ilLPStatusIcons::getInstance($variant);
528
529 switch ($status) {
530 case "passed":
531 return $icons->renderIcon(
532 $icons->getImagePathCompleted(),
533 $lng->txt("exc_" . $status)
534 );
535
536 case "failed":
537 return $icons->renderIcon(
538 $icons->getImagePathFailed(),
539 $lng->txt("exc_" . $status)
540 );
541
542 default:
543 return $icons->renderIcon(
544 $icons->getImagePathNotAttempted(),
545 $lng->txt("exc_" . $status)
546 );
547 }
548 }
549}
Provides fluid interface to RBAC services.
Definition: UIServices.php:24
const IL_CAL_UNIX
const IL_CAL_DATETIME
Class ilCtrl provides processing control methods.
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
@classDescription Date and time handling
GUI class for exercise assignments.
getIconForStatus(string $status, int $variant=ilLPStatusIcons::ICON_VARIANT_LONG)
Get the rendered icon for a status (failed, passed or not graded).
addSubmission(ilInfoScreenGUI $a_info, ilExAssignment $a_ass)
getOverviewHeader(ilExAssignment $a_ass)
Get assignment header for overview.
addSubmissionFeedback(ilInfoScreenGUI $a_info, ilExAssignment $a_ass, string $a_feedback_id, bool $a_show_global_feedback)
addSchedule(ilInfoScreenGUI $a_info, ilExAssignment $a_ass)
getSubmissionLink(string $a_cmd, array $a_params=null)
getTimeString(int $a_deadline)
Get time string for deadline.
addFiles(ilInfoScreenGUI $a_info, ilExAssignment $a_ass)
addPublicSubmissions(ilInfoScreenGUI $a_info, ilExAssignment $a_ass)
ILIAS MediaObjects MediaType MediaTypeManager $media_type
getOverviewBody(ilExAssignment $a_ass)
Get assignment body for overview.
MandatoryAssignmentsManager $mandatory_manager
addInstructions(ilInfoScreenGUI $a_info, ilExAssignment $a_ass)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Exercise assignment.
getMemberStatus(?int $a_user_id=null)
static getOverviewContent(ilInfoScreenGUI $a_info, ilExSubmission $a_submission)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstanceByIds(int $a_ass_id, int $a_user_id=0)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilInfoScreenGUI.
addSection(string $a_title)
addProperty(string $a_name, string $a_value, string $a_link="")
add a property to current section
static getInstance(int $variant=ilLPStatusIcons::ICON_VARIANT_DEFAULT, ?\ILIAS\UI\Renderer $renderer=null, ?\ILIAS\UI\Factory $factory=null)
language handling
loadLanguageModule(string $a_module)
Load language module.
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...
static period2String(ilDateTime $a_from, $a_to=null)
Return a string of time period.
static getInstance()
Class ilObjExercise.
static getMimeType(string $a_file, bool $a_external=false)
get mime type for file
User class.
special template class to simplify handling of ITX/PEAR
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
global $DIC
Definition: feed.php:28
$img
Definition: imgupload.php:83
$ilUser
Definition: imgupload.php:34
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
Definition: latex.php:41
if($format !==null) $name
Definition: metadata.php:247
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$url
$lng