ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilExerciseSubmissionTableGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once("./Services/Table/classes/class.ilTable2GUI.php");
5include_once("./Modules/Exercise/classes/class.ilExAssignment.php");
6include_once("./Modules/Exercise/classes/class.ilExAssignmentTeam.php");
7include_once("./Services/UIComponent/Modal/classes/class.ilModalGUI.php");
8
18{
22 protected $access;
23
24 protected $exc; // [ilObjExercise]
25 protected $mode; // [int]
26 protected $filter; // [array]
27 protected $comment_modals = array(); // [array]
28
30 const MODE_BY_USER = 2;
31
32 // needs PH P5.6 for array support
33 protected $cols_mandatory = array("name", "status");
34 protected $cols_default = array("login", "submission", "idl", "calc_deadline");
35 protected $cols_order = array("image", "name", "login", "team_members",
36 "sent_time", "submission", "calc_deadline", "idl", "status", "mark", "status_time",
37 "feedback_time", "comment", "notice");
38
48 public function __construct($a_parent_obj, $a_parent_cmd, ilObjExercise $a_exc, $a_item_id)
49 {
50 global $DIC;
51
52 $this->ctrl = $DIC->ctrl();
53 $this->access = $DIC->access();
54 $this->tpl = $DIC["tpl"];
55 $this->lng = $DIC->language();
56
57
58 $ilCtrl = $DIC->ctrl();
59
60 $this->exc = $a_exc;
61
62 $this->initMode($a_item_id);
63
64 parent::__construct($a_parent_obj, $a_parent_cmd);
65
66 $this->setShowTemplates(true);
67
68 $this->setFormAction($ilCtrl->getFormAction($a_parent_obj));
69 $this->setRowTemplate("tpl.exc_members_row.html", "Modules/Exercise");
70
71 #25100
72 if ($this->mode == self::MODE_BY_ASSIGNMENT) {
73 $this->setDefaultOrderField("name");
74 $this->setDefaultOrderDirection("asc");
75 }
76
77
78 // columns
79
80 $this->addColumn("", "", "1", true);
81
82 $selected = $this->getSelectedColumns();
83 $columns = $this->parseColumns();
84 foreach ($this->cols_order as $id) {
85 if (in_array($id, $this->cols_mandatory) ||
86 in_array($id, $selected)) {
87 if (array_key_exists($id, $columns)) {
88 $col = $columns[$id];
89 $this->addColumn($col[0], $col[1]);
90 }
91 }
92 }
93
94 $this->addColumn($this->lng->txt("actions"));
95
96
97 // multi actions
98
99 $this->addMultiCommand("saveStatusSelected", $this->lng->txt("exc_save_selected"));
100
101 $this->setFormName("ilExcIDlForm");
102
103 // see 0021530 and parseRow here with similar action per user
104 if ($this->mode == self::MODE_BY_ASSIGNMENT &&
105 $this->ass->hasActiveIDl() &&
106 !$this->ass->hasReadOnlyIDl()) {
107 $this->addMultiCommand("setIndividualDeadline", $this->lng->txt("exc_individual_deadline_action"));
108 }
109
110 if ($this->exc->hasTutorFeedbackMail() &&
111 $this->mode == self::MODE_BY_ASSIGNMENT) {
112 $this->addMultiCommand("redirectFeedbackMail", $this->lng->txt("exc_tbl_action_feedback_mail"));
113 }
114
115 $this->addMultiCommand("sendMembers", $this->lng->txt("exc_send_assignment"));
116
117 if ($this->mode == self::MODE_BY_ASSIGNMENT &&
118 $this->ass &&
119 $this->ass->hasTeam()) {
120 $this->addMultiCommand("createTeams", $this->lng->txt("exc_team_multi_create"));
121 $this->addMultiCommand("dissolveTeams", $this->lng->txt("exc_team_multi_dissolve"));
122 }
123
124 if ($this->mode == self::MODE_BY_ASSIGNMENT) {
125 $this->addMultiCommand("confirmDeassignMembers", $this->lng->txt("exc_deassign_members"));
126 }
127
128 $this->setFilterCommand($this->getParentCmd() . "Apply");
129 $this->setResetCommand($this->getParentCmd() . "Reset");
130
131 $this->initFilter();
132 $this->setData($this->parseData());
133
134 include_once "Services/Form/classes/class.ilPropertyFormGUI.php";
135 }
136
137 public function initFilter()
138 {
139 if ($this->mode == self::MODE_BY_ASSIGNMENT) {
140 $item = $this->addFilterItemByMetaType("flt_name", self::FILTER_TEXT, false, $this->lng->txt("name") . " / " . $this->lng->txt("login"));
141 $this->filter["name"] = $item->getValue();
142 }
143
144 $this->lng->loadLanguageModule("search");
145 $options = array(
146 "" => $this->lng->txt("search_any"),
147 "notgraded" => $this->lng->txt("exc_notgraded"),
148 "passed" => $this->lng->txt("exc_passed"),
149 "failed" => $this->lng->txt("exc_failed")
150 );
151 $item = $this->addFilterItemByMetaType("flt_status", self::FILTER_SELECT, false, $this->lng->txt("exc_tbl_status"));
152 $item->setOptions($options);
153 $this->filter["status"] = $item->getValue();
154
155 $options = array(
156 "" => $this->lng->txt("search_any"),
157 "y" => $this->lng->txt("exc_tbl_filter_has_submission"),
158 "n" => $this->lng->txt("exc_tbl_filter_has_no_submission")
159 );
160 $item = $this->addFilterItemByMetaType("flt_subm", self::FILTER_SELECT, false, $this->lng->txt("exc_tbl_filter_submission"));
161 $item->setOptions($options);
162 $this->filter["subm"] = $item->getValue();
163 }
164
165 abstract protected function initMode($a_item_id);
166
167 abstract protected function parseData();
168
169 abstract protected function parseModeColumns();
170
171 public function getSelectableColumns()
172 {
173 $cols = array();
174
175 $columns = $this->parseColumns();
176 foreach ($this->cols_order as $id) {
177 if (in_array($id, $this->cols_mandatory)) {
178 continue;
179 }
180
181 if (array_key_exists($id, $columns)) {
182 $col = $columns[$id];
183
184 $cols[$id] = array(
185 "txt" => $col[0],
186 "default" => in_array($id, $this->cols_default)
187 );
188 }
189 }
190 return $cols;
191 }
192
193 protected function parseColumns()
194 {
195 $cols = $this->parseModeColumns();
196
197 $cols["submission"] = array($this->lng->txt("exc_tbl_submission_date"), "submission");
198
199 $cols["status"] = array($this->lng->txt("exc_tbl_status"), "status");
200 $cols["mark"] = array($this->lng->txt("exc_tbl_mark"), "mark");
201 $cols["status_time"] = array($this->lng->txt("exc_tbl_status_time"), "status_time");
202
203 $cols["sent_time"] = array($this->lng->txt("exc_tbl_sent_time"), "sent_time");
204
205 if ($this->exc->hasTutorFeedbackText() ||
206 $this->exc->hasTutorFeedbackMail() ||
207 $this->exc->hasTutorFeedbackFile()) {
208 $cols["feedback_time"] = array($this->lng->txt("exc_tbl_feedback_time"), "feedback_time");
209 }
210
211 if ($this->exc->hasTutorFeedbackText()) {
212 $cols["comment"] = array($this->lng->txt("exc_tbl_comment"), "comment");
213 }
214
215 $cols["notice"] = array($this->lng->txt("exc_tbl_notice"), "notice");
216
217 return $cols;
218 }
219
220 protected function parseRow($a_user_id, ilExAssignment $a_ass, array $a_row)
221 {
223 $ilAccess = $this->access;
224
225 $has_no_team_yet = ($a_ass->hasTeam() &&
226 !ilExAssignmentTeam::getTeamId($a_ass->getId(), $a_user_id));
227
228
229 // static columns
230
231 if ($this->mode == self::MODE_BY_ASSIGNMENT) {
232 if (!$a_ass->hasTeam()) {
233 $this->tpl->setVariable("VAL_NAME", $a_row["name"]);
234
235 // #18327
236 if (!$ilAccess->checkAccessOfUser($a_user_id, "read", "", $this->exc->getRefId()) &&
237 is_array($info = $ilAccess->getInfo())) {
238 $this->tpl->setCurrentBlock('access_warning');
239 $this->tpl->setVariable('PARENT_ACCESS', $info[0]["text"]);
240 $this->tpl->parseCurrentBlock();
241 }
242 } else {
243 asort($a_row["team"]);
244 foreach ($a_row["team"] as $team_member_id => $team_member_name) { // #10749
245 if (sizeof($a_row["team"]) > 1) {
246 $ilCtrl->setParameterByClass("ilExSubmissionTeamGUI", "id", $team_member_id);
247 $url = $ilCtrl->getLinkTargetByClass("ilExSubmissionTeamGUI", "confirmRemoveTeamMember");
248 $ilCtrl->setParameterByClass("ilExSubmissionTeamGUI", "id", "");
249
250 include_once "Services/UIComponent/Glyph/classes/class.ilGlyphGUI.php";
251
252 $this->tpl->setCurrentBlock("team_member_removal_bl");
253 $this->tpl->setVariable("URL_TEAM_MEMBER_REMOVAL", $url);
254 $this->tpl->setVariable(
255 "TXT_TEAM_MEMBER_REMOVAL",
256 ilGlyphGUI::get(ilGlyphGUI::CLOSE, $this->lng->txt("remove"))
257 );
258 $this->tpl->parseCurrentBlock();
259 }
260
261 // #18327
262 if (!$ilAccess->checkAccessOfUser($team_member_id, "read", "", $this->exc->getRefId()) &&
263 is_array($info = $ilAccess->getInfo())) {
264 $this->tpl->setCurrentBlock('team_access_warning');
265 $this->tpl->setVariable('TEAM_PARENT_ACCESS', $info[0]["text"]);
266 $this->tpl->parseCurrentBlock();
267 }
268
269 $this->tpl->setCurrentBlock("team_member");
270 $this->tpl->setVariable("TXT_MEMBER_NAME", $team_member_name);
271 $this->tpl->parseCurrentBlock();
272 }
273
274 if ($has_no_team_yet) {
275 // #11957
276 $this->tpl->setCurrentBlock("team_info");
277 $this->tpl->setVariable("TXT_TEAM_INFO", $this->lng->txt("exc_no_team_yet"));
278 } else {
279 $this->tpl->setCurrentBlock("team_info");
280 $this->tpl->setVariable("TXT_TEAM_INFO", "(" . $a_row["submission_obj"]->getTeam()->getId() . ")");
281 }
282 }
283 } else {
284 $this->tpl->setVariable("VAL_NAME", $a_row["name"]);
285 }
286
287 // do not grade or mark if no team yet
288 if (!$has_no_team_yet) {
289 // status
290 $this->tpl->setVariable("SEL_" . strtoupper($a_row["status"]), ' selected="selected" ');
291 $this->tpl->setVariable("TXT_NOTGRADED", $this->lng->txt("exc_notgraded"));
292 $this->tpl->setVariable("TXT_PASSED", $this->lng->txt("exc_passed"));
293 $this->tpl->setVariable("TXT_FAILED", $this->lng->txt("exc_failed"));
294 } else {
295 $nt_colspan = in_array("mark", $this->getSelectedColumns())
296 ? 2
297 : 1;
298
299 $this->tpl->setVariable("NO_TEAM_COLSPAN", $nt_colspan);
300 }
301
302
303 // comment modal
304
305 if ($this->exc->hasTutorFeedbackText()) {
306 $comment_id = "excasscomm_" . $a_ass->getId() . "_" . $a_user_id;
307
308 $modal = ilModalGUI::getInstance();
309 $modal->setId($comment_id);
310 $modal->setHeading($this->lng->txt("exc_tbl_action_feedback_text"));
311
312 $lcomment_form = new ilPropertyFormGUI();
313 $lcomment_form->setId($comment_id);
314 $lcomment_form->setPreventDoubleSubmission(false);
315
316 $lcomment = new ilTextAreaInputGUI($this->lng->txt("exc_comment_for_learner"), "lcomment_" . $a_ass->getId() . "_" . $a_user_id);
317 $lcomment->setInfo($this->lng->txt("exc_comment_for_learner_info"));
318 $lcomment->setValue($a_row["comment"]);
319 $lcomment->setCols(45);
320 $lcomment->setRows(10);
321 $lcomment_form->addItem($lcomment);
322
323 $lcomment_form->addCommandButton("save", $this->lng->txt("save"));
324 // $lcomment_form->addCommandButton("cancel", $lng->txt("cancel"));
325
326 $modal->setBody($lcomment_form->getHTML());
327
328 $this->comment_modals[] = $modal->getHTML();
329 unset($modal);
330 }
331
332
333 // selectable columns
334
335 foreach ($this->getSelectedColumns() as $col) {
336 $include_seconds = false;
337 switch ($col) {
338 case "image":
339 if (!$a_ass->hasTeam()) {
340 include_once "./Services/Object/classes/class.ilObjectFactory.php";
341 if ($usr_obj = ilObjectFactory::getInstanceByObjId($a_user_id, false)) {
342 $this->tpl->setVariable("VAL_IMAGE", $usr_obj->getPersonalPicturePath("xxsmall"));
343 $this->tpl->setVariable("TXT_IMAGE", $this->lng->txt("personal_picture"));
344 }
345 }
346 break;
347
348 case "team_members":
349 if ($a_ass->hasTeam()) {
350 if (!sizeof($a_row["team"])) {
351 $this->tpl->setVariable("VAL_TEAM_MEMBER", $this->lng->txt("exc_no_team_yet"));
352 } else {
353 foreach ($a_row["team"] as $name) {
354 $this->tpl->setCurrentBlock("team_member_bl");
355 $this->tpl->setVariable("VAL_TEAM_MEMBER", $name);
356 $this->tpl->parseCurrentBlock();
357 }
358 }
359 } else {
360 $this->tpl->setVariable("VAL_TEAM_MEMBER", "&nbsp;");
361 }
362 break;
363
364 case "idl":
365 $this->tpl->setVariable(
366 "VAL_" . strtoupper($col),
367 $a_row[$col]
369 : "&nbsp;"
370 );
371 break;
372
373 case "calc_deadline":
374 $this->tpl->setVariable(
375 "VAL_" . strtoupper($col),
376 $a_row[$col]
378 : "&nbsp;"
379 );
380 break;
381
382 case "mark":
383 if ($has_no_team_yet) {
384 break;
385 }
386 // fallthrough
387
388 // no break
389 case "notice":
390 // see #22076
391 $this->tpl->setVariable("VAL_" . strtoupper($col), ilUtil::prepareFormOutput(trim($a_row[$col])));
392 break;
393
394 case "comment":
395 // for js-updating
396 $this->tpl->setVariable("LCOMMENT_ID", $comment_id . "_snip");
397
398 // see #22076
399 $this->tpl->setVariable("VAL_" . strtoupper($col), (trim($a_row[$col]) !== "")
400 ? nl2br(trim($a_row[$col]))
401 : "&nbsp;");
402 break;
403
404 case "submission":
405 $include_seconds = true;
406 if ($a_row["submission_obj"]) {
407 foreach ($a_row["submission_obj"]->getFiles() as $file) {
408 if ($file["late"]) {
409 $this->tpl->setVariable("TXT_LATE", $this->lng->txt("exc_late_submission"));
410 break;
411 }
412 }
413 }
414 // fallthrough
415
416 // no break
417 case "feedback_time":
418 case "status_time":
419 case "sent_time":
420 $this->tpl->setVariable(
421 "VAL_" . strtoupper($col),
422 $a_row[$col]
424 new ilDateTime($a_row[$col], IL_CAL_DATETIME),
425 false,
426 false,
427 $include_seconds
428 )
429 : "&nbsp;"
430 );
431 break;
432
433 case "login":
434 if ($a_ass->hasTeam()) {
435 break;
436 }
437 // fallthrough
438
439 // no break
440 default:
441 $this->tpl->setVariable("VAL_" . strtoupper($col), $a_row[$col]
442 ? trim($a_row[$col])
443 : "&nbsp;");
444 break;
445 }
446 }
447
448
449 // actions
450
451 include_once "Services/UIComponent/AdvancedSelectionList/classes/class.ilAdvancedSelectionListGUI.php";
452 $actions = new ilAdvancedSelectionListGUI();
453 $actions->setId($a_ass->getId() . "_" . $a_user_id);
454 $actions->setListTitle($this->lng->txt("actions"));
455
456 $file_info = $a_row["submission_obj"]->getDownloadedFilesInfoForTableGUIS($this->getParentObject(), $this->getParentCmd());
457
458 $counter = $file_info["files"]["count"];
459 if ($counter) {
460 if ($file_info["files"]["download_url"]) {
461 $actions->addItem(
462 $file_info["files"]["download_txt"] . " (" . $counter . ")",
463 "",
464 $file_info["files"]["download_url"]
465 );
466 }
467
468 if ($file_info["files"]["download_new_url"]) {
469 $actions->addItem(
470 $file_info["files"]["download_new_txt"],
471 "",
472 $file_info["files"]["download_new_url"]
473 );
474 }
475 }
476
477 if (!$has_no_team_yet &&
478 $a_ass->hasActiveIDl() &&
479 !$a_ass->hasReadOnlyIDl()) {
480 $idl_id = $a_ass->hasTeam()
481 ? "t" . ilExAssignmentTeam::getTeamId($a_ass->getId(), $a_user_id)
482 : $a_user_id;
483
484 $this->tpl->setVariable("VAL_IDL_ID", $a_ass->getId() . "_" . $idl_id);
485
486 $actions->addItem(
487 $this->lng->txt("exc_individual_deadline_action"),
488 "",
489 "#",
490 "",
491 "",
492 "",
493 "",
494 false,
495 "il.ExcIDl.trigger('" . $idl_id . "'," . $a_ass->getId() . ")"
496 );
497 }
498
499 // feedback mail
500 if ($this->exc->hasTutorFeedbackMail()) {
501 $actions->addItem(
502 $this->lng->txt("exc_tbl_action_feedback_mail"),
503 "",
504 $ilCtrl->getLinkTarget($this->parent_obj, "redirectFeedbackMail")
505 );
506 }
507
508 // feedback files
509 if ($this->exc->hasTutorFeedbackFile()) {
510 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
511 $storage = new ilFSStorageExercise($this->exc->getId(), $a_ass->getId());
512 $counter = $storage->countFeedbackFiles($a_row["submission_obj"]->getFeedbackId());
513 $counter = $counter
514 ? " (" . $counter . ")"
515 : "";
516 $actions->addItem(
517 $this->lng->txt("exc_tbl_action_feedback_file") . $counter,
518 "",
519 $ilCtrl->getLinkTargetByClass("ilfilesystemgui", "listFiles")
520 );
521 }
522
523 // comment (modal - see above)
524 if ($this->exc->hasTutorFeedbackText()) {
525 $actions->addItem(
526 $this->lng->txt("exc_tbl_action_feedback_text"),
527 "",
528 "#",
529 "",
530 "",
531 "",
532 "",
533 false,
534 "il.ExcManagement.showComment('" . $comment_id . "')"
535 );
536 }
537
538 // peer review
539 if (($peer_review = $a_row["submission_obj"]->getPeerReview()) && $a_ass->afterDeadlineStrict()) { // see #22246
540 $counter = $peer_review->countGivenFeedback(true, $a_user_id);
541 $counter = $counter
542 ? " (" . $counter . ")"
543 : "";
544 $actions->addItem(
545 $this->lng->txt("exc_tbl_action_peer_review_given") . $counter,
546 "",
547 $ilCtrl->getLinkTargetByClass("ilexpeerreviewgui", "showGivenPeerReview")
548 );
549
550 $counter = sizeof($peer_review->getPeerReviewsByPeerId($a_user_id, true));
551 $counter = $counter
552 ? " (" . $counter . ")"
553 : "";
554 $actions->addItem(
555 $this->lng->txt("exc_tbl_action_peer_review_received") . $counter,
556 "",
557 $ilCtrl->getLinkTargetByClass("ilexpeerreviewgui", "showReceivedPeerReview")
558 );
559 }
560
561 // team
562 if ($has_no_team_yet) {
563 $actions->addItem(
564 $this->lng->txt("exc_create_team"),
565 "",
566 $ilCtrl->getLinkTargetByClass("ilExSubmissionTeamGUI", "createSingleMemberTeam")
567 );
568 } elseif ($a_ass->hasTeam()) {
569 $actions->addItem(
570 $this->lng->txt("exc_tbl_action_team_log"),
571 "",
572 $ilCtrl->getLinkTargetByClass("ilExSubmissionTeamGUI", "showTeamLog")
573 );
574 }
575
576 $this->tpl->setVariable("ACTIONS", $actions->getHTML());
577 }
578
579 public function render()
580 {
581 global $DIC;
583 $tpl = $DIC->ui()->mainTemplate();
584
585 $url = $ilCtrl->getLinkTarget($this->getParentObject(), "saveCommentForLearners", "", true, false);
586
587 $tpl->addJavaScript("Modules/Exercise/js/ilExcManagement.js");
588 $tpl->addOnLoadCode('il.ExcManagement.init("' . $url . '");');
589
590 return parent::render() .
591 implode("\n", $this->comment_modals);
592 }
593}
if(! $in) $columns
Definition: Utf8Test.php:45
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_UNIX
const IL_CAL_DATETIME
User interface class for advanced drop-down selection lists.
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
static getTeamId($a_assignment_id, $a_user_id, $a_create_on_demand=false)
Get team id for member id.
Exercise assignment.
afterDeadlineStrict($a_include_personal=true)
getId()
Get assignment id.
parseRow($a_user_id, ilExAssignment $a_ass, array $a_row)
__construct($a_parent_obj, $a_parent_cmd, ilObjExercise $a_exc, $a_item_id)
Constructor.
static get($a_glyph, $a_text="")
Get glyph html.
static getInstance()
Get instance.
Class ilObjExercise.
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
This class represents a property form user interface.
Class ilTable2GUI.
getParentCmd()
Get parent command.
getSelectedColumns()
Get selected columns.
getParentObject()
Get parent object.
getId()
Get element id.
setData($a_data)
set table data @access public
setResetCommand($a_val, $a_caption=null)
Set reset filter command.
setRowTemplate($a_template, $a_template_dir="")
Set row template.
addMultiCommand($a_cmd, $a_text)
Add Command button.
setDefaultOrderField($a_defaultorderfield)
Set Default order field.
addColumn( $a_text, $a_sort_field="", $a_width="", $a_is_checkbox_action_column=false, $a_class="", $a_tooltip="", $a_tooltip_with_html=false)
Add a column to the header.
addFilterItemByMetaType($id, $type=self::FILTER_TEXT, $a_optional=false, $caption=null)
Add filter by standard type.
setFormName($a_formname="")
Set Form name.
setFormAction($a_form_action, $a_multipart=false)
Set Form action parameter.
setDefaultOrderDirection($a_defaultorderdirection)
Set Default order direction.
setFilterCommand($a_val, $a_caption=null)
Set filter command.
setShowTemplates($a_value)
Toggle templates.
This class represents a text area property in a property form.
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
if(!array_key_exists('StateId', $_REQUEST)) $id
global $ilCtrl
Definition: ilias.php:18
$info
Definition: index.php:5
$url
global $DIC
Definition: saml.php:7
$cols
Definition: xhr_table.php:11