19 declare(strict_types=1);
51 protected \ilLanguage
$lng;
54 protected \ilExAssignmentTypes
$types;
58 protected \ilExcAssMemberState
$state;
61 protected \ilObjExercise
$exc;
63 protected \ILIAS\MediaObjects\MediaType\MediaTypeManager
$media_type;
65 protected \ilExAssignmentInfo
$info;
86 $this->media_type = $DIC->mediaObjects()->internal()->domain()->mediaType();
87 $this->domain = $domain_service;
88 $this->gui = $gui_service;
89 $this->
lng = $domain_service->lng();
91 $this->
lng->loadLanguageModule(
"exc");
92 $this->
ctrl = $gui_service->ctrl();
93 $this->types_gui = $gui_service->
assignment()->types();
101 if ($this->user_builded === $user_id && $this->ass_builded === $ass->
getId()) {
104 $this->assignment = $ass;
108 $this->ex_ass = new \ilExAssignment($this->assignment->getId());
109 $this->submission = new \ilExSubmission($this->ex_ass, $user_id);
110 $this->lead_text =
"";
111 $this->head_properties = [];
113 $this->additional_head_properties = [];
114 $this->main_action = [];
119 $this->ass_builded = $ass->
getId();
122 public function getSections(
bool $include_schedule =
true,
bool $overview =
false): array
125 $secs[self::SEC_INSTRUCTIONS] = $this->
lng->txt(
"exc_instruction");
127 $secs[self::SEC_INSTRUCTIONS_OV] =
"";
129 if ($include_schedule) {
130 $secs[self::SEC_SCHEDULE] = $this->
lng->txt(
"exc_schedule");
132 $secs[self::SEC_FILES] = $this->
lng->txt(
"exc_files");
133 $secs[self::SEC_TEAM] = $this->
lng->txt(
"exc_team");
134 $secs[self::SEC_SUBMISSION] = $this->
lng->txt(
"exc_submission");
135 $secs[self::SEC_PEER_FEEDBACK] = $this->
lng->txt(
"exc_peer_review");
136 $secs[self::SEC_TUTOR_EVAL] = $this->
lng->txt(
"exc_feedback_from_tutor");
137 $secs[self::SEC_SAMPLE_SOLUTION] = $this->
lng->txt(
"exc_global_feedback_file");
145 return $secs[$sec] ??
"";
155 return $this->head_properties[
$type] ??
null;
165 $this->lead_text = $text;
170 $this->instructions_hidden = $hidden;
180 $this->head_properties[
$type] = [
188 $this->additional_head_properties[] = [
194 public function addProperty(
string $section,
string $prop,
string $val): void
196 $this->properties[$section][] = [
204 return $this->properties[$section] ?? [];
209 $this->actions[$section][] = $button_or_link;
214 return $this->actions[$section] ?? [];
219 $this->main_action[$section] = $button;
224 return $this->main_action[$section] ??
null;
247 if ($state->exceededOfficialDeadline()) {
250 if ($state->hasEnded()) {
252 $lng->txt(
"exc_ended")
256 $state->getPeerReviewLeadText()
262 $lng->txt(
"exc_ended_on"),
263 $state->getCommonDeadlinePresentation()
267 if ($state->getPeerReviewDeadline()) {
269 $lng->txt(
"exc_peer_review_deadline"),
270 $state->getPeerReviewDeadlinePresentation()
274 } elseif (!$state->hasGenerallyStarted()) {
275 if ($state->getRelativeDeadline()) {
276 $prop = $lng->txt(
"exc_earliest_start_time");
278 $prop = $lng->txt(
"exc_starting_on");
281 $prop .
" " . $state->getGeneralStartPresentation()
286 $state->getGeneralStartPresentation()
290 if ($state->getCommonDeadline() > 0) {
292 $state->getRemainingTimeLeadText()
296 $lng->txt(
"exc_edit_until"),
297 $state->getCommonDeadlinePresentation()
300 } elseif ($state->getRelativeDeadline()) {
303 $lng->txt(
"exc_rem_time_after_start"),
304 $state->getRelativeDeadlinePresentation()
307 $state->getRelativeDeadlineStartLeadText()
310 if ($state->getLastSubmissionOfRelativeDeadline()) {
312 $lng->txt(
"exc_rel_last_submission"),
313 $state->getLastSubmissionOfRelativeDeadlinePresentation()
317 if ($state->needsIndividualDeadline()) {
318 if ($state->hasRequestedIndividualDeadline()) {
320 $this->
lng->txt(
"exc_lead_wait_for_idl")
324 $this->
lng->txt(
"exc_lead_request_idl")
329 $lng->txt(
"exc_deadline"),
330 $lng->txt(
"exc_deadline_not_set_yet")
334 $state->getRemainingTimeLeadText()
338 $lng->txt(
"exc_edit_until"),
339 $state->getIndividualDeadlinePresentation()
345 $this->
lng->txt(
"exc_submit_anytime")
349 $lng->txt(
"exc_edit_until"),
350 $lng->txt(
"exc_no_deadline")
354 if ($state->getIndividualDeadline() > 0 &&
357 $lng->txt(
"exc_individual_deadline"),
358 $state->getIndividualDeadlinePresentation()
363 if ($this->mandatory_manager->isMandatoryForUser($this->assignment->getId(),
$this->user_id)) {
365 self::PROP_REQUIREMENT,
366 $lng->txt(
"exc_requirement"),
367 $lng->txt(
"exc_mandatory")
371 self::PROP_REQUIREMENT,
372 $lng->txt(
"exc_requirement"),
373 $lng->txt(
"exc_optional")
378 if ($this->submission->hasSubmitted()) {
379 $last_sub = $this->submission->getLastSubmission();
383 self::PROP_SUBMISSION,
384 $this->
lng->txt(
"exc_last_submission"),
390 self::PROP_SUBMISSION,
391 $this->
lng->txt(
"exc_last_submission"),
392 $this->
lng->txt(
"exc_no_submission_yet")
397 $ass_type = $this->types->getById($this->assignment->getType());
400 $this->
lng->txt(
"exc_type"),
401 $ass_type->getTitle()
405 if (!$this->state->isFuture()) {
406 $status = $this->ex_ass->getMemberStatus($this->user_id)->getStatus();
407 if ($status !==
"") {
411 $lng->txt(
"exc_" . $status)
417 if (!$this->state->isFuture()) {
418 $mark = $this->ex_ass->getMemberStatus($this->user_id)->getMark();
422 $lng->txt(
"exc_mark"),
442 $this->
ctrl->setParameterByClass(\ilAssignmentPresentationGUI::class,
"ass_id", $this->assignment->getId());
445 $this->
lng->txt(
"overview"),
446 $this->
ctrl->getLinkTargetByClass(\ilAssignmentPresentationGUI::class,
"")
449 if ($this->state->areInstructionsVisible()) {
458 if ($this->state->hasSubmissionStarted()) {
468 $inst = $this->
info->getInstructionInfo();
469 if (count($inst) > 0) {
471 self::SEC_INSTRUCTIONS,
473 $inst[
"instruction"][
"value"]
475 $link = $this->gui->ui()->factory()->link()->standard(
476 $this->
lng->txt(
"exc_show_instructions"),
477 $this->
ctrl->getLinkTargetByClass(\ilAssignmentPresentationGUI::class,
"")
480 self::SEC_INSTRUCTIONS_OV,
500 if ($state->getGeneralStart() > 0) {
503 $schedule[
"start_time"][
"txt"],
504 $schedule[
"start_time"][
"value"]
508 if ($state->getCommonDeadline()) {
511 $schedule[
"until"][
"txt"],
512 $schedule[
"until"][
"value"]
514 } elseif ($state->getRelativeDeadline()) {
516 if ($state->hasGenerallyStarted()) {
517 $ilCtrl->setParameterByClass(
"ilobjexercisegui",
"ass_id", $this->assignment->getId());
518 $but = $this->gui->ui()->factory()->button()->primary($lng->txt(
"exc_start_assignment"), $ilCtrl->getLinkTargetByClass(
"ilobjexercisegui",
"startAssignment"));
519 $ilCtrl->setParameterByClass(
"ilobjexercisegui",
"ass_id",
null);
527 $schedule[
"time_after_start"][
"txt"],
528 $schedule[
"time_after_start"][
"value"]
531 if ($state->getLastSubmissionOfRelativeDeadline()) {
534 $lng->txt(
"exc_rel_last_submission"),
535 $state->getLastSubmissionOfRelativeDeadlinePresentation()
538 } elseif ($state->needsIndividualDeadline()) {
539 if ($state->hasRequestedIndividualDeadline()) {
542 $this->
lng->txt(
"exc_deadline"),
543 $this->
lng->txt(
"exc_idl_tutor_needed")
548 $this->
lng->txt(
"exc_deadline"),
549 $this->
lng->txt(
"exc_idl_request_and_tutor_needed")
551 $ilCtrl->setParameterByClass(
"ilobjexercisegui",
"ass_id", $this->assignment->getId());
552 $but = $this->gui->ui()->factory()->button()->primary($lng->txt(
"exc_request_deadline"), $ilCtrl->getLinkTargetByClass(
"ilobjexercisegui",
"requestDeadline"));
553 $ilCtrl->setParameterByClass(
"ilobjexercisegui",
"ass_id",
null);
561 if ($state->getOfficialDeadline() > $state->getCommonDeadline()) {
564 $schedule[
"individual_deadline"][
"txt"],
565 $schedule[
"individual_deadline"][
"value"]
569 if ($state->hasSubmissionStarted()) {
572 $schedule[
"time_to_send"][
"txt"],
573 $schedule[
"time_to_send"][
"value"]
581 if ($this->state->hasSubmissionEnded()) {
582 $link = $this->gui->ui()->factory()->link()->standard(
583 $this->
lng->txt(
"exc_public_submission"),
587 self::SEC_SUBMISSION,
591 "public_submissions",
592 $this->
lng->txt(
"exc_public_submission"),
597 self::SEC_SUBMISSION,
598 $this->
lng->txt(
"exc_public_submission"),
599 $this->
lng->txt(
"exc_msg_public_submission")
607 $ui_factory = $this->gui->ui()->factory();
608 $ui_renderer = $this->gui->ui()->renderer();
612 if (count($files) > 0) {
614 foreach ($files as $file) {
618 $mime = $file[
"mime"] ??
"";
619 $output_filename = htmlspecialchars($file[
'name'] ??
"");
621 if ($this->media_type->isImage($mime)) {
622 $image = $ui_factory->image()->responsive($file[
'fullpath'], $output_filename);
623 $glyph_lens = $ui_factory->symbol()->glyph()->enlarge();
624 $button_lens = $ui_factory->button()->standard(
625 $lng->txt(
"exc_fullscreen"),
629 $modal_page = $ui_factory->modal()->lightboxImagePage($image, $output_filename);
630 $modal = $ui_factory->modal()->lightbox($modal_page);
632 $image = $image->withAction($modal->getShowSignal());
633 $image_lens = $button_lens->withOnClick($modal->getShowSignal());
635 $img_tpl = new \ilTemplate(
"tpl.image_file.html",
true,
true,
"components/ILIAS/Exercise");
636 $img_tpl->setCurrentBlock(
"image_content");
637 $img_tpl->setVariable(
"MODAL", $ui_renderer->render($modal));
638 $img_tpl->setVariable(
"IMAGE", $ui_renderer->render($image));
639 $img_tpl->setvariable(
"IMAGE_LENS", $ui_renderer->render($image_lens));
640 $img_tpl->parseCurrentBlock();
648 } elseif ($this->media_type->isAudio($mime) || $this->media_type->isVideo($mime)) {
649 $media_tpl = new \ilTemplate(
"tpl.media_file.html",
true,
true,
"components/ILIAS/Exercise");
651 if ($this->media_type->isAudio($mime)) {
652 $p = $ui_factory->player()->audio($file[
'fullpath']);
654 $p = $ui_factory->player()->video($file[
'fullpath']);
656 $media_tpl->setVariable(
"MEDIA", $ui_renderer->render($p));
658 $but = $ui_factory->button()->shy(
659 $lng->txt(
"download"),
660 $this->
getSubmissionLink(
"downloadFile", array(
"file" => urlencode($file[
"name"])))
662 $media_tpl->setVariable(
"DOWNLOAD_BUTTON", $ui_renderer->render($but));
669 $l = $ui_factory->link()->standard(
670 $lng->txt(
"download"),
671 $this->
getSubmissionLink(
"downloadFile", array(
"file" => urlencode($file[
"name"])))
676 $ui_renderer->render($l)
690 if (!$this->submission->canView()) {
694 $this->
ctrl->setParameterByClass(
697 $this->assignment->getId()
700 if ($this->submission->getAssignment()->hasTeam()) {
701 $team_gui = $this->gui->getTeamSubmissionGUI($this->exc, $this->submission);
702 $team_gui->buildSubmissionPropertiesAndActions($this);
705 $type_gui = $this->types_gui->getById($this->ex_ass->getType());
706 $type_gui->setSubmission($this->submission);
707 $type_gui->setExercise($this->exc);
708 $type_gui->buildSubmissionPropertiesAndActions($this);
711 if ($this->submission->hasSubmitted()) {
712 $last_sub = $this->submission->getLastSubmission();
716 self::SEC_SUBMISSION,
717 $this->
lng->txt(
"exc_last_submission"),
723 self::SEC_SUBMISSION,
724 $this->
lng->txt(
"exc_last_submission"),
725 $this->
lng->txt(
"exc_no_submission_yet")
729 if ($this->exc->getShowSubmissions()) {
736 if (!$this->submission->canView()) {
739 $peer_review_gui = $this->gui->peerReview()->getPeerReviewGUI(
743 $peer_review_gui->buildSubmissionPropertiesAndActions($this);
753 if ($submission->hasSubmitted()) {
754 $last_sub = $submission->getLastSubmission();
759 $show_global_feedback = ($state->hasSubmissionEndedForAllUsers() && $ass->getFeedbackFile());
765 $show_global_feedback = ($ass->afterCustomDate() && $ass->getFeedbackFile());
767 $show_global_feedback = ($last_sub && $ass->getFeedbackFile());
773 bool $a_show_global_feedback
776 $f = $this->gui->ui()->factory();
777 $r = $this->gui->ui()->renderer();
780 $feedback_id = $this->submission->getFeedbackId();
783 $feedback_file_manager = $this->domain->assignment()->tutorFeedbackFile($ass->getId());
784 $cnt_files = $feedback_file_manager->count($this->user_id);
787 $lpcomment = $ass->getMemberStatus()->getComment();
788 $mark = $ass->getMemberStatus()->getMark();
789 $status = $ass->getMemberStatus()->getStatus();
791 if ($lpcomment !=
"" ||
793 $status !==
"notgraded" ||
795 $a_show_global_feedback) {
797 if ($lpcomment !==
"") {
799 self::SEC_TUTOR_EVAL,
800 $lng->txt(
"exc_comment"),
806 self::SEC_TUTOR_EVAL,
807 $lng->txt(
"exc_mark"),
812 if ($status !==
"" && $status !==
"notgraded") {
814 self::SEC_TUTOR_EVAL,
816 $lng->txt(
"exc_" . $status)
820 if ($cnt_files > 0) {
821 $files = $feedback_file_manager->getFiles($this->user_id);
822 foreach ($files as $file) {
823 $link =
$f->link()->standard(
824 $lng->txt(
"download"),
825 $this->
getSubmissionLink(
"downloadFeedbackFile", array(
"file" => urlencode($file)))
828 self::SEC_TUTOR_EVAL,
836 if ($a_show_global_feedback) {
837 $link =
$f->link()->standard(
838 $lng->txt(
"download"),
842 self::SEC_SAMPLE_SOLUTION,
843 $ass->getFeedbackFile(),
858 if ($a_deadline == 0) {
859 return $lng->
txt(
"exc_submit_convenience_no_deadline");
862 if ($a_deadline - time() <= 0) {
863 $time_str = $lng->txt(
"exc_time_over_short");
873 ?array $a_params =
null 877 if (is_array($a_params)) {
878 foreach ($a_params as $name => $value) {
883 $ilCtrl->setParameterByClass(
"ilexsubmissiongui",
"ass_id", $this->assignment->getId());
884 $url = $ilCtrl->getLinkTargetByClass([\ilAssignmentPresentationGUI::class,
"ilexsubmissiongui"], $a_cmd);
885 $ilCtrl->setParameterByClass(
"ilexsubmissiongui",
"ass_id",
"");
887 if (is_array($a_params)) {
888 foreach ($a_params as $name => $value) {
889 $ilCtrl->setParameterByClass(
"ilexsubmissiongui", $name,
"");
906 return $icons->renderIcon(
907 $icons->getImagePathCompleted(),
908 $lng->txt(
"exc_" . $status)
912 return $icons->renderIcon(
913 $icons->getImagePathFailed(),
914 $lng->txt(
"exc_" . $status)
918 return $icons->renderIcon(
919 $icons->getImagePathNotAttempted(),
920 $lng->txt(
"exc_" . $status)
getActions(string $section)
setInstructionsHidden(bool $hidden)
getHeadProperty(string $type)
Exercise UI frontend presentation service class.
const SEC_SAMPLE_SOLUTION
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...
getSubmissionLink(string $a_cmd, ?array $a_params=null)
const SEC_INSTRUCTIONS_OV
bool $instructions_hidden
static getInstance(int $variant=ilLPStatusIcons::ICON_VARIANT_DEFAULT, ?\ILIAS\UI\Renderer $renderer=null, ?\ILIAS\UI\Factory $factory=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ILIAS MediaObjects MediaType MediaTypeManager $media_type
setParameterByClass(string $a_class, string $a_parameter, $a_value)
array $additional_head_properties
getIconForStatus(string $status, int $variant=\ilLPStatusIcons::ICON_VARIANT_LONG)
Get the rendered icon for a status (failed, passed or not graded).
getSections(bool $include_schedule=true, bool $overview=false)
getMainAction(string $section)
ilExcAssMemberState $state
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
info()
description: > Example for rendering a info message box.
ilExAssignmentTypesGUI $types_gui
setMainAction(string $section, ButtonPrimary $button)
const DEADLINE_ABSOLUTE_INDIVIDUAL
addAdditionalHeadProperty(string $prop, string $val)
addProperty(string $section, string $prop, string $val)
__construct(\ilObjExercise $exc, MandatoryAssignmentsManager $mandatory_manager, InternalDomainService $domain_service, InternalGUIService $gui_service)
ilExSubmission $submission
withSymbol(Symbol $symbol)
static getInstanceByIds(int $a_ass_id, int $a_user_id=0)
getSectionTitle(string $sec)
ilExAssignmentTypes $types
buildSubmissionFeedback(bool $a_show_global_feedback)
addView(string $id, string $txt, string $url)
MandatoryAssignmentsManager $mandatory_manager
setLeadText(string $text)
addAction(string $section, Component $button_or_link)
build(Assignment $ass, int $user_id)
const FEEDBACK_DATE_DEADLINE
setHeadProperty(string $type, string $prop, string $val)
getProperties(string $section)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
getAdditionalHeadProperties()
Manages random mandatory assignments of an exercise.
const FEEDBACK_DATE_CUSTOM
InternalDomainService $domain
getTimeString(int $a_deadline)
Get time string for deadline.