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 $item_id =
"il-ex-modal-img-" . $ass->getId() .
"-" . $cnt;
625 $image = $ui_renderer->render($ui_factory->image()->responsive($file[
'fullpath'], $output_filename));
629 $modal->setId($item_id);
631 $modal->setBody($image);
632 $modal->setHeading($output_filename);
633 $modal = $modal->getHTML();
635 $img_tpl = new \ilTemplate(
"tpl.image_file.html",
true,
true,
"Modules/Exercise");
636 $img_tpl->setCurrentBlock(
"image_content");
637 $img_tpl->setVariable(
"MODAL", $modal);
638 $img_tpl->setVariable(
"ITEM_ID", $item_id);
639 $img_tpl->setVariable(
"IMAGE", $image);
640 $img_tpl->setvariable(
"IMAGE_LENS", $image_lens);
641 $img_tpl->setvariable(
"ALT_LENS", $lng->txt(
"exc_fullscreen"));
642 $img_tpl->parseCurrentBlock();
650 } elseif ($this->media_type->isAudio($mime) || $this->media_type->isVideo($mime)) {
651 $media_tpl = new \ilTemplate(
"tpl.media_file.html",
true,
true,
"Modules/Exercise");
653 if ($this->media_type->isAudio($mime)) {
654 $p = $ui_factory->player()->audio($file[
'fullpath']);
656 $p = $ui_factory->player()->video($file[
'fullpath']);
658 $media_tpl->setVariable(
"MEDIA", $ui_renderer->render($p));
660 $but = $ui_factory->button()->shy(
661 $lng->txt(
"download"),
662 $this->
getSubmissionLink(
"downloadFile", array(
"file" => urlencode($file[
"name"])))
664 $media_tpl->setVariable(
"DOWNLOAD_BUTTON", $ui_renderer->render($but));
671 $l = $ui_factory->link()->standard(
672 $lng->txt(
"download"),
673 $this->
getSubmissionLink(
"downloadFile", array(
"file" => urlencode($file[
"name"])))
678 $ui_renderer->render($l)
692 if (!$this->submission->canView()) {
696 $this->
ctrl->setParameterByClass(
699 $this->assignment->getId()
702 if ($this->submission->getAssignment()->hasTeam()) {
703 $team_gui = $this->gui->getTeamSubmissionGUI($this->exc, $this->submission);
704 $team_gui->buildSubmissionPropertiesAndActions($this);
707 $type_gui = $this->types_gui->getById($this->ex_ass->getType());
708 $type_gui->setSubmission($this->submission);
709 $type_gui->setExercise($this->exc);
710 $type_gui->buildSubmissionPropertiesAndActions($this);
713 if ($this->submission->hasSubmitted()) {
714 $last_sub = $this->submission->getLastSubmission();
718 self::SEC_SUBMISSION,
719 $this->
lng->txt(
"exc_last_submission"),
725 self::SEC_SUBMISSION,
726 $this->
lng->txt(
"exc_last_submission"),
727 $this->
lng->txt(
"exc_no_submission_yet")
731 if ($this->exc->getShowSubmissions()) {
738 if (!$this->submission->canView()) {
741 $peer_review_gui = $this->gui->peerReview()->getPeerReviewGUI(
745 $peer_review_gui->buildSubmissionPropertiesAndActions($this);
755 if ($submission->hasSubmitted()) {
761 $show_global_feedback = ($state->hasSubmissionEndedForAllUsers() && $ass->getFeedbackFile());
767 $show_global_feedback = ($ass->afterCustomDate() && $ass->getFeedbackFile());
769 $show_global_feedback = ($last_sub && $ass->getFeedbackFile());
775 bool $a_show_global_feedback
778 $f = $this->gui->ui()->factory();
779 $r = $this->gui->ui()->renderer();
782 $feedback_id = $this->submission->getFeedbackId();
787 $feedback_file_manager = $this->domain->assignment()->tutorFeedbackFile($ass->getId());
788 $cnt_files = $feedback_file_manager->count($this->user_id);
791 $lpcomment = $ass->getMemberStatus()->getComment();
792 $mark = $ass->getMemberStatus()->getMark();
793 $status = $ass->getMemberStatus()->getStatus();
795 if ($lpcomment !=
"" ||
797 $status !==
"notgraded" ||
799 $a_show_global_feedback) {
801 if ($lpcomment !==
"") {
803 self::SEC_TUTOR_EVAL,
804 $lng->txt(
"exc_comment"),
810 self::SEC_TUTOR_EVAL,
811 $lng->txt(
"exc_mark"),
816 if ($status !==
"" && $status !==
"notgraded") {
818 self::SEC_TUTOR_EVAL,
820 $lng->txt(
"exc_" . $status)
824 if ($cnt_files > 0) {
825 $files = $feedback_file_manager->getFiles($this->user_id);
826 foreach ($files as $file) {
827 $link =
$f->link()->standard(
828 $lng->txt(
"download"),
829 $this->
getSubmissionLink(
"downloadFeedbackFile", array(
"file" => urlencode($file)))
832 self::SEC_TUTOR_EVAL,
840 if ($a_show_global_feedback) {
841 $link =
$f->link()->standard(
842 $lng->txt(
"download"),
846 self::SEC_SAMPLE_SOLUTION,
847 $ass->getFeedbackFile(),
862 if ($a_deadline == 0) {
863 return $lng->
txt(
"exc_submit_convenience_no_deadline");
866 if ($a_deadline - time() <= 0) {
867 $time_str = $lng->txt(
"exc_time_over_short");
877 array $a_params = null
881 if (is_array($a_params)) {
882 foreach ($a_params as $name => $value) {
887 $ilCtrl->setParameterByClass(
"ilexsubmissiongui",
"ass_id", $this->assignment->getId());
888 $url = $ilCtrl->getLinkTargetByClass([\ilAssignmentPresentationGUI::class,
"ilexsubmissiongui"], $a_cmd);
889 $ilCtrl->setParameterByClass(
"ilexsubmissiongui",
"ass_id",
"");
891 if (is_array($a_params)) {
892 foreach ($a_params as $name => $value) {
893 $ilCtrl->setParameterByClass(
"ilexsubmissiongui", $name,
"");
910 return $icons->renderIcon(
911 $icons->getImagePathCompleted(),
912 $lng->txt(
"exc_" . $status)
916 return $icons->renderIcon(
917 $icons->getImagePathFailed(),
918 $lng->txt(
"exc_" . $status)
922 return $icons->renderIcon(
923 $icons->getImagePathNotAttempted(),
924 $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...
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
const SEC_INSTRUCTIONS_OV
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
bool $instructions_hidden
static getInstance(int $variant=ilLPStatusIcons::ICON_VARIANT_DEFAULT, ?\ILIAS\UI\Renderer $renderer=null, ?\ILIAS\UI\Factory $factory=null)
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
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
static getInstanceByIds(int $a_ass_id, int $a_user_id=0)
getLastSubmission()
TODO -> get rid of getTableUserWhere and move to repository class Get the date of the last submission...
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)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
build(Assignment $ass, int $user_id)
const FEEDBACK_DATE_DEADLINE
setHeadProperty(string $type, string $prop, string $val)
getProperties(string $section)
getAdditionalHeadProperties()
Manages random mandatory assignments of an exercise.
const FEEDBACK_DATE_CUSTOM
getSubmissionLink(string $a_cmd, array $a_params=null)
InternalDomainService $domain
getTimeString(int $a_deadline)
Get time string for deadline.