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