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