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 
4 include_once("./Services/Table/classes/class.ilTable2GUI.php");
5 include_once("./Modules/Exercise/classes/class.ilExAssignment.php");
6 include_once("./Modules/Exercise/classes/class.ilExAssignmentTeam.php");
7 include_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 
29  const MODE_BY_ASSIGNMENT = 1;
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 }
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
setDefaultOrderField($a_defaultorderfield)
Set Default order field.
Exercise assignment.
const IL_CAL_DATETIME
This class represents a property form user interface.
global $DIC
Definition: saml.php:7
static getTeamId($a_assignment_id, $a_user_id, $a_create_on_demand=false)
Get team id for member id.
setShowTemplates($a_value)
Toggle templates.
getId()
Get assignment id.
if(!array_key_exists('StateId', $_REQUEST)) $id
addFilterItemByMetaType($id, $type=self::FILTER_TEXT, $a_optional=false, $caption=null)
Add filter by standard type.
static get($a_glyph, $a_text="")
Get glyph html.
const IL_CAL_UNIX
getParentCmd()
Get parent command.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date public.
getParentObject()
Get parent object.
global $ilCtrl
Definition: ilias.php:18
setDefaultOrderDirection($a_defaultorderdirection)
Set Default order direction.
setInfo($a_info)
Set Information Text.
Class ilObjExercise.
Class ilTable2GUI.
setResetCommand($a_val, $a_caption=null)
Set reset filter command.
addMultiCommand($a_cmd, $a_text)
Add Command button.
parseRow($a_user_id, ilExAssignment $a_ass, array $a_row)
Date and time handling
getSelectedColumns()
Get selected columns.
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
setRowTemplate($a_template, $a_template_dir="")
Set row template.
User interface class for advanced drop-down selection lists.
__construct($a_parent_obj, $a_parent_cmd, ilObjExercise $a_exc, $a_item_id)
Constructor.
afterDeadlineStrict($a_include_personal=true)
static getInstance()
Get instance.
setFormAction($a_form_action, $a_multipart=false)
Set Form action parameter.
setFormName($a_formname="")
Set Form name.
This class represents a text area property in a property form.
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.
$url
countFeedbackFiles($a_user_id)
Count number of feedback files for a user.
getId()
Get element id.
$info
Definition: index.php:5
if(! $in) $columns
Definition: Utf8Test.php:45
$cols
Definition: xhr_table.php:11
setFilterCommand($a_val, $a_caption=null)
Set filter command.