ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilExerciseManagementGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
16{
20 protected $ctrl;
21
25 protected $tabs_gui;
26
30 protected $lng;
31
35 protected $tpl;
36
40 protected $ui_factory;
41
45 protected $ui_renderer;
46
50 protected $filter;
51
55 protected $toolbar;
56
57 protected $exercise; // [ilObjExercise]
58 protected $assignment; // [ilExAssignment]
59
63 protected $task_factory;
64
68 protected $log;
69
73 protected $user;
74
75 const VIEW_ASSIGNMENT = 1;
77 const VIEW_GRADES = 3;
78
79 const FEEDBACK_ONLY_SUBMISSION = "submission_only";
80 const FEEDBACK_FULL_SUBMISSION = "submission_feedback";
81
82 const GRADE_NOT_GRADED = "notgraded";
83 const GRADE_PASSED = "passed";
84 const GRADE_FAILED = "failed";
85
89 protected $service;
90
98 {
99 global $DIC;
100
101 $this->ui_factory = $DIC->ui()->factory();
102 $this->ui_renderer = $DIC->ui()->renderer();
103 $this->user = $DIC->user();
104 $this->toolbar = $DIC->toolbar();
105 $this->log = ilLoggerFactory::getLogger("exc");
106
107 $this->ctrl = $DIC->ctrl();
108 $this->tabs_gui = $DIC->tabs();
109 $this->lng = $DIC->language();
110 $this->tpl = $DIC["tpl"];
111
112 $this->task_factory = $DIC->backgroundTasks()->taskFactory();
113
114 $request = $DIC->exercise()->internal()->request();
115
116 $this->service = $service;
117
118 $this->exercise = $request->getRequestedExercise();
119 if ($a_ass) {
120 $this->assignment = $a_ass;
121 $this->ass_id = $this->assignment->getId();
122 }
123
124 $this->ctrl->saveParameter($this, array("vw", "member_id"));
125 }
126
127 public function executeCommand()
128 {
131 $ilTabs = $this->tabs_gui;
132
133 $class = $ilCtrl->getNextClass($this);
134 //$cmd = $ilCtrl->getCmd("listPublicSubmissions");
135
136 switch ($class) {
137 case "ilfilesystemgui":
138 $ilTabs->clearTargets();
139 $ilTabs->setBackTarget(
140 $lng->txt("back"),
141 $ilCtrl->getLinkTarget($this, $this->getViewBack())
142 );
143
144 ilUtil::sendInfo($lng->txt("exc_fb_tutor_info"));
145
146 $fstorage = new ilFSStorageExercise($this->exercise->getId(), $this->assignment->getId());
147 $fstorage->create();
148
149 $submission = new ilExSubmission($this->assignment, (int) $_GET["member_id"]);
150 $feedback_id = $submission->getFeedbackId();
151 $noti_rec_ids = $submission->getUserIds();
152
153 $fs_title = array();
154 foreach ($noti_rec_ids as $rec_id) {
155 $fs_title[] = ilUserUtil::getNamePresentation($rec_id, false, false, "", true);
156 }
157 $fs_title = implode(" / ", $fs_title);
158
159 $fs_gui = new ilFileSystemGUI($fstorage->getFeedbackPath($feedback_id));
160 $fs_gui->setTableId("excfbfil" . $this->assignment->getId() . "_" . $feedback_id);
161 $fs_gui->setAllowDirectories(false);
162 $fs_gui->setTitle($lng->txt("exc_fb_files") . " - " .
163 $this->assignment->getTitle() . " - " .
164 $fs_title);
165 $pcommand = $fs_gui->getLastPerformedCommand();
166 if (is_array($pcommand) && $pcommand["cmd"] == "create_file") {
167 foreach ($noti_rec_ids as $user_id) {
168 $member_status = $this->assignment->getMemberStatus($user_id);
169 $member_status->setFeedback(true);
170 $member_status->update();
171 }
172
173 $this->exercise->sendFeedbackFileNotification(
174 $pcommand["name"],
175 $noti_rec_ids,
176 $this->assignment->getId()
177 );
178 }
179 $this->ctrl->forwardCommand($fs_gui);
180 break;
181
182 case 'ilrepositorysearchgui':
183 $rep_search = new ilRepositorySearchGUI();
184 $ref_id = $this->exercise->getRefId();
185 $rep_search->addUserAccessFilterCallable(function ($a_user_ids) use ($ref_id) {
186 return $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
187 'edit_submissions_grades',
188 'edit_submissions_grades',
189 $ref_id,
190 $a_user_ids
191 );
192 });
193 $rep_search->setTitle($this->lng->txt("exc_add_participant"));
194 $rep_search->setCallback($this, 'addMembersObject');
195
196 // Set tabs
197 $this->addSubTabs("assignment");
198 $this->ctrl->setReturn($this, 'members');
199
200 $this->ctrl->forwardCommand($rep_search);
201 break;
202
203 case "ilexsubmissionteamgui":
204 $gui = new ilExSubmissionTeamGUI($this->exercise, $this->initSubmission());
205 $ilCtrl->forwardCommand($gui);
206 break;
207
208 case "ilexsubmissionfilegui":
209 $gui = new ilExSubmissionFileGUI($this->exercise, $this->initSubmission());
210 $ilCtrl->forwardCommand($gui);
211 break;
212
213 case "ilexsubmissiontextgui":
214 $ilCtrl->saveParameter($this, array("part_id"));
215 $gui = new ilExSubmissionTextGUI($this->exercise, $this->initSubmission());
216 $ilCtrl->forwardCommand($gui);
217 break;
218
219 case "ilexpeerreviewgui":
220 $gui = new ilExPeerReviewGUI($this->assignment, $this->initSubmission());
221 $ilCtrl->forwardCommand($gui);
222 break;
223
224 default:
225 $cmd = $ilCtrl->getCmd();
226 switch ($cmd) {
227 case 'downloadSubmissions':
228 $cmd = $ilCtrl->getCmd("downloadSubmissions");
229 break;
230 default:
231 $cmd = $ilCtrl->getCmd("listPublicSubmissions");
232 break;
233 }
234 $this->{$cmd . "Object"}();
235 break;
236 }
237 }
238
239 protected function getViewBack()
240 {
241 switch ($_REQUEST["vw"]) {
243 $back_cmd = "showParticipant";
244 break;
245
247 $back_cmd = "showGradesOverview";
248 break;
249
250 default:
251 // case self::VIEW_ASSIGNMENT:
252 $back_cmd = "members";
253 break;
254 }
255 return $back_cmd;
256 }
257
258 protected function initSubmission()
259 {
260 $back_cmd = $this->getViewBack();
261 $this->ctrl->setReturn($this, $back_cmd);
262
263 $this->tabs_gui->clearTargets();
264 $this->tabs_gui->setBackTarget(
265 $this->lng->txt("back"),
266 $this->ctrl->getLinkTarget($this, $back_cmd)
267 );
268
269 return new ilExSubmission($this->assignment, $_REQUEST["member_id"], null, true);
270 }
271
277 public function addSubTabs($a_activate)
278 {
279 $ilTabs = $this->tabs_gui;
282
283 $ass_id = $_GET["ass_id"];
284 $part_id = $_GET["part_id"];
285
286 $ilCtrl->setParameter($this, "vw", "");
287 $ilCtrl->setParameter($this, "member_id", "");
288 $ilCtrl->setParameter($this, "ass_id", "");
289 $ilCtrl->setParameter($this, "part_id", "");
290
291 $ilTabs->addSubTab(
292 "assignment",
293 $lng->txt("exc_assignment_view"),
294 $ilCtrl->getLinkTarget($this, "members")
295 );
296 $ilTabs->addSubTab(
297 "participant",
298 $lng->txt("exc_participant_view"),
299 $ilCtrl->getLinkTarget($this, "showParticipant")
300 );
301 $ilTabs->addSubTab(
302 "grades",
303 $lng->txt("exc_grades_overview"),
304 $ilCtrl->getLinkTarget($this, "showGradesOverview")
305 );
306 $ilTabs->activateSubTab($a_activate);
307
308 $ilCtrl->setParameter($this, "ass_id", $ass_id);
309 $ilCtrl->setParameter($this, "part_id", $part_id);
310 }
311
312 public function waitingDownloadObject()
313 {
316
317 $ilCtrl->setParameterByClass("ilExSubmissionFileGUI", "member_id", (int) $_GET["member_id"]);
318 $url = $ilCtrl->getLinkTargetByClass(array("ilRepositoryGUI", "ilExerciseHandlerGUI", "ilObjExerciseGUI", "ilExerciseManagementGUI", "ilExSubmissionFileGUI"), "downloadNewReturned");
319 $js_url = $ilCtrl->getLinkTargetByClass(array("ilRepositoryGUI", "ilExerciseHandlerGUI", "ilObjExerciseGUI", "ilExerciseManagementGUI", "ilExSubmissionFileGUI"), "downloadNewReturned", "", "", false);
320 ilUtil::sendInfo($lng->txt("exc_wait_for_files") . "<a href='$url'> " . $lng->txt('exc_download_files') . "</a><script>window.location.href ='" . $js_url . "';</script>");
321 $this->membersObject();
322 }
323
327 public function membersObject()
328 {
330 $ilToolbar = $this->toolbar;
333
334 $this->addSubTabs("assignment");
335
336 // assignment selection
337 $ass = ilExAssignment::getInstancesByExercise($this->exercise->getId());
338
339 if (!$this->assignment) {
340 $this->assignment = current($ass);
341 }
342
343 reset($ass);
344 if (count($ass) > 1) {
345 $options = array();
346 foreach ($ass as $a) {
347 $options[$a->getId()] = $a->getTitle();
348 }
349 $si = new ilSelectInputGUI($this->lng->txt(""), "ass_id");
350 $si->setOptions($options);
351 $si->setValue($this->assignment->getId());
352 $ilToolbar->addStickyItem($si);
353
354 $button = ilSubmitButton::getInstance();
355 $button->setCaption("exc_select_ass");
356 $button->setCommand("selectAssignment");
357 $ilToolbar->addStickyItem($button);
358
359 $ilToolbar->addSeparator();
360 }
361 // #16165 - if only 1 assignment dropdown is not displayed;
362 elseif ($this->assignment) {
363 $ilCtrl->setParameter($this, "ass_id", $this->assignment->getId());
364 }
365
366 // add member
367 // is only shown if 'edit_submissions_grades' is granted by rbac. positions
368 // access is not sufficient.
369 $has_rbac_access = $GLOBALS['DIC']->access()->checkAccess(
370 'edit_submissions_grades',
371 '',
372 $this->exercise->getRefId()
373 );
374 if ($has_rbac_access) {
376 $this,
377 $ilToolbar,
378 array(
379 'auto_complete_name' => $lng->txt('user'),
380 'submit_name' => $lng->txt('add'),
381 'add_search' => true,
382 'add_from_container' => $this->exercise->getRefId()
383 )
384 );
385 }
386
387 // #16168 - no assignments
388 if (count($ass) > 0) {
389 if ($has_rbac_access) {
390 $ilToolbar->addSeparator();
391 }
392
393 // we do not want the ilRepositorySearchGUI form action
394 $ilToolbar->setFormAction($ilCtrl->getFormAction($this));
395
396 $ilCtrl->setParameter($this, "ass_id", $this->assignment->getId());
397
398 if ($this->assignment->getType() == ilExAssignment::TYPE_UPLOAD_TEAM) {
399 if (ilExAssignmentTeam::getAdoptableGroups($this->exercise->getRefId())) {
400 $ilToolbar->addButton(
401 $this->lng->txt("exc_adopt_group_teams"),
402 $this->ctrl->getLinkTarget($this, "adoptTeamsFromGroup")
403 );
404
405 $ilToolbar->addSeparator();
406 }
407 } elseif ($this->exercise->hasTutorFeedbackFile()) {
408 if (!$this->assignment->getAssignmentType()->usesTeams()) {
409 // multi-feedback
410 $ilToolbar->addButton(
411 $this->lng->txt("exc_multi_feedback"),
412 $this->ctrl->getLinkTarget($this, "showMultiFeedback")
413 );
414
415 $ilToolbar->addSeparator();
416 }
417 }
418
419 $submission_repository = new ilExcSubmissionRepository($this->db);
420
421 if ($submission_repository->hasSubmissions($this->assignment->getId())) {
422 $ass_type = $this->assignment->getType();
423 //todo change addFormButton for addButtonInstance
424 if ($ass_type == ilExAssignment::TYPE_TEXT) {
425 $ilToolbar->addFormButton($lng->txt("exc_list_text_assignment"), "listTextAssignment");
426 }
427 $ilToolbar->addFormButton($lng->txt("download_all_returned_files"), "downloadSubmissions");
428 }
429 $this->ctrl->setParameter($this, "vw", self::VIEW_ASSIGNMENT);
430
431 $exc_tab = new ilExerciseMemberTableGUI($this, "members", $this->exercise, $this->assignment->getId());
432 $tpl->setContent(
433 $exc_tab->getHTML() .
434 $this->initIndividualDeadlineModal()
435 );
436 } else {
437 ilUtil::sendInfo($lng->txt("exc_no_assignments_available"));
438 }
439
440 $ilCtrl->setParameter($this, "ass_id", "");
441
442 return;
443 }
444
446 {
447 $participant_id = $_REQUEST['part_id'];
448
449 $download_task = new ilDownloadSubmissionsBackgroundTask(
450 (int) $GLOBALS['DIC']->user()->getId(),
451 (int) $this->exercise->getRefId(),
452 (int) $this->exercise->getId(),
453 (int) $this->ass_id,
454 (int) $participant_id
455 );
456
457 if ($download_task->run()) {
458 ilUtil::sendSuccess($this->lng->txt('exc_down_files_started_bg'), true);
459 }
460
461 if ($this->assignment) {
462 $this->ctrl->redirect($this, "members");
463 } else {
464 $this->ctrl->redirect($this, "showParticipant");
465 }
466 }
467
468 public function membersApplyObject()
469 {
470 $this->saveStatusAllObject(null, false);
471 $exc_tab = new ilExerciseMemberTableGUI($this, "members", $this->exercise, $this->assignment->getId());
472 $exc_tab->resetOffset();
473 $exc_tab->writeFilterToSession();
474
475 $this->membersObject();
476 }
477
478 public function membersResetObject()
479 {
480 $exc_tab = new ilExerciseMemberTableGUI($this, "members", $this->exercise, $this->assignment->getId());
481 $exc_tab->resetOffset();
482 $exc_tab->resetFilter();
483
484 $this->membersObject();
485 }
486
490 public function saveGradesObject()
491 {
494
495 if (is_array($_POST["lcomment"])) {
496 foreach ($_POST["lcomment"] as $k => $v) {
497 $marks_obj = new ilLPMarks($this->exercise->getId(), (int) $k);
498 $marks_obj->setComment(ilUtil::stripSlashes($v));
499 $marks_obj->setMark(ilUtil::stripSlashes($_POST["mark"][$k]));
500 $marks_obj->update();
501 }
502 }
503 ilUtil::sendSuccess($lng->txt("exc_msg_saved_grades"), true);
504 $ilCtrl->redirect($this, "showGradesOverview");
505 }
506
507
508 // TEXT ASSIGNMENT ?!
509
513 public function listTextAssignmentObject()
514 {
515 $this->initFilter();
516
517 $this->setBackToMembers();
518
519 $button_print = $this->ui_factory->button()->standard($this->lng->txt('print'), "#")
520 ->withOnLoadCode(function ($id) {
521 return "$('#{$id}').click(function() { window.print(); return false; });";
522 });
523 $this->toolbar->addSeparator();
524 $this->toolbar->addComponent($button_print);
525
526 $group_panels_tpl = new ilTemplate("tpl.exc_group_report_panels.html", true, true, "Modules/Exercise");
527 $group_panels_tpl->setVariable('TITLE', $this->lng->txt("exc_list_text_assignment") . ": " . $this->assignment->getTitle());
528
529 $report_html = "";
530 $total_reports = 0;
531
532 $members = ilExSubmission::getAssignmentParticipants($this->exercise->getId(), $this->ass_id);
533 $members_filter = new ilExerciseMembersFilter($this->exercise->getRefId(), $members, $this->user->getId());
534 $members = $members_filter->filterParticipantsByAccess();
535
536 foreach (ilExSubmission::getAssignmentFilesByUsers($this->exercise->getId(), $this->assignment->getId(), $members) as $file) {
537 if (trim($file["atext"]) && ilObjUser::_exists($file["user_id"])) {
538 $feedback_data = $this->collectFeedbackDataFromPeer($file);
539 $submission_data = $this->assignment->getExerciseMemberAssignmentData($file["user_id"], $this->filter["status"]);
540
541 if (is_array($submission_data)) {
542 $data = array_merge($feedback_data, $submission_data);
543 $report_html .= $this->getReportPanel($data);
544 $total_reports++;
545 }
546 }
547 }
548 if ($total_reports == 0) {
549 $mtpl = new ilTemplate("tpl.message.html", true, true, "Services/Utilities");
550 $mtpl->setCurrentBlock("info_message");
551 $mtpl->setVariable("TEXT", $this->lng->txt("fiter_no_results"));
552 $mtpl->parseCurrentBlock();
553 $report_html .= $mtpl->get();
554 }
555
556 $group_panels_tpl->setVariable('CONTENT', $report_html);
557 $this->tpl->setContent($group_panels_tpl->get());
558 }
559
566 {
567 $this->setBackToMembers();
568
569 $group_panels_tpl = new ilTemplate("tpl.exc_group_report_panels.html", true, true, "Modules/Exercise");
570 $group_panels_tpl->setVariable('TITLE', $this->lng->txt("exc_compare_selected_submissions"));
571
572 $report_html = "";
573 //participant ids selected via checkboxes
574 $participants = array_keys($this->getMultiActionUserIds());
575
576 foreach ($participants as $participant_id) {
577 $submission = new ilExSubmission($this->assignment, $participant_id);
578
579 //submission data array
580 $file = reset($submission->getFiles());
581
582 if (!$file) {
583 $file = [
584 "user_id" => $participant_id,
585 "ts" => null,
586 "atext" => null
587 ];
588 }
589
590 $feedback_data = $this->collectFeedbackDataFromPeer($file);
591
592 $submission_data = $this->assignment->getExerciseMemberAssignmentData($file["user_id"], $this->filter["status"]);
593
594 if (is_array($submission_data)) {
595 $data = array_merge($feedback_data, $submission_data);
596 $report_html .= $this->getReportPanel($data);
597 $total_reports++;
598 }
599 }
600
601 $group_panels_tpl->setVariable('CONTENT', $report_html);
602 $this->tpl->setContent($group_panels_tpl->get());
603 }
604
605 public function getReportPanel($a_data)
606 {
607 $modal = $this->getEvaluationModal($a_data);
608
609 $this->ctrl->setParameter($this, "member_id", $a_data['uid']);
610 $actions = array(
611 $this->ui_factory->button()->shy($this->lng->txt("grade_evaluate"), "#")->withOnClick($modal->getShowSignal())
612 );
613 if ($this->exercise->hasTutorFeedbackMail()) {
614 $actions[] = $this->ui_factory->button()->shy(
615 $this->lng->txt("exc_tbl_action_feedback_mail"),
616 $this->ctrl->getLinkTarget($this, "redirectFeedbackMail")
617 );
618 }
619 if ($this->exercise->hasTutorFeedbackFile()) {
620 $actions[] = $this->ui_factory->button()->shy(
621 $this->lng->txt("exc_tbl_action_feedback_file"),
622 $this->ctrl->getLinkTargetByClass("ilFileSystemGUI", "listFiles")
623 );
624 }
625
626 $this->ctrl->setParameter($this, "member_id", "");
627
628 $actions_dropdown = $this->ui_factory->dropdown()->standard($actions);
629
630 if ($a_data['status'] == self::GRADE_NOT_GRADED) {
631 $str_status_key = $this->lng->txt('exc_tbl_status');
632 $str_status_value = $this->lng->txt('not_yet');
633 } else {
634 $str_status_key = $this->lng->txt('exc_tbl_status_time');
635 $str_status_value = ilDatePresentation::formatDate(new ilDateTime($a_data["status_time"], IL_CAL_DATETIME));
636 }
637
638 $str_mark_key = $this->lng->txt("exc_tbl_mark");
639 $str_mark_value = $this->lng->txt('not_yet');
640
641 if (($a_data['mark'] != "")) {
642 $str_mark_value = $a_data['mark'];
643 }
644
645 if ($a_data['feedback_time']) {
646 $str_evaluation_key = $this->lng->txt('exc_tbl_feedback_time');
647 $str_evaluation_value = ilDatePresentation::formatDate(new ilDateTime($a_data["feedback_time"], IL_CAL_DATETIME));
648 } else {
649 $str_evaluation_key = $this->lng->txt('exc_settings_feedback');
650 $str_evaluation_value = $this->lng->txt('not_yet');
651 }
652
653 $card_content = array(
654 $this->lng->txt("exc_tbl_submission_date") => ilDatePresentation::formatDate(new ilDateTime($a_data["udate"], IL_CAL_DATETIME)),
655 $str_status_key => $str_status_value,
656 $str_mark_key => $str_mark_value,
657 $str_evaluation_key => $str_evaluation_value,
658 $this->lng->txt('feedback_given') => $a_data['fb_given'],
659 $this->lng->txt('feedback_received') => $a_data['fb_received']
660 );
661 $card_tpl = new ilTemplate("tpl.exc_report_details_card.html", true, true, "Modules/Exercise");
662 foreach ($card_content as $key => $value) {
663 $card_tpl->setCurrentBlock("assingment_card");
664 $card_tpl->setVariable("ROW_KEY", $key);
665 $card_tpl->setVariable("ROW_VALUE", $value);
666 $card_tpl->parseCurrentBlock();
667 }
668
669 $main_panel = $this->ui_factory->panel()->sub($a_data['uname'], $this->ui_factory->legacy($a_data['utext']))
670 ->withCard($this->ui_factory->card()->standard($this->lng->txt('text_assignment'))->withSections(array($this->ui_factory->legacy($card_tpl->get()))))->withActions($actions_dropdown);
671
672 $feedback_tpl = new ilTemplate("tpl.exc_report_feedback.html", true, true, "Modules/Exercise");
673 //if no feedback filter the feedback is displayed. Can be list submissions or compare submissions.
674 if (array_key_exists("peer", $a_data) && ($this->filter["feedback"] == self::FEEDBACK_FULL_SUBMISSION) || $this->filter["feedback"] == "") {
675 $feedback_tpl->setCurrentBlock("feedback");
676 foreach ($a_data["peer"] as $peer_id) {
677 if (ilObject::_lookupType($peer_id) == "usr") {
678 $user = new ilObjUser($peer_id);
679 $peer_name = $user->getFirstname() . " " . $user->getLastname();
680 } else {
681 $peer_name = $this->lng->txt("exc_deleted_user");
682 }
683
684 $feedback_tpl->setCurrentBlock("peer_feedback");
685 $feedback_tpl->setVariable("PEER_NAME", $peer_name);
686
687 $submission = new ilExSubmission($this->assignment, $a_data["uid"]);
688 $values = $submission->getPeerReview()->getPeerReviewValues($peer_id, $a_data["uid"]);
689
690 $review_html = "";
691 foreach ($this->assignment->getPeerReviewCriteriaCatalogueItems() as $crit) {
692 $crit_id = $crit->getId()
693 ? $crit->getId()
694 : $crit->getType();
695 $crit->setPeerReviewContext($this->assignment, $peer_id, $a_data["uid"]);
696
697 $review_html .=
698 '<div class="ilBlockPropertyCaption">' . $crit->getTitle() . '</div>' .
699 '<div style="margin:2px 0;">' . $crit->getHTML($values[$crit_id]) . '</div>';
700 }
701 $feedback_tpl->setVariable("PEER_FEEDBACK", $review_html);
702 $feedback_tpl->parseCurrentBlock();
703 }
704 $feedback_tpl->parseCurrentBlock();
705 }
706 $feedback_tpl->setVariable("GRADE", $this->lng->txt('grade') . ": " . $this->lng->txt('exc_' . $a_data['status']));
707 $feedback_tpl->setVariable("COMMENT", $this->lng->txt('exc_comment') . "<br>" . $a_data['comment']);
708
709 $feedback_panel = $this->ui_factory->panel()->sub("", $this->ui_factory->legacy($feedback_tpl->get()));
710
711 $report = $this->ui_factory->panel()->report("", array($main_panel, $feedback_panel));
712
713 return $this->ui_renderer->render([$modal,$report]);
714 }
715
716 public function getEvaluationModal($a_data)
717 {
718 $modal_tpl = new ilTemplate("tpl.exc_report_evaluation_modal.html", true, true, "Modules/Exercise");
719 $modal_tpl->setVariable("USER_NAME", $a_data['uname']);
720
721 $form = new ilPropertyFormGUI();
722 $form->setFormAction($this->ctrl->getFormAction($this, "saveEvaluationFromModal"));
723 $form->setId(uniqid('form'));
724
725 //Grade
726 $options = array(
727 self::GRADE_NOT_GRADED => $this->lng->txt("exc_notgraded"),
728 self::GRADE_PASSED => $this->lng->txt("exc_passed"),
729 self::GRADE_FAILED => $this->lng->txt("exc_failed")
730 );
731 $si = new ilSelectInputGUI($this->lng->txt("exc_tbl_status"), "grade");
732 $si->setOptions($options);
733 $si->setValue($a_data['status']);
734 $form->addItem($si);
735
736 //Mark
737 $mark_input = new ilTextInputGUI($this->lng->txt("exc_tbl_mark"), "mark");
738 $mark_input->setValue($a_data['mark']);
739 $mark_input->setMaxLength(32);
740 $mark_input->setSize(4);
741 $form->addItem($mark_input);
742
743 $item = new ilHiddenInputGUI('mem_id');
744 $item->setValue($a_data['uid']);
745 $form->addItem($item);
746
747 //TODO: CHECK ilias string utils. ilUtil shortenText with net blank.
748 if ($this->exercise->hasTutorFeedbackText()) {
749 $max_chars = 500;
750
751 $u_text = strip_tags($a_data["utext"]); //otherwise will get open P
752 $text = $u_text;
753 //show more
754 if (strlen($u_text) > $max_chars) {
755 $text = "<input type='checkbox' class='read-more-state' id='post-1' />";
756 $text .= "<div class='read-more-wrap'>";
757 $text .= mb_substr($u_text, 0, $max_chars);
758 $text .= "<span class='read-more-target'>";
759 $text .= mb_substr($u_text, $max_chars);
760 $text .= "</span></div>";
761 $text .= "<label for='post-1' class='read-more-trigger'></label>";
762 }
763 $modal_tpl->setVariable("USER_TEXT", $text);
764
765 $ta = new ilTextAreaInputGUI($this->lng->txt("exc_comment"), 'comment');
766 $ta->setInfo($this->lng->txt("exc_comment_for_learner_info"));
767 $ta->setValue($a_data['comment']);
768 $ta->setRows(10);
769 $form->addItem($ta);
770 }
771
772 $modal_tpl->setVariable("FORM", $form->getHTML());
773
774 $form_id = 'form_' . $form->getId();
775 $submit_btn = $this->ui_factory->button()->primary($this->lng->txt("save"), '#')
776 ->withOnLoadCode(function ($id) use ($form_id) {
777 return "$('#{$id}').click(function() { $('#{$form_id}').submit(); return false; });";
778 });
779
780 return $this->ui_factory->modal()->roundtrip(strtoupper($this->lng->txt("grade_evaluate")), $this->ui_factory->legacy($modal_tpl->get()))->withActionButtons([$submit_btn]);
781 }
782
787 {
788 $comment = trim($_POST['comment']);
789 $user_id = (int) $_POST['mem_id'];
790 $grade = trim($_POST["grade"]);
791 $mark = trim($_POST['mark']);
792
793 if ($this->assignment->getId() && $user_id) {
794 $member_status = $this->assignment->getMemberStatus($user_id);
795 $member_status->setComment(ilUtil::stripSlashes($comment));
796 $member_status->setStatus($grade);
797 $member_status->setMark($mark);
798 if ($comment != "") {
799 $member_status->setFeedback(true);
800 }
801 $member_status->update();
802 }
803 ilUtil::sendSuccess($this->lng->txt("exc_status_saved"), true);
804 $this->ctrl->redirect($this, "listTextAssignment");
805 }
806
811 {
812 if (!strlen(trim($_POST['user_login']))) {
813 ilUtil::sendFailure($this->lng->txt('msg_no_search_string'));
814 $this->membersObject();
815 return false;
816 }
817 $users = explode(',', $_POST['user_login']);
818
819 $user_ids = array();
820 foreach ($users as $user) {
821 $user_id = ilObjUser::_lookupId($user);
822
823 if (!$user_id) {
824 ilUtil::sendFailure($this->lng->txt('user_not_known'));
825 return $this->membersObject();
826 }
827
828 $user_ids[] = $user_id;
829 }
830
831 if (!$this->addMembersObject($user_ids)) {
832 $this->membersObject();
833 return false;
834 }
835 return true;
836 }
837
841 public function addMembersObject($a_user_ids = array())
842 {
843 if (!count($a_user_ids)) {
844 ilUtil::sendFailure($this->lng->txt("no_checkbox"));
845 return false;
846 }
847
848 if (!$this->exercise->members_obj->assignMembers($a_user_ids)) {
849 ilUtil::sendFailure($this->lng->txt("exc_members_already_assigned"));
850 return false;
851 } else {
852 /* #16921
853 // #9946 - create team for new user(s) for each team upload assignment
854 foreach(ilExAssignment::getInstancesByExercise($this->exercise->getId()) as $ass)
855 {
856 if($ass->hasTeam())
857 {
858 foreach($a_user_ids as $user_id)
859 {
860 // #15915
861 ilExAssignmentTeam::getTeamId($ass->getId(), $user_id, true);
862 }
863 }
864 }
865 */
866
867 ilUtil::sendSuccess($this->lng->txt("exc_members_assigned"), true);
868 }
869
870 $this->ctrl->redirect($this, "members");
871 return true;
872 }
873
874
878 public function selectAssignmentObject()
879 {
880 $_GET["ass_id"] = ilUtil::stripSlashes($_POST["ass_id"]);
881 $this->membersObject();
882 }
883
887 public function showParticipantObject()
888 {
890 $ilToolbar = $this->toolbar;
893
894 $this->addSubTabs("participant");
895 $this->ctrl->setParameter($this, "ass_id", "");
896
897 // participant selection
898 $ass = ilExAssignment::getAssignmentDataOfExercise($this->exercise->getId());
899 $members = $this->exercise->members_obj->getMembers();
900
901 $members = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
902 'edit_submissions_grades',
903 'edit_submissions_grades',
904 $this->exercise->getRefId(),
905 $members
906 );
907
908
909 if (count($members) == 0) {
910 ilUtil::sendInfo($lng->txt("exc_no_participants"));
911 return;
912 }
913
914 $mems = array();
915 foreach ($members as $mem_id) {
916 if (ilObject::_lookupType($mem_id) == "usr") {
917 $name = ilObjUser::_lookupName($mem_id);
918 if (trim($name["login"]) != "") { // #20073
919 $mems[$mem_id] = $name;
920 }
921 }
922 }
923
924 $mems = ilUtil::sortArray($mems, "lastname", "asc", false, true);
925
926 if ($_GET["part_id"] == "" && count($mems) > 0) {
927 $_GET["part_id"] = key($mems);
928 }
929
930 $current_participant = $_GET["part_id"];
931
932 reset($mems);
933 if (count($mems) > 1) {
934 $options = array();
935 foreach ($mems as $k => $m) {
936 $options[$k] =
937 $m["lastname"] . ", " . $m["firstname"] . " [" . $m["login"] . "]";
938 }
939 $si = new ilSelectInputGUI($this->lng->txt(""), "part_id");
940 $si->setOptions($options);
941 $si->setValue($current_participant);
942 $ilToolbar->addStickyItem($si);
943
944 $button = ilSubmitButton::getInstance();
945 $button->setCaption("exc_select_part");
946 $button->setCommand("selectParticipant");
947 $ilToolbar->addStickyItem($button);
948 }
949
950 if (count($mems) > 0) {
951 $this->ctrl->setParameter($this, "vw", self::VIEW_PARTICIPANT);
952 $this->ctrl->setParameter($this, "part_id", $current_participant);
953
954 $ilToolbar->setFormAction($ilCtrl->getFormAction($this));
955 $ilToolbar->addFormButton($lng->txt("download_all_returned_files"), "downloadSubmissions");
956
957 $part_tab = new ilExParticipantTableGUI(
958 $this,
959 "showParticipant",
960 $this->exercise,
961 $current_participant
962 );
963 $tpl->setContent($part_tab->getHTML() .
964 $this->initIndividualDeadlineModal());
965 } else {
966 ilUtil::sendInfo($this->lng->txt("exc_no_assignments_available"));
967 }
968 }
969
971 {
972 $exc_tab = new ilExParticipantTableGUI($this, "showParticipant", $this->exercise, $_GET["part_id"]);
973 $exc_tab->resetOffset();
974 $exc_tab->writeFilterToSession();
975
976 $this->showParticipantObject();
977 }
978
980 {
981 $exc_tab = new ilExParticipantTableGUI($this, "showParticipant", $this->exercise, $_GET["part_id"]);
982 $exc_tab->resetOffset();
983 $exc_tab->resetFilter();
984
985 $this->showParticipantObject();
986 }
987
991 public function selectParticipantObject()
992 {
993 $_GET["part_id"] = ilUtil::stripSlashes($_POST["part_id"]);
994 $this->showParticipantObject();
995 }
996
1001 {
1002 $tpl = $this->tpl;
1003 $ilToolbar = $this->toolbar;
1005 $lng = $this->lng;
1006
1007 $this->addSubTabs("grades");
1008
1009 $mem_obj = new ilExerciseMembers($this->exercise);
1010 $mems = $mem_obj->getMembers();
1011
1012 $mems = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
1013 'edit_submissions_grades',
1014 'edit_submissions_grades',
1015 $this->exercise->getRefId(),
1016 $mems
1017 );
1018 if (count($mems) > 0) {
1019 $ilToolbar->addButton(
1020 $lng->txt("exc_export_excel"),
1021 $ilCtrl->getLinkTarget($this, "exportExcel")
1022 );
1023 }
1024
1025 $this->ctrl->setParameter($this, "vw", self::VIEW_GRADES);
1026
1027 $grades_tab = new ilExGradesTableGUI(
1028 $this,
1029 "showGradesOverview",
1030 $this->service,
1031 $mem_obj
1032 );
1033 $tpl->setContent($grades_tab->getHTML());
1034 }
1035
1040 {
1041 $members = array();
1042
1043 if ($_GET["member_id"] != "") {
1044 $submission = new ilExSubmission($this->assignment, $_GET["member_id"]);
1045 $members = $submission->getUserIds();
1046 } elseif ($members = $this->getMultiActionUserIds()) {
1047 $members = array_keys($members);
1048 }
1049
1050 if ($members) {
1051 $logins = array();
1052 foreach ($members as $user_id) {
1053 $member_status = $this->assignment->getMemberStatus($user_id);
1054 $member_status->setFeedback(true);
1055 $member_status->update();
1056
1057 $logins[] = ilObjUser::_lookupLogin($user_id);
1058 }
1059 $logins = implode(",", $logins);
1060
1061 // #16530 - see ilObjCourseGUI::createMailSignature
1062 $sig = chr(13) . chr(10) . chr(13) . chr(10);
1063 $sig .= $this->lng->txt('exc_mail_permanent_link');
1064 $sig .= chr(13) . chr(10) . chr(13) . chr(10);
1065 $sig .= ilLink::_getLink($this->exercise->getRefId());
1066 $sig = rawurlencode(base64_encode($sig));
1067
1069 $this,
1070 $this->getViewBack(),
1071 array(),
1072 array(
1073 'type' => 'new',
1074 'rcp_to' => $logins,
1076 )
1077 ));
1078 }
1079 }
1080
1084 public function downloadAllObject()
1085 {
1086 $members = array();
1087
1088 foreach ($this->exercise->members_obj->getMembers() as $member_id) {
1089 $submission = new ilExSubmission($this->assignment, $member_id);
1090 $submission->updateTutorDownloadTime();
1091
1092 // get member object (ilObjUser)
1093 if (ilObject::_exists($member_id)) {
1094 $storage_id = "";
1095 // adding file metadata
1096 foreach ($submission->getFiles() as $file) {
1097 if ($this->assignment->getAssignmentType()->isSubmissionAssignedToTeam()) {
1098 $storage_id = $file["team_id"];
1099 } else {
1100 $storage_id = $file["user_id"];
1101 }
1102
1103 $members[$storage_id]["files"][$file["returned_id"]] = $file;
1104 }
1105 if ($this->assignment->getAssignmentType()->isSubmissionAssignedToTeam()) {
1106 $name = "Team " . $submission->getTeam()->getId();
1107 } else {
1108 $tmp_obj = ilObjectFactory::getInstanceByObjId($member_id);
1109 $name = $tmp_obj->getFirstname() . " " . $tmp_obj->getLastname();
1110 }
1111 if ($storage_id > 0) {
1112 $members[$storage_id]["name"] = $name;
1113 }
1114 unset($tmp_obj);
1115 }
1116 }
1117
1118 ilExSubmission::downloadAllAssignmentFiles($this->assignment, $members);
1119 }
1120
1121 protected function getMultiActionUserIds($a_keep_teams = false)
1122 {
1123 // multi-user
1124 if ($this->assignment) {
1125 if (!$_POST["member"]) {
1126 ilUtil::sendFailure($this->lng->txt("no_checkbox"), true);
1127 $this->ctrl->redirect($this, "members");
1128 }
1129
1130 foreach (array_keys($_POST["member"]) as $user_id) {
1131 $submission = new ilExSubmission($this->assignment, $user_id);
1132 $tmembers = $submission->getUserIds();
1133 if (!(bool) $a_keep_teams) {
1134 foreach ($tmembers as $tuser_id) {
1135 $members[$tuser_id] = 1;
1136 }
1137 } else {
1138 if ($tmembers) {
1139 $members[] = $tmembers;
1140 } else {
1141 // no team yet
1142 $members[] = $user_id;
1143 }
1144 }
1145 }
1146 }
1147 // multi-ass
1148 else {
1149 if (!$_POST["ass"]) {
1150 ilUtil::sendFailure($this->lng->txt("no_checkbox"), true);
1151 $this->ctrl->redirect($this, "showParticipant");
1152 }
1153
1154 $user_id = $_GET["part_id"];
1155
1156 foreach (array_keys($_POST["ass"]) as $ass_id) {
1157 $submission = new ilExSubmission(new ilExAssignment($ass_id), $user_id);
1158 $tmembers = $submission->getUserIds();
1159 if (!(bool) $a_keep_teams) {
1160 foreach ($tmembers as $tuser_id) {
1161 $members[$ass_id][] = $tuser_id;
1162 }
1163 } else {
1164 if ($tmembers) {
1165 $members[$ass_id][] = $tmembers;
1166 } else {
1167 // no team yet
1168 $members[$ass_id][] = $user_id;
1169 }
1170 }
1171 }
1172 }
1173
1174 return $members;
1175 }
1176
1180 public function sendMembersObject()
1181 {
1182 $members = $this->getMultiActionUserIds();
1183
1184 ilUtil::sendSuccess($this->lng->txt("exc_sent"), true);
1185 if ($this->assignment) {
1186 $this->exercise->sendAssignment($this->assignment, array_keys($members));
1187 $this->ctrl->redirect($this, "members");
1188 } else {
1189 foreach ($members as $ass_id => $users) {
1190 $this->exercise->sendAssignment(new ilExAssignment($ass_id), $users);
1191 }
1192 $this->ctrl->setParameter($this, "part_id", $_GET["part_id"]); // #17629
1193 $this->ctrl->redirect($this, "showParticipant");
1194 }
1195 }
1196
1201 {
1203 $tpl = $this->tpl;
1204 $lng = $this->lng;
1205
1206 $members = $this->getMultiActionUserIds();
1207
1208 $cgui = new ilConfirmationGUI();
1209 $cgui->setFormAction($ilCtrl->getFormAction($this));
1210 $cgui->setHeaderText($lng->txt("exc_msg_sure_to_deassign_participant"));
1211 $cgui->setCancel($lng->txt("cancel"), "members");
1212 $cgui->setConfirm($lng->txt("remove"), "deassignMembers");
1213
1214 foreach ($members as $k => $m) {
1215 $cgui->addItem(
1216 "member[$k]",
1217 $m,
1218 ilUserUtil::getNamePresentation((int) $k, false, false, "", true)
1219 );
1220 }
1221
1222 $tpl->setContent($cgui->getHTML());
1223 }
1224
1228 public function deassignMembersObject()
1229 {
1231 $lng = $this->lng;
1232
1233 $members = $this->getMultiActionUserIds();
1234
1235 foreach (array_keys($members) as $usr_id) {
1236 $this->exercise->members_obj->deassignMember((int) $usr_id);
1237 $this->removeUserSubmissionFilesFromWebDir((int) $usr_id);
1238 }
1239 ilUtil::sendSuccess($lng->txt("exc_msg_participants_removed"), true);
1240 $ilCtrl->redirect($this, "members");
1241 }
1242
1243 public function removeUserSubmissionFilesFromWebDir(int $user_id) : void
1244 {
1245 $storage = new ilFSWebStorageExercise($this->exercise->getId(), $this->ass_id);
1246 $storage->deleteUserSubmissionDirectory($user_id);
1247 }
1248
1249 public function saveCommentsObject()
1250 {
1251 if (!isset($_POST['comments_value'])) {
1252 return;
1253 }
1254
1255 $this->exercise->members_obj->setNoticeForMember(
1256 $_GET["member_id"],
1257 ilUtil::stripSlashes($_POST["comments_value"])
1258 );
1259 ilUtil::sendSuccess($this->lng->txt("exc_members_comments_saved"));
1260 $this->membersObject();
1261 }
1262
1266 public function saveStatusParticipantObject(array $a_selected = null)
1267 {
1269
1270 $member_id = (int) $_GET["part_id"];
1271 $data = array();
1272 foreach (array_keys($_POST["id"]) as $ass_id) {
1273 if (is_array($a_selected) &&
1274 !in_array($ass_id, $a_selected)) {
1275 continue;
1276 }
1277
1278 $data[$ass_id][$member_id] = array(
1279 "status" => ilUtil::stripSlashes($_POST["status"][$ass_id])
1280 );
1281
1282 if (array_key_exists("mark", $_POST)) {
1283 $data[$ass_id][$member_id]["mark"] = ilUtil::stripSlashes($_POST["mark"][$ass_id]);
1284 }
1285 if (array_key_exists("notice", $_POST)) {
1286 $data[$ass_id][$member_id]["notice"] = ilUtil::stripSlashes($_POST["notice"][$ass_id]);
1287 }
1288 }
1289
1290 $ilCtrl->setParameter($this, "part_id", $member_id); // #17629
1291 $this->saveStatus($data);
1292 }
1293
1294
1295 public function saveStatusAllObject(array $a_selected = null, $a_redirect = true)
1296 {
1297 $user_ids = (array) array_keys((array) $_POST['id']);
1298 $filtered_user_ids = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
1299 'edit_submissions_grades',
1300 'edit_submissions_grades',
1301 $this->exercise->getRefId(),
1302 $user_ids
1303 );
1304
1305 $data = array();
1306 foreach ($filtered_user_ids as $user_id) {
1307 if (is_array($a_selected) &&
1308 !in_array($user_id, $a_selected)) {
1309 continue;
1310 }
1311
1312 $data[-1][$user_id] = array(
1313 "status" => ilUtil::stripSlashes($_POST["status"][$user_id])
1314 );
1315
1316 if (array_key_exists("mark", $_POST)) {
1317 $data[-1][$user_id]["mark"] = ilUtil::stripSlashes($_POST["mark"][$user_id]);
1318 }
1319 if (array_key_exists("notice", $_POST)) {
1320 $data[-1][$user_id]["notice"] = ilUtil::stripSlashes($_POST["notice"][$user_id]);
1321 }
1322 }
1323 $this->saveStatus($data, $a_redirect);
1324 }
1325
1327 {
1328 $members = $this->getMultiActionUserIds();
1329
1330 if ($this->assignment) {
1331 $this->saveStatusAllObject(array_keys($members));
1332 } else {
1333 $this->saveStatusParticipantObject(array_keys($members));
1334 }
1335 }
1336
1340 protected function saveStatus(array $a_data, $a_redirect = true)
1341 {
1343
1344 $saved_for = array();
1345 foreach ($a_data as $ass_id => $users) {
1346 $ass = ($ass_id < 0)
1347 ? $this->assignment
1348 : new ilExAssignment($ass_id);
1349 foreach ($users as $user_id => $values) {
1350 // this will add team members if available
1351 $submission = new ilExSubmission($ass, $user_id);
1352 foreach ($submission->getUserIds() as $sub_user_id) {
1353 $uname = ilObjUser::_lookupName($sub_user_id);
1354 $saved_for[$sub_user_id] = $uname["lastname"] . ", " . $uname["firstname"];
1355
1356 $member_status = $ass->getMemberStatus($sub_user_id);
1357
1358 // see bug #22566
1359 $status = $values["status"];
1360 if ($status == "") {
1361 $status = self::GRADE_NOT_GRADED;
1362 }
1363 $member_status->setStatus($status);
1364 if (array_key_exists("mark", $values)) {
1365 $member_status->setMark($values["mark"]);
1366 }
1367 if (array_key_exists("notice", $values)) {
1368 $member_status->setNotice($values["notice"]);
1369 }
1370 $member_status->update();
1371 }
1372 }
1373 }
1374
1375 if (count($saved_for) > 0) {
1376 $save_for_str = "(" . implode(" - ", $saved_for) . ")";
1377 }
1378
1379 if ($a_redirect) {
1380 ilUtil::sendSuccess($this->lng->txt("exc_status_saved") . " " . $save_for_str, true);
1381 $ilCtrl->redirect($this, $this->getViewBack());
1382 }
1383 }
1384
1389 {
1390 $res = array("result" => false);
1391
1392 if ($this->ctrl->isAsynch()) {
1393 $ass_id = (int) $_POST["ass_id"];
1394 $user_id = (int) $_POST["mem_id"];
1395 $comment = trim($_POST["comm"]);
1396
1397 if ($ass_id && $user_id) {
1398 $submission = new ilExSubmission($this->assignment, $user_id);
1399 $user_ids = $submission->getUserIds();
1400
1401 $all_members = new ilExerciseMembers($this->exercise);
1402 $all_members = $all_members->getMembers();
1403
1404 $reci_ids = array();
1405 foreach ($user_ids as $user_id) {
1406 if (in_array($user_id, $all_members)) {
1407 $member_status = $this->assignment->getMemberStatus($user_id);
1408 $member_status->setComment(ilUtil::stripSlashes($comment));
1409 $member_status->setFeedback(true);
1410 $member_status->update();
1411
1412 if (trim($comment)) {
1413 $reci_ids[] = $user_id;
1414 }
1415 }
1416 }
1417
1418 if (sizeof($reci_ids)) {
1419 // send notification
1420 $this->exercise->sendFeedbackFileNotification(
1421 null,
1422 $reci_ids,
1423 $ass_id,
1424 true
1425 );
1426 }
1427
1428 $res = array("result" => true, "snippet" => nl2br($comment));
1429 }
1430 }
1431
1432 echo(json_encode($res));
1433 exit();
1434 }
1435
1439 public function exportExcelObject()
1440 {
1441 $this->exercise->exportGradesExcel();
1442 exit;
1443 }
1444
1445
1446 //
1447 // TEAM
1448 //
1449
1450 public function createTeamsObject()
1451 {
1453
1454 $members = $this->getMultiActionUserIds(true);
1455
1456 $new_members = array();
1457
1458 foreach ($members as $group) {
1459 if (is_array($group)) {
1460 $new_members = array_merge($new_members, $group);
1461
1462 $first_user = $group;
1463 $first_user = array_shift($first_user);
1464 $team = ilExAssignmentTeam::getInstanceByUserId($this->assignment->getId(), $first_user);
1465 foreach ($group as $user_id) {
1466 $team->removeTeamMember($user_id);
1467 }
1468 } else {
1469 $new_members[] = $group;
1470 }
1471 }
1472
1473 if (sizeof($new_members)) {
1474 // see ilExSubmissionTeamGUI::addTeamMemberActionObject()
1475
1476 $first_user = array_shift($new_members);
1477 $team = ilExAssignmentTeam::getInstanceByUserId($this->assignment->getId(), $first_user, true);
1478 if (sizeof($new_members)) {
1479 foreach ($new_members as $user_id) {
1480 $team->addTeamMember($user_id);
1481 }
1482 }
1483
1484 // re-evaluate complete team, as some members might have had submitted
1485 $submission = new ilExSubmission($this->assignment, $first_user);
1486 $this->exercise->processExerciseStatus(
1487 $this->assignment,
1488 $team->getMembers(),
1489 $submission->hasSubmitted(),
1490 $submission->validatePeerReviews()
1491 );
1492 }
1493
1494 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1495 $ilCtrl->redirect($this, "members");
1496 }
1497
1498 public function dissolveTeamsObject()
1499 {
1501
1502 $members = $this->getMultiActionUserIds(true);
1503
1504 foreach ($members as $group) {
1505 // if single member - nothing to do
1506 if (is_array($group)) {
1507 // see ilExSubmissionTeamGUI::removeTeamMemberObject()
1508
1509 $first_user = $group;
1510 $first_user = array_shift($first_user);
1511 $team = ilExAssignmentTeam::getInstanceByUserId($this->assignment->getId(), $first_user);
1512 foreach ($group as $user_id) {
1513 $team->removeTeamMember($user_id);
1514 }
1515
1516 // reset ex team members, as any submission is not valid without team
1517 $this->exercise->processExerciseStatus(
1518 $this->assignment,
1519 $group,
1520 false
1521 );
1522 }
1523 }
1524
1525 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1526 $ilCtrl->redirect($this, "members");
1527 }
1528
1529 public function adoptTeamsFromGroupObject(ilPropertyFormGUI $a_form = null)
1530 {
1532 $ilTabs = $this->tabs_gui;
1533 $lng = $this->lng;
1534 $tpl = $this->tpl;
1535
1536 $ilTabs->clearTargets();
1537 $ilTabs->setBackTarget(
1538 $lng->txt("back"),
1539 $ilCtrl->getLinkTarget($this, $this->getViewBack())
1540 );
1541
1542 if (!$a_form) {
1543 $a_form = $this->initGroupForm();
1544 }
1545 $tpl->setContent($a_form->getHTML());
1546 }
1547
1548 protected function initGroupForm()
1549 {
1550 $lng = $this->lng;
1551
1552 $form = new ilPropertyFormGUI();
1553 $form->setTitle($lng->txt("exc_adopt_group_teams") . " - " . $this->assignment->getTitle());
1554 $form->setFormAction($this->ctrl->getFormAction($this, "createTeamsFromGroups"));
1555
1556 $all_members = array();
1557 foreach (ilExAssignmentTeam::getGroupMembersMap($this->exercise->getRefId()) as $grp_id => $group) {
1558 if (sizeof($group["members"])) {
1559 $grp_team = new ilCheckboxGroupInputGUI($lng->txt("obj_grp") . " \"" . $group["title"] . "\"", "grpt_" . $grp_id);
1560 $grp_value = $options = array();
1561 foreach ($group["members"] as $user_id) {
1562 $user_name = ilUserUtil::getNamePresentation($user_id, false, false, "", true);
1563 $options[$user_id] = $user_name;
1564 if (!in_array($user_id, $all_members)) {
1565 $grp_value[] = $user_id;
1566 $all_members[] = $user_id;
1567 }
1568 }
1569 asort($options);
1570 foreach ($options as $user_id => $user_name) {
1571 $grp_team->addOption(new ilCheckboxOption($user_name, $user_id));
1572 }
1573 $grp_team->setValue($grp_value);
1574 $form->addItem($grp_team);
1575 } else {
1576 $grp_team = new ilNonEditableValueGUI($group["title"]);
1577 $grp_team->setValue($lng->txt("exc_adopt_group_teams_no_members"));
1578 $form->addItem($grp_team);
1579 }
1580 }
1581
1582 if (sizeof($all_members)) {
1583 $form->addCommandButton("createTeamsFromGroups", $lng->txt("save"));
1584 }
1585 $form->addCommandButton("members", $lng->txt("cancel"));
1586
1587 return $form;
1588 }
1589
1591 {
1592 $lng = $this->lng;
1593
1594 $form = $this->initGroupForm();
1595 if ($form->checkInput()) {
1596 $map = ilExAssignmentTeam::getGroupMembersMap($this->exercise->getRefId());
1597 $all_members = $teams = array();
1598 $valid = true;
1599 foreach (array_keys($map) as $grp_id) {
1600 $postvar = "grpt_" . $grp_id;
1601 $members = $_POST[$postvar];
1602 if (is_array($members)) {
1603 $teams[] = $members;
1604 $invalid_team_members = array();
1605
1606 foreach ($members as $user_id) {
1607 if (!array_key_exists($user_id, $all_members)) {
1608 $all_members[$user_id] = $grp_id;
1609 } else {
1610 // user is selected in multiple groups
1611 $invalid_team_members[] = $user_id;
1612 }
1613 }
1614
1615 if (sizeof($invalid_team_members)) {
1616 $valid = false;
1617
1618 $alert = array();
1619 foreach ($invalid_team_members as $user_id) {
1620 $user_name = ilUserUtil::getNamePresentation($user_id, false, false, "", true);
1621 $grp_title = $map[$all_members[$user_id]]["title"];
1622 $alert[] = sprintf($lng->txt("exc_adopt_group_teams_conflict"), $user_name, $grp_title);
1623 }
1624 $input = $form->getItemByPostVar($postvar);
1625 $input->setAlert(implode("<br/>", $alert));
1626 }
1627 }
1628 }
1629 if ($valid) {
1630 if (sizeof($teams)) {
1631 $existing_users = array_keys(ilExAssignmentTeam::getAssignmentTeamMap($this->assignment->getId()));
1632
1633 // create teams from group selections
1634 $sum = array("added" => 0, "blocked" => 0);
1635 foreach ($teams as $members) {
1636 foreach ($members as $user_id) {
1637 if (!$this->exercise->members_obj->isAssigned($user_id)) {
1638 $this->exercise->members_obj->assignMember($user_id);
1639 }
1640
1641 if (!in_array($user_id, $existing_users)) {
1642 $sum["added"]++;
1643 } else {
1644 $sum["blocked"]++;
1645 }
1646 }
1647
1648 $first = array_shift($members);
1649 $team = ilExAssignmentTeam::getInstanceByUserId($this->assignment->getId(), $first, true);
1650
1651 // getTeamId() does NOT send notification
1652 // $team->sendNotification($this->exercise->getRefId(), $first, "add");
1653
1654 if (sizeof($members)) {
1655 foreach ($members as $user_id) {
1656 $team->addTeamMember($user_id);
1657 }
1658 }
1659 }
1660
1661 $mess = array();
1662 if ($sum["added"]) {
1663 $mess[] = sprintf($lng->txt("exc_adopt_group_teams_added"), $sum["added"]);
1664 }
1665 if ($sum["blocked"]) {
1666 $mess[] = sprintf($lng->txt("exc_adopt_group_teams_blocked"), $sum["blocked"]);
1667 }
1668 if ($sum["added"]) {
1669 ilUtil::sendSuccess(implode(" ", $mess), true);
1670 } else {
1671 ilUtil::sendFailure(implode(" ", $mess), true);
1672 }
1673 }
1674 $this->ctrl->redirect($this, "members");
1675 } else {
1676 ilUtil::sendFailure($lng->txt("form_input_not_valid"));
1677 }
1678 }
1679
1680 $form->setValuesByPost();
1681 $this->adoptTeamsFromGroupObject($form);
1682 }
1683
1684
1688
1689 public function initMultiFeedbackForm($a_ass_id)
1690 {
1691 $lng = $this->lng;
1692
1693 $form = new ilPropertyFormGUI();
1694 $form->addCommandButton("uploadMultiFeedback", $lng->txt("upload"));
1695 $form->addCommandButton("members", $lng->txt("cancel"));
1696
1697 // multi feedback file
1698 $fi = new ilFileInputGUI($lng->txt("exc_multi_feedback_file"), "mfzip");
1699 $fi->setSuffixes(array("zip"));
1700 $fi->setRequired(true);
1701 $form->addItem($fi);
1702
1703 $form->setTitle(ilExAssignment::lookupTitle($a_ass_id));
1704 $form->setFormAction($this->ctrl->getFormAction($this, "uploadMultiFeedback"));
1705
1706 return $form;
1707 }
1708
1715 public function showMultiFeedbackObject(ilPropertyFormGUI $a_form = null)
1716 {
1717 $ilToolbar = $this->toolbar;
1718 $lng = $this->lng;
1719 $tpl = $this->tpl;
1720
1721 ilUtil::sendInfo($lng->txt("exc_multi_feedb_info"));
1722
1723 $this->addSubTabs("assignment");
1724
1725 // #13719
1726 $button = ilLinkButton::getInstance();
1727 $button->setCaption("exc_download_zip_structure");
1728 $button->setUrl($this->ctrl->getLinkTarget($this, "downloadMultiFeedbackZip"));
1729 $button->setOmitPreventDoubleSubmission(true);
1730 $ilToolbar->addButtonInstance($button);
1731
1732 if (!$a_form) {
1733 $a_form = $this->initMultiFeedbackForm($this->assignment->getId());
1734 }
1735
1736 $tpl->setContent($a_form->getHTML());
1737 }
1738
1743 {
1744 $this->assignment->sendMultiFeedbackStructureFile($this->exercise);
1745 }
1746
1751 {
1752 // #11983
1753 $form = $this->initMultiFeedbackForm($this->assignment->getId());
1754 if ($form->checkInput()) {
1755 try {
1756 $this->assignment->uploadMultiFeedbackFile(ilUtil::stripSlashesArray($_FILES["mfzip"]));
1757 $this->ctrl->redirect($this, "showMultiFeedbackConfirmationTable");
1758 } catch (ilExerciseException $e) {
1759 ilUtil::sendFailure($e->getMessage(), true);
1760 $this->ctrl->redirect($this, "showMultiFeedback");
1761 }
1762 }
1763
1764 $form->setValuesByPost();
1765 $this->showMultiFeedbackObject($form);
1766 }
1767
1775 {
1776 $tpl = $this->tpl;
1777
1778 $this->addSubTabs("assignment");
1779
1780 $tab = new ilFeedbackConfirmationTable2GUI($this, "showMultiFeedbackConfirmationTable", $this->assignment);
1781 $tpl->setContent($tab->getHTML());
1782 }
1783
1788 {
1789 $this->assignment->clearMultiFeedbackDirectory();
1790 $this->ctrl->redirect($this, "members");
1791 }
1792
1796 public function saveMultiFeedbackObject()
1797 {
1798 $this->assignment->saveMultiFeedbackFiles($_POST["file"], $this->exercise);
1799
1800 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1801 $this->ctrl->redirect($this, "members");
1802 }
1803
1804
1805 //
1806 // individual deadlines
1807 //
1808
1809 protected function initIndividualDeadlineModal()
1810 {
1811 $lng = $this->lng;
1812 $tpl = $this->tpl;
1813
1814 // prepare modal+
1815 $modal = ilModalGUI::getInstance();
1816 $modal->setHeading($lng->txt("exc_individual_deadline"));
1817 $modal->setId("ilExcIDl");
1818 $modal->setBody('<div id="ilExcIDlBody"></div>');
1819 $modal = $modal->getHTML();
1820
1821 $ajax_url = $this->ctrl->getLinkTarget($this, "handleIndividualDeadlineCalls", "", true, false);
1822
1823 $tpl->addJavaScript("./Modules/Exercise/js/ilExcIDl.js", true, 3);
1824 $tpl->addOnloadCode('il.ExcIDl.init("' . $ajax_url . '");');
1825
1827
1828 return $modal;
1829 }
1830
1831 protected function parseIndividualDeadlineData(array $a_data)
1832 {
1833 if ($a_data) {
1834 $map = array();
1835 $ass_tmp = array();
1836 foreach ($a_data as $item) {
1837 $item = explode("_", $item);
1838 $ass_id = $item[0];
1839 $user_id = $item[1];
1840
1841 if (!array_key_exists($ass_id, $ass_tmp)) {
1842 if ($this->assignment &&
1843 $ass_id == $this->assignment->getId()) {
1844 $ass_tmp[$ass_id] = $this->assignment;
1845 } else {
1846 $ass_tmp[$ass_id] = new ilExAssignment($ass_id);
1847 }
1848 }
1849
1850 $map[$ass_id][] = $user_id;
1851 }
1852
1853 return array($map, $ass_tmp);
1854 }
1855 }
1856
1858 {
1859 $tpl = $this->tpl;
1860
1861 $this->ctrl->saveParameter($this, "part_id");
1862
1863 // we are done
1864 if ((bool) $_GET["dn"]) {
1865 ilUtil::sendSuccess($this->lng->txt("settings_saved"), true);
1866 $this->ctrl->redirect($this, $this->assignment
1867 ? "members"
1868 : "showParticipant");
1869 }
1870
1871 // initial form call
1872 if ($_GET["idlid"]) {
1873 $tmp = $this->parseIndividualDeadlineData(explode(",", $_GET["idlid"]));
1874 if (is_array($tmp)) {
1875 $form = $this->initIndividualDeadlineForm($tmp[1], $tmp[0]);
1876 echo $form->getHTML() .
1877 $tpl->getOnLoadCodeForAsynch();
1878 }
1879 }
1880 // form "submit"
1881 else {
1882 $tmp = array();
1883 foreach (array_keys($_POST) as $id) {
1884 if (substr($id, 0, 3) == "dl_") {
1885 $tmp[] = substr($id, 3);
1886 }
1887 }
1888 $tmp = $this->parseIndividualDeadlineData($tmp);
1889 $ass_map = $tmp[1];
1890 $users = $tmp[0];
1891 unset($tmp);
1892
1893 $form = $this->initIndividualDeadlineForm($ass_map, $users);
1894 $res = array();
1895 if ($valid = $form->checkInput()) {
1896 foreach ($users as $ass_id => $users) {
1897 $ass = $ass_map[$ass_id];
1898
1899 // :TODO: should individual deadlines BEFORE extended be possible?
1900 $dl = new ilDateTime($ass->getDeadline(), IL_CAL_UNIX);
1901
1902 foreach ($users as $user_id) {
1903 $date_field = $form->getItemByPostVar("dl_" . $ass_id . "_" . $user_id);
1904 if (ilDate::_before($date_field->getDate(), $dl)) {
1905 $date_field->setAlert(sprintf($this->lng->txt("exc_individual_deadline_before_global"), ilDatePresentation::formatDate($dl)));
1906 $valid = false;
1907 } else {
1908 $res[$ass_id][$user_id] = $date_field->getDate();
1909 }
1910 }
1911 }
1912 }
1913
1914 if (!$valid) {
1915 $form->setValuesByPost();
1916 echo $form->getHTML() .
1917 $tpl->getOnLoadCodeForAsynch();
1918 } else {
1919 foreach ($res as $ass_id => $users) {
1920 $ass = $ass_map[$ass_id];
1921
1922 foreach ($users as $id => $date) {
1923 $ass->setIndividualDeadline($id, $date);
1924 }
1925
1926 $ass->recalculateLateSubmissions();
1927 }
1928
1929 echo "ok";
1930 }
1931 }
1932
1933 exit();
1934 }
1935
1936 protected function initIndividualDeadlineForm(array $a_ass_map, array $ids)
1937 {
1938 $form = new ilPropertyFormGUI();
1939 $form->setFormAction($this->ctrl->getFormAction($this));
1940 $form->setName("ilExcIDlForm");
1941
1942 foreach ($ids as $ass_id => $users) {
1943 $ass = $a_ass_map[$ass_id];
1944
1946 $section->setTitle($ass->getTitle());
1947 $form->addItem($section);
1948
1949 $teams = ilExAssignmentTeam::getInstancesFromMap($ass->getId());
1950
1951 $values = $ass->getIndividualDeadlines();
1952
1953 foreach ($users as $id) {
1954 // single user
1955 if (is_numeric($id)) {
1957 $name = $name["lastname"] . ", " . $name["firstname"];
1958 }
1959 // team
1960 else {
1961 $name = "";
1962 $team_id = (int) substr($id, 1);
1963 if (array_key_exists($team_id, $teams)) {
1964 $name = array();
1965 foreach ($teams[$team_id]->getMembers() as $member_id) {
1966 $uname = ilObjUser::_lookupName($member_id);
1967 $name[] = $uname["lastname"] . ", " . $uname["firstname"];
1968 }
1969 asort($name);
1970 $name = implode("<br />", $name);
1971 }
1972 }
1973
1974 $dl = new ilDateTimeInputGUI($name, "dl_" . $ass_id . "_" . $id);
1975 $dl->setShowTime(true);
1976 $dl->setRequired(true);
1977 $form->addItem($dl);
1978
1979 if (array_key_exists($id, $values)) {
1980 $dl->setDate(new ilDateTime($values[$id], IL_CAL_UNIX));
1981 }
1982 }
1983 }
1984
1985 $form->addCommandButton("", $this->lng->txt("save"));
1986
1987 return $form;
1988 }
1989
1990 protected function setIndividualDeadlineObject()
1991 {
1992 // this will only get called if no selection
1993 ilUtil::sendFailure($this->lng->txt("select_one"));
1994
1995 if ($this->assignment) {
1996 $this->membersObject();
1997 } else {
1998 $this->showParticipantObject();
1999 }
2000 }
2001
2002 public function initFilter()
2003 {
2004 if ($_POST["filter_status"]) {
2005 $this->filter["status"] = trim(ilUtil::stripSlashes($_POST["filter_status"]));
2006 }
2007
2008 if ($_POST["filter_feedback"]) {
2009 $this->filter["feedback"] = trim(ilUtil::stripSlashes($_POST["filter_feedback"]));
2010 }
2011
2012 $this->lng->loadLanguageModule("search");
2013
2014 $this->toolbar->setFormAction($this->ctrl->getFormAction($this, "listTextAssignment"));
2015
2016 // Status
2017
2018 if ($_POST["filter_status"]) {
2019 $this->filter["status"] = trim(ilUtil::stripSlashes($_POST["filter_status"]));
2020 }
2021
2022 $si_status = new ilSelectInputGUI($this->lng->txt("exc_tbl_status"), "filter_status");
2023 $options = array(
2024 "" => $this->lng->txt("search_any"),
2025 self::GRADE_NOT_GRADED => $this->lng->txt("exc_notgraded"),
2026 self::GRADE_PASSED => $this->lng->txt("exc_passed"),
2027 self::GRADE_FAILED => $this->lng->txt("exc_failed")
2028 );
2029 $si_status->setOptions($options);
2030 $si_status->setValue($this->filter["status"]);
2031
2032 $si_feedback = new ilSelectInputGUI($this->lng->txt("feedback"), "filter_feedback");
2033 $options = array(
2034 self::FEEDBACK_FULL_SUBMISSION => $this->lng->txt("submissions_feedback"),
2035 self::FEEDBACK_ONLY_SUBMISSION => $this->lng->txt("submissions_only")
2036 );
2037 $si_feedback->setOptions($options);
2038 $si_feedback->setValue($this->filter["feedback"]);
2039
2040 $this->toolbar->addInputItem($si_status, true);
2041
2042 // Submissions and Feedback
2043 #24713
2044 if ($this->assignment->getPeerReview()) {
2045 if ($_POST["filter_feedback"]) {
2046 $this->filter["feedback"] = trim(ilUtil::stripSlashes($_POST["filter_feedback"]));
2047 } else {
2048 $this->filter["feedback"] = "submission_feedback";
2049 }
2050
2051 $si_feedback = new ilSelectInputGUI($this->lng->txt("feedback"), "filter_feedback");
2052 $options = array(
2053 "submission_feedback" => $this->lng->txt("submissions_feedback"),
2054 "submission_only" => $this->lng->txt("submissions_only")
2055 );
2056 $si_feedback->setOptions($options);
2057 $si_feedback->setValue($this->filter["feedback"]);
2058
2059 $this->toolbar->addInputItem($si_feedback, true);
2060 }
2061
2062 //todo: old school here.
2063 $submit = ilSubmitButton::getInstance();
2064 $submit->setCaption("filter");
2065 $submit->setCommand("listTextAssignment");
2066 $this->toolbar->addButtonInstance($submit);
2067 }
2068
2073 {
2074 global $DIC;
2075
2076 $ass_id = (int) $_GET["ass_id"];
2077 $member_id = (int) $_GET["member_id"];
2078
2079 $submission = new ilExSubmission($this->assignment, $member_id);
2080
2081 $last_opening = $submission->getLastOpeningHTMLView();
2082
2083 $submission_time = $submission->getLastSubmission();
2084
2085 $zip_original_full_path = $this->getSubmissionZipFilePath($submission);
2086
2087 $zip_internal_path = $this->getWebFilePathFromExternalFilePath($zip_original_full_path);
2088
2089 list($obj_date, $obj_id) = explode("_", basename($zip_original_full_path));
2090
2091 $obj_dir = $this->assignment->getAssignmentType()->getStringIdentifier() . "_" . $obj_id;
2092
2093 $index_html_file = ILIAS_WEB_DIR .
2094 DIRECTORY_SEPARATOR .
2095 CLIENT_ID .
2096 DIRECTORY_SEPARATOR .
2097 dirname($zip_internal_path) .
2098 DIRECTORY_SEPARATOR .
2099 $obj_dir .
2100 DIRECTORY_SEPARATOR .
2101 "index.html";
2102
2104
2105 $web_filesystem = $DIC->filesystem()->web();
2106
2107 if ($last_opening > $submission_time && $web_filesystem->has($index_html_file)) {
2108 ilUtil::redirect($index_html_file);
2109 }
2110 if ($zip_original_full_path) {
2111 $file_copied = $this->copyFileToWebDir($zip_original_full_path, $zip_internal_path);
2112
2113 if ($file_copied) {
2114 ilUtil::unzip($file_copied, true);
2115
2116 $web_filesystem->delete($zip_internal_path);
2117
2118 $submission_repository = new ilExcSubmissionRepository();
2119 $submission_repository->updateWebDirAccessTime($this->assignment->getId(), $member_id);
2120
2121 ilUtil::redirect($index_html_file);
2122 }
2123
2124 $error_msg = $this->lng->txt("exc_copy_zip_error");
2125 }
2126
2127 if (!$error_msg) {
2128 $error_msg = $this->lng->txt("exc_find_zip_error");
2129 }
2130
2131 ilUtil::sendFailure($error_msg);
2132 }
2133
2139 protected function getSubmissionZipFilePath(ilExSubmission $submission) : ?string
2140 {
2141 $submitted = $submission->getFiles();
2142
2143 if (count($submitted) > 0) {
2144 $submitted = array_pop($submitted);
2145
2146 return $submitted['filename'];
2147 }
2148
2149 return null;
2150 }
2151
2158 protected function copyFileToWebDir(string $origin_path_filename, string $internal_file_path) : ?string
2159 {
2160 global $DIC;
2161
2162 $web_filesystem = $DIC->filesystem()->web();
2163 $data_filesystem = $DIC->filesystem()->storage();
2164
2165 $internal_dirs = dirname($internal_file_path);
2166 $zip_file = basename($internal_file_path);
2167
2168 if ($data_filesystem->has($internal_file_path)) {
2169 if (!$web_filesystem->hasDir($internal_dirs)) {
2170 $web_filesystem->createDir($internal_dirs);
2171 }
2172
2173 if (!$web_filesystem->has($internal_file_path)) {
2174 $stream = $data_filesystem->readStream($internal_file_path);
2175 $web_filesystem->writeStream($internal_file_path, $stream);
2176
2177 return ILIAS_ABSOLUTE_PATH .
2178 DIRECTORY_SEPARATOR .
2179 ILIAS_WEB_DIR .
2180 DIRECTORY_SEPARATOR .
2181 CLIENT_ID .
2182 DIRECTORY_SEPARATOR .
2183 $internal_dirs .
2184 DIRECTORY_SEPARATOR .
2185 $zip_file;
2186 }
2187 }
2188
2189 return null;
2190 }
2191
2197 protected function getWebFilePathFromExternalFilePath(string $external_file_path) : string
2198 {
2199 list($external_path, $internal_file_path) = explode(CLIENT_ID . "/", $external_file_path);
2200
2201 return $internal_file_path;
2202 }
2203
2204 /*
2205 * Add the Back link to the tabs. (used in submission list and submission compare)
2206 */
2207 protected function setBackToMembers()
2208 {
2209 //tabs
2210 $this->tabs_gui->clearTargets();
2211 $this->tabs_gui->setBackTarget(
2212 $this->lng->txt("back"),
2213 $this->ctrl->getLinkTarget($this, "members")
2214 );
2215 }
2216
2221 public function collectFeedbackDataFromPeer(array $a_data) : array
2222 {
2223 $user = new ilObjUser($a_data["user_id"]);
2224 $uname = $user->getFirstname() . " " . $user->getLastname();
2225
2226 $data = array(
2227 "uid" => $a_data["user_id"],
2228 "uname" => $uname,
2229 "udate" => $a_data["ts"],
2230 "utext" => ilRTE::_replaceMediaObjectImageSrc($a_data["atext"], 1) // mob id to mob src
2231 );
2232
2233 //get data peer and assign it
2234 $peer_review = new ilExPeerReview($this->assignment);
2235 $data["peer"] = array();
2236 foreach ($peer_review->getPeerReviewsByPeerId($a_data['user_id']) as $key => $value) {
2237 $data["peer"][] = $value['giver_id'];
2238 }
2239
2240 $data["fb_received"] = count($data["peer"]);
2241 $data["fb_given"] = $peer_review->countGivenFeedback(true, $a_data["user_id"]);
2242
2243 return $data;
2244 }
2245}
user()
Definition: user.php:4
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$section
Definition: Utf8Test.php:83
$comment
Definition: buildRTE.php:83
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_UNIX
const IL_CAL_DATETIME
This class represents a property in a property form.
This class represents an option in a checkbox group.
Confirmation screen class.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date @access public.
This class represents a date/time property in a property form.
@classDescription Date and time handling
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
Download submissions and feedback for exercises.
static getAdoptableGroups($a_exc_ref_id)
static getGroupMembersMap($a_exc_ref_id)
static getAssignmentTeamMap($a_ass_id)
Get team structure for assignment.
static getInstanceByUserId($a_assignment_id, $a_user_id, $a_create_on_demand=false)
static getInstancesFromMap($a_assignment_id)
Exercise assignment.
static getInstancesByExercise($a_exc_id)
static getAssignmentDataOfExercise($a_exc_id)
Get assignments data of an exercise in an array.
static lookupTitle($a_id)
Lookup title.
Exercise participant table.
Class ilExPeerReviewGUI.
Exercise peer review.
Object-based submissions (ends up as static file)
Exercise submission //TODO: This class has to much static methods related to delivered "files".
static downloadAllAssignmentFiles(ilExAssignment $a_ass, array $members, $to_path)
Download all submitted files of an assignment (all user)
static getAssignmentFilesByUsers(int $a_exc_id, int $a_ass_id, array $a_users)
static getAssignmentParticipants(int $a_exercise_id, int $a_ass_id)
getFiles(array $a_file_ids=null, $a_only_valid=false, $a_min_timestamp=null)
Get submission items (not only files)
Exercise exceptions class.
Class ilExerciseManagementGUI.
initIndividualDeadlineForm(array $a_ass_map, array $ids)
copyFileToWebDir(string $origin_path_filename, string $internal_file_path)
Generate the directories and copy the file if necessary.
redirectFeedbackMailObject()
set feedback status for member and redirect to mail screen
confirmDeassignMembersObject()
Confirm deassigning members.
addSubTabs($a_activate)
adds tabs to tab gui object
uploadMultiFeedbackObject()
Upload multi feedback file.
sendMembersObject()
Send assignment per mail to participants.
saveStatusAllObject(array $a_selected=null, $a_redirect=true)
showMultiFeedbackObject(ilPropertyFormGUI $a_form=null)
Show multi-feedback screen.
saveStatusParticipantObject(array $a_selected=null)
Save assignment status (participant view)
adoptTeamsFromGroupObject(ilPropertyFormGUI $a_form=null)
saveEvaluationFromModalObject()
Save assignment submission grade(status) and comment from the roundtrip modal.
getSubmissionZipFilePath(ilExSubmission $submission)
Returns the ZIP file path from outside web directory.
deassignMembersObject()
Deassign members from exercise.
openSubmissionViewObject()
Open HTML view for portfolio submissions.
showMultiFeedbackConfirmationTableObject()
Show multi feedback confirmation table.
saveMultiFeedbackObject()
Save multi feedback.
getWebFilePathFromExternalFilePath(string $external_file_path)
Get the object specific file path from an external full file path.
cancelMultiFeedbackObject()
Cancel Multi Feedback.
membersObject()
All participants and submission of one assignment.
showGradesOverviewObject()
Show grades overview.
addUserFromAutoCompleteObject()
Add user as member.
compareTextAssignmentsObject()
TODO -> Deal with the redirection after update the grade via action button.
selectParticipantObject()
Select participant.
__construct(ilExerciseInternalService $service, ilExAssignment $a_ass=null)
Constructor.
downloadAllObject()
Download all submitted files (of all members).
downloadMultiFeedbackZipObject()
Download multi-feedback structrue file.
addMembersObject($a_user_ids=array())
Add new partipant.
saveStatus(array $a_data, $a_redirect=true)
Save status of selecte members.
saveCommentForLearnersObject()
Save comment for learner (asynch)
Class ilExerciseMembersFilter.
Class ilExerciseMembers.
This class represents a file property in a property form.
File System Explorer GUI class.
This class represents a section header in a property form.
This class represents a hidden form property in a property form.
static getInstance()
Factory.
static getLogger($a_component_id)
Get component logger.
static getRedirectTarget($gui, $cmd, array $gui_params=array(), array $mail_params=array(), array $context_params=array())
const SIGNATURE_KEY
Session parameter for the hash.
static getInstance()
Get instance.
This class represents a non editable value in a property form.
static _lookupLogin($a_user_id)
lookup login
static _lookupId($a_user_str)
Lookup id by login.
static _lookupName($a_user_id)
lookup user name
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data@access public
static _lookupType($a_id, $a_reference=false)
lookup object type
This class represents a property form user interface.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static fillAutoCompleteToolbar($parent_object, ilToolbarGUI $toolbar=null, $a_options=array(), $a_sticky=false)
fill toolbar with
This class represents a selection list property in a property form.
static getInstance()
Factory.
special template class to simplify handling of ITX/PEAR
This class represents a text area property in a property form.
This class represents a text property in a property form.
static getNamePresentation( $a_user_id, $a_user_image=false, $a_profile_link=false, $a_profile_back_link="", $a_force_first_lastname=false, $a_omit_login=false, $a_sortable=true, $a_return_data_array=false, $a_ctrl_path="ilpublicuserprofilegui")
Default behaviour is:
static sortArray( $array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static redirect($a_script)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static stripSlashesArray($a_arr, $a_strip_html=true, $a_allow="")
Strip slashes from array.
static signFolderOfStartFile($start_file_path)
$valid
global $ilCtrl
Definition: ilias.php:18
exit
Definition: login.php:29
if($format !==null) $name
Definition: metadata.php:230
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$url
foreach($_POST as $key=> $value) $res
$data
Definition: storeScorm.php:23
$DIC
Definition: xapitoken.php:46