ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilExAssignment.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
11 {
15  protected $db;
16 
20  protected $lng;
21 
25  protected $user;
26 
30  protected $app_event_handler;
31 
35  const TYPE_UPLOAD = 1;
39  const TYPE_BLOG = 2;
43  const TYPE_PORTFOLIO = 3;
47  const TYPE_UPLOAD_TEAM = 4;
51  const TYPE_TEXT = 5;
55  const TYPE_WIKI_TEAM = 6;
56 
60 
64 
69 
70  const DEADLINE_ABSOLUTE = 0;
71  const DEADLINE_RELATIVE = 1;
72 
73 
74  protected $id;
75  protected $exc_id;
76  protected $type;
77  protected $start_time;
78  protected $deadline;
79  protected $deadline2;
80  protected $instruction;
81  protected $title;
82  protected $mandatory;
83  protected $order_nr;
84  protected $peer;
85  protected $peer_min;
86  protected $peer_unlock;
87  protected $peer_dl;
88  protected $peer_valid;
89  protected $peer_file;
90  protected $peer_personal;
91  protected $peer_char;
92  protected $peer_text;
93  protected $peer_rating;
94  protected $peer_crit_cat;
95  protected $feedback_file;
96  protected $feedback_cron;
97  protected $feedback_date;
99  protected $team_tutor = false;
100  protected $max_file;
101 
103  protected $min_char_limit;
104  protected $max_char_limit;
105 
106  protected $types = null;
107 
111  protected $ass_type;
112 
113  protected $deadline_mode = 0;
114  protected $relative_deadline = 0;
115  protected $starting_timestamp = null;
116 
121 
122  protected $member_status = array(); // [array]
123 
124  protected $log;
125 
129  public function __construct($a_id = 0)
130  {
131  global $DIC;
132 
133  $this->db = $DIC->database();
134  $this->lng = $DIC->language();
135  $this->user = $DIC->user();
136  $this->app_event_handler = $DIC["ilAppEventHandler"];
137  $this->types = ilExAssignmentTypes::getInstance();
138 
139  $this->setType(self::TYPE_UPLOAD);
140  $this->setFeedbackDate(self::FEEDBACK_DATE_DEADLINE);
141 
142  $this->log = ilLoggerFactory::getLogger("exc");
143 
144  if ($a_id > 0) {
145  $this->setId($a_id);
146  $this->read();
147  }
148  }
149 
154  public static function getInstancesByExercise($a_exc_id)
155  {
156  global $DIC;
157 
158  $ilDB = $DIC->database();
159 
160  $set = $ilDB->query("SELECT * FROM exc_assignment " .
161  " WHERE exc_id = " . $ilDB->quote($a_exc_id, "integer") .
162  " ORDER BY order_nr ASC");
163  $data = array();
164 
165  $order_val = 10;
166  while ($rec = $ilDB->fetchAssoc($set)) {
167  // ???
168  $rec["order_val"] = $order_val;
169 
170  $ass = new self();
171  $ass->initFromDB($rec);
172  $data[] = $ass;
173 
174  $order_val += 10;
175  }
176 
177  return $data;
178  }
179 
185  public static function instructionFileGetFileOrderData($a_file_data, $a_ass_id)
186  {
187  global $DIC;
188 
189  $db = $DIC->database();
190  $db->setLimit(1, 0);
191 
192  $result_order_val = $db->query("
193  SELECT id, order_nr
194  FROM exc_ass_file_order
195  WHERE assignment_id = {$db->quote($a_ass_id, 'integer')}
196  AND filename = {$db->quote($a_file_data['entry'], 'string')}
197  ");
198 
199  $order_val = 0;
200  $order_id = 0;
201  while ($row = $db->fetchAssoc($result_order_val)) {
202  $order_val = (int) $row['order_nr'];
203  $order_id = (int) $row['id'];
204  }
205  return array($order_val, $order_id);
206  }
207 
208  public function hasTeam()
209  {
210  return $this->ass_type->usesTeams();
211  }
212 
218  public function setId($a_val)
219  {
220  $this->id = $a_val;
221  }
222 
228  public function getId()
229  {
230  return $this->id;
231  }
232 
238  public function setExerciseId($a_val)
239  {
240  $this->exc_id = $a_val;
241  }
242 
248  public function getExerciseId()
249  {
250  return $this->exc_id;
251  }
252 
258  public function setStartTime($a_val)
259  {
260  $this->start_time = $a_val;
261  }
262 
268  public function getStartTime()
269  {
270  return $this->start_time;
271  }
272 
278  public function setDeadline($a_val)
279  {
280  $this->deadline = $a_val;
281  }
282 
288  public function getDeadline()
289  {
290  return $this->deadline;
291  }
292 
298  public function setDeadlineMode($a_val)
299  {
300  $this->deadline_mode = $a_val;
301  }
302 
308  public function getDeadlineMode()
309  {
310  return $this->deadline_mode;
311  }
312 
318  public function setRelativeDeadline($a_val)
319  {
320  $this->relative_deadline = $a_val;
321  }
322 
328  public function getRelativeDeadline()
329  {
331  }
332 
338  public function setRelDeadlineLastSubmission($a_val)
339  {
340  $this->rel_deadline_last_subm = $a_val;
341  }
342 
349  {
351  }
352 
353 
359  public function getPersonalDeadline($a_user_id)
360  {
361  $ilDB = $this->db;
362 
363  $is_team = false;
364  if ($this->ass_type->usesTeams()) {
365  $team_id = ilExAssignmentTeam::getTeamId($this->getId(), $a_user_id);
366  if (!$team_id) {
367  // #0021043
368  return $this->getDeadline();
369  }
370  $a_user_id = $team_id;
371  $is_team = true;
372  }
373 
374  $set = $ilDB->query("SELECT tstamp FROM exc_idl" .
375  " WHERE ass_id = " . $ilDB->quote($this->getId(), "integer") .
376  " AND member_id = " . $ilDB->quote($a_user_id, "integer") .
377  " AND is_team = " . $ilDB->quote($is_team, "integer"));
378  $row = $ilDB->fetchAssoc($set);
379 
380  // use assignment deadline if no direct personal
381  return max($row["tstamp"], $this->getDeadline());
382  }
383 
389  public function getLastPersonalDeadline()
390  {
391  $ilDB = $this->db;
392 
393  $set = $ilDB->query("SELECT MAX(tstamp) FROM exc_idl" .
394  " WHERE ass_id = " . $ilDB->quote($this->getId(), "integer"));
395  $row = $ilDB->fetchAssoc($set);
396  return $row["tstamp"];
397  }
398 
404  public function setExtendedDeadline($a_val)
405  {
406  if ($a_val !== null) {
407  $a_val = (int) $a_val;
408  }
409  $this->deadline2 = $a_val;
410  }
411 
417  public function getExtendedDeadline()
418  {
419  return $this->deadline2;
420  }
421 
427  public function setInstruction($a_val)
428  {
429  $this->instruction = $a_val;
430  }
431 
437  public function getInstruction()
438  {
439  return $this->instruction;
440  }
441 
447  public function getInstructionPresentation()
448  {
449  $inst = $this->getInstruction();
450  if (trim($inst)) {
451  $is_html = (strlen($inst) != strlen(strip_tags($inst)));
452  if (!$is_html) {
453  $inst = nl2br(ilUtil::makeClickable($inst, true));
454  }
455  }
456  return $inst;
457  }
458 
459 
465  public function setTitle($a_val)
466  {
467  $this->title = $a_val;
468  }
469 
475  public function getTitle()
476  {
477  return $this->title;
478  }
479 
485  public function setMandatory($a_val)
486  {
487  $this->mandatory = $a_val;
488  }
489 
495  public function getMandatory()
496  {
497  return $this->mandatory;
498  }
499 
505  public function setOrderNr($a_val)
506  {
507  $this->order_nr = $a_val;
508  }
509 
515  public function getOrderNr()
516  {
517  return $this->order_nr;
518  }
519 
526  public function setType($a_value)
527  {
528  if ($this->isValidType($a_value)) {
529  $this->type = (int) $a_value;
530 
531  $this->ass_type = $this->types->getById($a_value);
532 
533  if ($this->ass_type->usesTeams()) {
534  $this->setPeerReview(false);
535  }
536  }
537  }
538 
545  public function getAssignmentType()
546  {
547  return $this->ass_type;
548  }
549 
550 
557  public function getType()
558  {
559  return $this->type;
560  }
561 
568  public function isValidType($a_value)
569  {
570  return $this->types->isValidId($a_value);
571  }
572 
578  public function setPeerReview($a_value)
579  {
580  $this->peer = (bool) $a_value;
581  }
582 
588  public function getPeerReview()
589  {
590  return (bool) $this->peer;
591  }
592 
598  public function setPeerReviewMin($a_value)
599  {
600  $this->peer_min = (int) $a_value;
601  }
602 
608  public function getPeerReviewMin()
609  {
610  return (int) $this->peer_min;
611  }
612 
618  public function setPeerReviewSimpleUnlock($a_value)
619  {
620  $this->peer_unlock = (bool) $a_value;
621  }
622 
628  public function getPeerReviewSimpleUnlock()
629  {
630  return (bool) $this->peer_unlock;
631  }
632 
638  public function setPeerReviewDeadline($a_val)
639  {
640  $this->peer_dl = $a_val;
641  }
642 
648  public function getPeerReviewDeadline()
649  {
650  return $this->peer_dl;
651  }
652 
658  public function setPeerReviewValid($a_value)
659  {
660  $this->peer_valid = (int) $a_value;
661  }
662 
668  public function getPeerReviewValid()
669  {
670  return (int) $this->peer_valid;
671  }
672 
678  public function setPeerReviewRating($a_val)
679  {
680  $this->peer_rating = (bool) $a_val;
681  }
682 
688  public function hasPeerReviewRating()
689  {
690  return $this->peer_rating;
691  }
692 
698  public function setPeerReviewText($a_val)
699  {
700  $this->peer_text = (bool) $a_val;
701  }
702 
708  public function hasPeerReviewText()
709  {
710  return $this->peer_text;
711  }
712 
718  public function setPeerReviewFileUpload($a_val)
719  {
720  $this->peer_file = (bool) $a_val;
721  }
722 
728  public function hasPeerReviewFileUpload()
729  {
730  return $this->peer_file;
731  }
732 
738  public function setPeerReviewPersonalized($a_val)
739  {
740  $this->peer_personal = (bool) $a_val;
741  }
742 
748  public function hasPeerReviewPersonalized()
749  {
750  return $this->peer_personal;
751  }
752 
758  public function setPeerReviewChars($a_value)
759  {
760  $a_value = (is_numeric($a_value) && (int) $a_value > 0)
761  ? (int) $a_value
762  : null;
763  $this->peer_char = $a_value;
764  }
765 
771  public function getPeerReviewChars()
772  {
773  return $this->peer_char;
774  }
775 
781  public function setPeerReviewCriteriaCatalogue($a_value)
782  {
783  $a_value = is_numeric($a_value)
784  ? (int) $a_value
785  : null;
786  $this->crit_cat = $a_value;
787  }
788 
795  {
796  return $this->crit_cat;
797  }
798 
800  {
801  if ($this->crit_cat) {
802  return ilExcCriteria::getInstancesByParentId($this->crit_cat);
803  } else {
804  $res = array();
805 
806  if ($this->peer_rating) {
808  }
809 
810  if ($this->peer_text) {
811  $crit = ilExcCriteria::getInstanceByType("text");
812  if ($this->peer_char) {
813  $crit->setMinChars($this->peer_char);
814  }
815  $res[] = $crit;
816  }
817 
818  if ($this->peer_file) {
820  }
821 
822  return $res;
823  }
824  }
825 
831  public function setFeedbackFile($a_value)
832  {
833  $this->feedback_file = (string) $a_value;
834  }
835 
841  public function getFeedbackFile()
842  {
843  return (string) $this->feedback_file;
844  }
845 
851  public function setFeedbackCron($a_value)
852  {
853  $this->feedback_cron = (string) $a_value;
854  }
855 
861  public function hasFeedbackCron()
862  {
863  return (bool) $this->feedback_cron;
864  }
865 
871  public function setFeedbackDate($a_value)
872  {
873  $this->feedback_date = (int) $a_value;
874  }
875 
881  public function getFeedbackDate()
882  {
883  return (int) $this->feedback_date;
884  }
885 
890  public function setFeedbackDateCustom($a_value)
891  {
892  $this->feedback_date_custom = $a_value;
893  }
894 
899  public function getFeedbackDateCustom()
900  {
902  }
903 
909  public function setTeamTutor($a_value)
910  {
911  $this->team_tutor = (bool) $a_value;
912  }
913 
919  public function getTeamTutor()
920  {
921  return $this->team_tutor;
922  }
923 
929  public function setMaxFile($a_value)
930  {
931  if ($a_value !== null) {
932  $a_value = (int) $a_value;
933  }
934  $this->max_file = $a_value;
935  }
936 
942  public function getMaxFile()
943  {
944  return $this->max_file;
945  }
946 
952  public function setPortfolioTemplateId($a_val)
953  {
954  $this->portfolio_template = $a_val;
955  }
956 
962  public function getPortfolioTemplateId()
963  {
965  }
966 
967 
971  public function read()
972  {
973  $ilDB = $this->db;
974 
975  $set = $ilDB->query(
976  "SELECT * FROM exc_assignment " .
977  " WHERE id = " . $ilDB->quote($this->getId(), "integer")
978  );
979  $rec = $ilDB->fetchAssoc($set);
980 
981  // #16172 - might be deleted
982  if (is_array($rec)) {
983  $this->initFromDB($rec);
984  }
985  }
986 
993  protected function initFromDB(array $a_set)
994  {
995  $this->setId($a_set["id"]);
996  $this->setExerciseId($a_set["exc_id"]);
997  $this->setDeadline($a_set["time_stamp"]);
998  $this->setExtendedDeadline($a_set["deadline2"]);
999  $this->setInstruction($a_set["instruction"]);
1000  $this->setTitle($a_set["title"]);
1001  $this->setStartTime($a_set["start_time"]);
1002  $this->setOrderNr($a_set["order_nr"]);
1003  $this->setMandatory($a_set["mandatory"]);
1004  $this->setType($a_set["type"]);
1005  $this->setPeerReview($a_set["peer"]);
1006  $this->setPeerReviewMin($a_set["peer_min"]);
1007  $this->setPeerReviewSimpleUnlock($a_set["peer_unlock"]);
1008  $this->setPeerReviewDeadline($a_set["peer_dl"]);
1009  $this->setPeerReviewValid($a_set["peer_valid"]);
1010  $this->setPeerReviewFileUpload($a_set["peer_file"]);
1011  $this->setPeerReviewPersonalized($a_set["peer_prsl"]);
1012  $this->setPeerReviewChars($a_set["peer_char"]);
1013  $this->setPeerReviewText($a_set["peer_text"]);
1014  $this->setPeerReviewRating($a_set["peer_rating"]);
1015  $this->setPeerReviewCriteriaCatalogue($a_set["peer_crit_cat"]);
1016  $this->setFeedbackFile($a_set["fb_file"]);
1017  $this->setFeedbackDate($a_set["fb_date"]);
1018  $this->setFeedbackDateCustom($a_set["fb_date_custom"]);
1019  $this->setFeedbackCron($a_set["fb_cron"]);
1020  $this->setTeamTutor($a_set["team_tutor"]);
1021  $this->setMaxFile($a_set["max_file"]);
1022  $this->setPortfolioTemplateId($a_set["portfolio_template"]);
1023  $this->setMinCharLimit($a_set["min_char_limit"]);
1024  $this->setMaxCharLimit($a_set["max_char_limit"]);
1025  $this->setDeadlineMode($a_set["deadline_mode"]);
1026  $this->setRelativeDeadline($a_set["relative_deadline"]);
1027  $this->setRelDeadlineLastSubmission($a_set["rel_deadline_last_subm"]);
1028  }
1029 
1033  public function save()
1034  {
1035  $ilDB = $this->db;
1036 
1037  if ($this->getOrderNr() == 0) {
1038  $this->setOrderNr(
1039  self::lookupMaxOrderNrForEx($this->getExerciseId())
1040  + 10
1041  );
1042  }
1043 
1044  $next_id = $ilDB->nextId("exc_assignment");
1045  $ilDB->insert("exc_assignment", array(
1046  "id" => array("integer", $next_id),
1047  "exc_id" => array("integer", $this->getExerciseId()),
1048  "time_stamp" => array("integer", $this->getDeadline()),
1049  "deadline2" => array("integer", $this->getExtendedDeadline()),
1050  "instruction" => array("clob", $this->getInstruction()),
1051  "title" => array("text", $this->getTitle()),
1052  "start_time" => array("integer", $this->getStartTime()),
1053  "order_nr" => array("integer", $this->getOrderNr()),
1054  "mandatory" => array("integer", $this->getMandatory()),
1055  "type" => array("integer", $this->getType()),
1056  "peer" => array("integer", $this->getPeerReview()),
1057  "peer_min" => array("integer", $this->getPeerReviewMin()),
1058  "peer_unlock" => array("integer", $this->getPeerReviewSimpleUnlock()),
1059  "peer_dl" => array("integer", $this->getPeerReviewDeadline()),
1060  "peer_valid" => array("integer", $this->getPeerReviewValid()),
1061  "peer_file" => array("integer", $this->hasPeerReviewFileUpload()),
1062  "peer_prsl" => array("integer", $this->hasPeerReviewPersonalized()),
1063  "peer_char" => array("integer", $this->getPeerReviewChars()),
1064  "peer_text" => array("integer", (int) $this->hasPeerReviewText()),
1065  "peer_rating" => array("integer", (int) $this->hasPeerReviewRating()),
1066  "peer_crit_cat" => array("integer", $this->getPeerReviewCriteriaCatalogue()),
1067  "fb_file" => array("text", $this->getFeedbackFile()),
1068  "fb_date" => array("integer", $this->getFeedbackDate()),
1069  "fb_date_custom" => array("integer", $this->getFeedbackDateCustom()),
1070  "fb_cron" => array("integer", $this->hasFeedbackCron()),
1071  "team_tutor" => array("integer", $this->getTeamTutor()),
1072  "max_file" => array("integer", $this->getMaxFile()),
1073  "portfolio_template" => array("integer", $this->getPortFolioTemplateId()),
1074  "min_char_limit" => array("integer", $this->getMinCharLimit()),
1075  "max_char_limit" => array("integer", $this->getMaxCharLimit()),
1076  "relative_deadline" => array("integer", $this->getRelativeDeadline()),
1077  "rel_deadline_last_subm" => array("integer", (int) $this->getRelDeadlineLastSubmission()),
1078  "deadline_mode" => array("integer", $this->getDeadlineMode())
1079  ));
1080  $this->setId($next_id);
1081  $exc = new ilObjExercise($this->getExerciseId(), false);
1082  $exc->updateAllUsersStatus();
1083  self::createNewAssignmentRecords($next_id, $exc);
1084 
1085  $this->handleCalendarEntries("create");
1086  }
1087 
1091  public function update()
1092  {
1093  $ilDB = $this->db;
1094 
1095  $ilDB->update(
1096  "exc_assignment",
1097  array(
1098  "exc_id" => array("integer", $this->getExerciseId()),
1099  "time_stamp" => array("integer", $this->getDeadline()),
1100  "deadline2" => array("integer", $this->getExtendedDeadline()),
1101  "instruction" => array("clob", $this->getInstruction()),
1102  "title" => array("text", $this->getTitle()),
1103  "start_time" => array("integer", $this->getStartTime()),
1104  "order_nr" => array("integer", $this->getOrderNr()),
1105  "mandatory" => array("integer", $this->getMandatory()),
1106  "type" => array("integer", $this->getType()),
1107  "peer" => array("integer", $this->getPeerReview()),
1108  "peer_min" => array("integer", $this->getPeerReviewMin()),
1109  "peer_unlock" => array("integer", $this->getPeerReviewSimpleUnlock()),
1110  "peer_dl" => array("integer", $this->getPeerReviewDeadline()),
1111  "peer_valid" => array("integer", $this->getPeerReviewValid()),
1112  "peer_file" => array("integer", $this->hasPeerReviewFileUpload()),
1113  "peer_prsl" => array("integer", $this->hasPeerReviewPersonalized()),
1114  "peer_char" => array("integer", $this->getPeerReviewChars()),
1115  "peer_text" => array("integer", (int) $this->hasPeerReviewText()),
1116  "peer_rating" => array("integer", (int) $this->hasPeerReviewRating()),
1117  "peer_crit_cat" => array("integer", $this->getPeerReviewCriteriaCatalogue()),
1118  "fb_file" => array("text", $this->getFeedbackFile()),
1119  "fb_date" => array("integer", $this->getFeedbackDate()),
1120  "fb_date_custom" => array("integer", $this->getFeedbackDateCustom()),
1121  "fb_cron" => array("integer", $this->hasFeedbackCron()),
1122  "team_tutor" => array("integer", $this->getTeamTutor()),
1123  "max_file" => array("integer", $this->getMaxFile()),
1124  "portfolio_template" => array("integer", $this->getPortFolioTemplateId()),
1125  "min_char_limit" => array("integer", $this->getMinCharLimit()),
1126  "max_char_limit" => array("integer", $this->getMaxCharLimit()),
1127  "deadline_mode" => array("integer", $this->getDeadlineMode()),
1128  "relative_deadline" => array("integer", $this->getRelativeDeadline()),
1129  "rel_deadline_last_subm" => array("integer", (int) $this->getRelDeadlineLastSubmission())
1130  ),
1131  array(
1132  "id" => array("integer", $this->getId()),
1133  )
1134  );
1135  $exc = new ilObjExercise($this->getExerciseId(), false);
1136  $exc->updateAllUsersStatus();
1137 
1138  $this->handleCalendarEntries("update");
1139  }
1140 
1144  public function delete()
1145  {
1146  $ilDB = $this->db;
1147 
1148  $this->deleteGlobalFeedbackFile();
1149 
1150  $ilDB->manipulate(
1151  "DELETE FROM exc_assignment WHERE " .
1152  " id = " . $ilDB->quote($this->getId(), "integer")
1153  );
1154  $exc = new ilObjExercise($this->getExerciseId(), false);
1155  $exc->updateAllUsersStatus();
1156 
1157  $this->handleCalendarEntries("delete");
1158 
1159  $reminder = new ilExAssignmentReminder();
1160  $reminder->deleteReminders($this->getId());
1161  }
1162 
1163 
1167  public static function getAssignmentDataOfExercise($a_exc_id)
1168  {
1169  global $DIC;
1170 
1171  $ilDB = $DIC->database();
1172 
1173  // should be changed to self::getInstancesByExerciseId()
1174 
1175  $set = $ilDB->query("SELECT * FROM exc_assignment " .
1176  " WHERE exc_id = " . $ilDB->quote($a_exc_id, "integer") .
1177  " ORDER BY order_nr ASC");
1178  $data = array();
1179 
1180  $order_val = 10;
1181  while ($rec = $ilDB->fetchAssoc($set)) {
1182  $data[] = array(
1183  "id" => $rec["id"],
1184  "exc_id" => $rec["exc_id"],
1185  "deadline" => $rec["time_stamp"],
1186  "deadline2" => $rec["deadline2"],
1187  "instruction" => $rec["instruction"],
1188  "title" => $rec["title"],
1189  "start_time" => $rec["start_time"],
1190  "order_val" => $order_val,
1191  "mandatory" => $rec["mandatory"],
1192  "type" => $rec["type"],
1193  "peer" => $rec["peer"],
1194  "peer_min" => $rec["peer_min"],
1195  "peer_dl" => $rec["peer_dl"],
1196  "peer_file" => $rec["peer_file"],
1197  "peer_prsl" => $rec["peer_prsl"],
1198  "fb_file" => $rec["fb_file"],
1199  "fb_date" => $rec["fb_date"],
1200  "fb_cron" => $rec["fb_cron"],
1201  "deadline_mode" => $rec["deadline_mode"],
1202  "relative_deadline" => $rec["relative_deadline"],
1203  "rel_deadline_last_subm" => $rec["rel_deadline_last_subm"]
1204  );
1205  $order_val += 10;
1206  }
1207  return $data;
1208  }
1209 
1215  public static function cloneAssignmentsOfExercise($a_old_exc_id, $a_new_exc_id, array $a_crit_cat_map)
1216  {
1217  $ass_data = self::getInstancesByExercise($a_old_exc_id);
1218  foreach ($ass_data as $d) {
1219  // clone assignment
1220  $new_ass = new ilExAssignment();
1221  $new_ass->setExerciseId($a_new_exc_id);
1222  $new_ass->setTitle($d->getTitle());
1223  $new_ass->setDeadline($d->getDeadline());
1224  $new_ass->setExtendedDeadline($d->getExtendedDeadline());
1225  $new_ass->setInstruction($d->getInstruction());
1226  $new_ass->setMandatory($d->getMandatory());
1227  $new_ass->setOrderNr($d->getOrderNr());
1228  $new_ass->setStartTime($d->getStartTime());
1229  $new_ass->setType($d->getType());
1230  $new_ass->setPeerReview($d->getPeerReview());
1231  $new_ass->setPeerReviewMin($d->getPeerReviewMin());
1232  $new_ass->setPeerReviewDeadline($d->getPeerReviewDeadline());
1233  $new_ass->setPeerReviewFileUpload($d->hasPeerReviewFileUpload());
1234  $new_ass->setPeerReviewPersonalized($d->hasPeerReviewPersonalized());
1235  $new_ass->setPeerReviewValid($d->getPeerReviewValid());
1236  $new_ass->setPeerReviewChars($d->getPeerReviewChars());
1237  $new_ass->setPeerReviewText($d->hasPeerReviewText());
1238  $new_ass->setPeerReviewRating($d->hasPeerReviewRating());
1239  $new_ass->setPeerReviewCriteriaCatalogue($d->getPeerReviewCriteriaCatalogue());
1240  $new_ass->setPeerReviewSimpleUnlock($d->getPeerReviewSimpleUnlock());
1241  $new_ass->setFeedbackFile($d->getFeedbackFile());
1242  $new_ass->setFeedbackDate($d->getFeedbackDate());
1243  $new_ass->setFeedbackDateCustom($d->getFeedbackDateCustom());
1244  $new_ass->setFeedbackCron($d->hasFeedbackCron()); // #16295
1245  $new_ass->setTeamTutor($d->getTeamTutor());
1246  $new_ass->setMaxFile($d->getMaxFile());
1247  $new_ass->setMinCharLimit($d->getMinCharLimit());
1248  $new_ass->setMaxCharLimit($d->getMaxCharLimit());
1249  $new_ass->setPortfolioTemplateId($d->getPortfolioTemplateId());
1250  $new_ass->setDeadlineMode($d->getDeadlineMode());
1251  $new_ass->setRelativeDeadline($d->getRelativeDeadline());
1252  $new_ass->setRelDeadlineLastSubmission($d->getRelDeadlineLastSubmission());
1253 
1254  // criteria catalogue(s)
1255  if ($d->getPeerReviewCriteriaCatalogue() &&
1256  array_key_exists($d->getPeerReviewCriteriaCatalogue(), $a_crit_cat_map)) {
1257  $new_ass->setPeerReviewCriteriaCatalogue($a_crit_cat_map[$d->getPeerReviewCriteriaCatalogue()]);
1258  }
1259 
1260  $new_ass->save();
1261 
1262 
1263  // clone assignment files
1264  $old_web_storage = new ilFSWebStorageExercise($a_old_exc_id, (int) $d->getId());
1265  $new_web_storage = new ilFSWebStorageExercise($a_new_exc_id, (int) $new_ass->getId());
1266  $new_web_storage->create();
1267  if (is_dir($old_web_storage->getPath())) {
1268  ilUtil::rCopy($old_web_storage->getPath(), $new_web_storage->getPath());
1269  }
1270  $order = $d->getInstructionFilesOrder();
1271  foreach ($order as $file) {
1272  ilExAssignment::insertFileOrderNr($new_ass->getId(), $file["filename"], $file["order_nr"]);
1273  }
1274 
1275  // clone global feedback file
1276  $old_storage = new ilFSStorageExercise($a_old_exc_id, (int) $d->getId());
1277  $new_storage = new ilFSStorageExercise($a_new_exc_id, (int) $new_ass->getId());
1278  $new_storage->create();
1279  if (is_dir($old_storage->getGlobalFeedbackPath())) {
1280  ilUtil::rCopy($old_storage->getGlobalFeedbackPath(), $new_storage->getGlobalFeedbackPath());
1281  }
1282 
1283  // clone reminders
1287  $rmd_sub = new ilExAssignmentReminder($a_old_exc_id, $d->getId(), $rem_type);
1288  if ($rmd_sub->getReminderStatus()) {
1289  $new_rmd_sub = new ilExAssignmentReminder($a_new_exc_id, $new_ass->getId(), $rem_type);
1290  $new_rmd_sub->setReminderStatus($rmd_sub->getReminderStatus());
1291  $new_rmd_sub->setReminderStart($rmd_sub->getReminderStart());
1292  $new_rmd_sub->setReminderEnd($rmd_sub->getReminderEnd());
1293  $new_rmd_sub->setReminderFrequency($rmd_sub->getReminderFrequency());
1294  $new_rmd_sub->setReminderMailTemplate($rmd_sub->getReminderMailTemplate());
1295  $new_rmd_sub->save();
1296  }
1297  }
1298 
1299 
1300  // type specific properties
1301  $ass_type = $d->getAssignmentType();
1302  $ass_type->cloneSpecificProperties($d, $new_ass);
1303  }
1304  }
1305 
1309  public function getFiles()
1310  {
1311  $this->log->debug("getting files from class.ilExAssignment using ilFSWebStorageExercise");
1312  $storage = new ilFSWebStorageExercise($this->getExerciseId(), $this->getId());
1313  return $storage->getFiles();
1314  }
1315 
1320  public function getInstructionFilesOrder()
1321  {
1322  $ilDB = $this->db;
1323 
1324  $set = $ilDB->query(
1325  "SELECT filename, order_nr, id FROM exc_ass_file_order " .
1326  " WHERE assignment_id = " . $ilDB->quote($this->getId(), "integer")
1327  );
1328 
1329  $data = array();
1330  while ($rec = $ilDB->fetchAssoc($set)) {
1331  $data[$rec['filename']] = $rec;
1332  }
1333 
1334  return $data;
1335  }
1336 
1340  public static function lookupMaxOrderNrForEx($a_exc_id)
1341  {
1342  global $DIC;
1343 
1344  $ilDB = $DIC->database();
1345 
1346  $set = $ilDB->query(
1347  "SELECT MAX(order_nr) mnr FROM exc_assignment " .
1348  " WHERE exc_id = " . $ilDB->quote($a_exc_id, "integer")
1349  );
1350  while ($rec = $ilDB->fetchAssoc($set)) {
1351  return (int) $rec["mnr"];
1352  }
1353  return 0;
1354  }
1355 
1361  public static function lookupAssignmentOnline($a_ass_id)
1362  {
1363  global $DIC;
1364 
1365  $ilDB = $DIC->database();
1366 
1367  $query = "SELECT id FROM exc_assignment " .
1368  "WHERE start_time <= " . $ilDB->quote(time(), 'integer') . ' ' .
1369  "AND time_stamp >= " . $ilDB->quote(time(), 'integer') . ' ' .
1370  "AND id = " . $ilDB->quote($a_ass_id, 'integer');
1371  $res = $ilDB->query($query);
1372 
1373  return $res->numRows() ? true : false;
1374  }
1375 
1382  public static function lookupExerciseId($a_ass_id)
1383  {
1384  global $DIC;
1385 
1386  $ilDB = $DIC->database();
1387 
1388  $query = "SELECT exc_id FROM exc_assignment " .
1389  "WHERE id = " . $ilDB->quote($a_ass_id, 'integer');
1390  $res = $ilDB->fetchAssoc($ilDB->query($query));
1391 
1392  return (int) $res["exc_id"];
1393  }
1394 
1398  private static function lookup($a_id, $a_field)
1399  {
1400  global $DIC;
1401 
1402  $ilDB = $DIC->database();
1403 
1404  $set = $ilDB->query(
1405  "SELECT " . $a_field . " FROM exc_assignment " .
1406  " WHERE id = " . $ilDB->quote($a_id, "integer")
1407  );
1408 
1409  $rec = $ilDB->fetchAssoc($set);
1410 
1411  return $rec[$a_field];
1412  }
1413 
1417  public static function lookupTitle($a_id)
1418  {
1419  return self::lookup($a_id, "title");
1420  }
1421 
1425  public static function lookupType($a_id)
1426  {
1427  return self::lookup($a_id, "type");
1428  }
1429 
1433  public static function saveAssOrderOfExercise($a_ex_id, $a_order)
1434  {
1435  global $DIC;
1436 
1437  $ilDB = $DIC->database();
1438 
1439  $result_order = array();
1440  asort($a_order);
1441  $nr = 10;
1442  foreach ($a_order as $k => $v) {
1443  // the check for exc_id is for security reasons. ass ids are unique.
1444  $ilDB->manipulate(
1445  $t = "UPDATE exc_assignment SET " .
1446  " order_nr = " . $ilDB->quote($nr, "integer") .
1447  " WHERE id = " . $ilDB->quote((int) $k, "integer") .
1448  " AND exc_id = " . $ilDB->quote((int) $a_ex_id, "integer")
1449  );
1450  $nr += 10;
1451  }
1452  }
1453 
1457  public static function orderAssByDeadline($a_ex_id)
1458  {
1459  global $DIC;
1460  $ilDB = $DIC->database();
1461 
1462  $set = $ilDB->query(
1463  "SELECT id FROM exc_assignment " .
1464  " WHERE exc_id = " . $ilDB->quote($a_ex_id, "integer") .
1465  " ORDER BY time_stamp ASC"
1466  );
1467  $nr = 10;
1468  while ($rec = $ilDB->fetchAssoc($set)) {
1469  $ilDB->manipulate(
1470  "UPDATE exc_assignment SET " .
1471  " order_nr = " . $ilDB->quote($nr, "integer") .
1472  " WHERE id = " . $ilDB->quote($rec["id"], "integer")
1473  );
1474  $nr += 10;
1475  }
1476  }
1477 
1481  public static function countMandatory($a_ex_id)
1482  {
1483  global $DIC;
1484 
1485  $ilDB = $DIC->database();
1486 
1487  $set = $ilDB->query(
1488  "SELECT count(*) cntm FROM exc_assignment " .
1489  " WHERE exc_id = " . $ilDB->quote($a_ex_id, "integer") .
1490  " AND mandatory = " . $ilDB->quote(1, "integer")
1491  );
1492  $rec = $ilDB->fetchAssoc($set);
1493  return $rec["cntm"];
1494  }
1495 
1499  public static function count($a_ex_id)
1500  {
1501  global $DIC;
1502 
1503  $ilDB = $DIC->database();
1504 
1505  $set = $ilDB->query(
1506  "SELECT count(*) cntm FROM exc_assignment " .
1507  " WHERE exc_id = " . $ilDB->quote($a_ex_id, "integer")
1508  );
1509  $rec = $ilDB->fetchAssoc($set);
1510  return $rec["cntm"];
1511  }
1512 
1516  public static function isInExercise($a_ass_id, $a_ex_id)
1517  {
1518  global $DIC;
1519 
1520  $ilDB = $DIC->database();
1521 
1522  $set = $ilDB->query(
1523  "SELECT * FROM exc_assignment " .
1524  " WHERE exc_id = " . $ilDB->quote($a_ex_id, "integer") .
1525  " AND id = " . $ilDB->quote($a_ass_id, "integer")
1526  );
1527  if ($rec = $ilDB->fetchAssoc($set)) {
1528  return true;
1529  }
1530  return false;
1531  }
1532 
1534 
1538  public static function lookupUpdatedSubmission($ass_id, $member_id)
1539  {
1540  global $DIC;
1541 
1542  $ilDB = $DIC->database();
1543  $lng = $DIC->language();
1544 
1545  // team upload?
1546  $user_ids = self::getTeamMembersByAssignmentId($ass_id, $member_id);
1547  if (!$user_ids) {
1548  $user_ids = array($member_id);
1549  }
1550 
1551  $q = "SELECT exc_mem_ass_status.status_time, exc_returned.ts " .
1552  "FROM exc_mem_ass_status, exc_returned " .
1553  "WHERE exc_mem_ass_status.status_time < exc_returned.ts " .
1554  "AND NOT exc_mem_ass_status.status_time IS NULL " .
1555  "AND exc_returned.ass_id = exc_mem_ass_status.ass_id " .
1556  "AND exc_returned.user_id = exc_mem_ass_status.usr_id " .
1557  "AND exc_returned.ass_id=" . $ilDB->quote($ass_id, "integer") .
1558  " AND " . $ilDB->in("exc_returned.user_id", $user_ids, "", "integer");
1559 
1560  $usr_set = $ilDB->query($q);
1561 
1562  $array = $ilDB->fetchAssoc($usr_set);
1563 
1564  if (count($array) == 0) {
1565  return 0;
1566  } else {
1567  return 1;
1568  }
1569  }
1570 
1574  public function getMemberListData()
1575  {
1576  $ilDB = $this->db;
1577 
1578  $mem = array();
1579 
1580  // first get list of members from member table
1581  $set = $ilDB->query("SELECT ud.usr_id, ud.lastname, ud.firstname, ud.login" .
1582  " FROM exc_members excm" .
1583  " JOIN usr_data ud ON (ud.usr_id = excm.usr_id)" .
1584  " WHERE excm.obj_id = " . $ilDB->quote($this->getExerciseId(), "integer"));
1585  while ($rec = $ilDB->fetchAssoc($set)) {
1586  $mem[$rec["usr_id"]] =
1587  array(
1588  "name" => $rec["lastname"] . ", " . $rec["firstname"],
1589  "login" => $rec["login"],
1590  "usr_id" => $rec["usr_id"],
1591  "lastname" => $rec["lastname"],
1592  "firstname" => $rec["firstname"]
1593  );
1594  }
1595 
1596  // users in idl may already exist before occuring in the members db table
1597  // if user starts an assignment with relative deadline
1598  $idl = $this->getIndividualDeadlines();
1599  foreach ($idl as $user_id => $v) {
1600  if (!isset($mem[$user_id])) {
1601  if (ilObjUser::_exists($user_id)) {
1602  $name = ilObjUser::_lookupName($user_id);
1603  $mem[$user_id] =
1604  array(
1605  "name" => $name["lastname"] . ", " . $name["firstname"],
1606  "login" => $name["login"],
1607  "usr_id" => $user_id,
1608  "lastname" => $name["lastname"],
1609  "firstname" => $name["firstname"]
1610  );
1611  }
1612  }
1613  }
1614 
1615 
1616  $q = "SELECT * FROM exc_mem_ass_status " .
1617  "WHERE ass_id = " . $ilDB->quote($this->getId(), "integer");
1618  $set = $ilDB->query($q);
1619  while ($rec = $ilDB->fetchAssoc($set)) {
1620  if (isset($mem[$rec["usr_id"]])) {
1621  $sub = new ilExSubmission($this, $rec["usr_id"]);
1622 
1623  $mem[$rec["usr_id"]]["sent_time"] = $rec["sent_time"];
1624  $mem[$rec["usr_id"]]["submission"] = $sub->getLastSubmission();
1625  $mem[$rec["usr_id"]]["status_time"] = $rec["status_time"];
1626  $mem[$rec["usr_id"]]["feedback_time"] = $rec["feedback_time"];
1627  $mem[$rec["usr_id"]]["notice"] = $rec["notice"];
1628  $mem[$rec["usr_id"]]["status"] = $rec["status"];
1629  $mem[$rec["usr_id"]]["mark"] = $rec["mark"];
1630  $mem[$rec["usr_id"]]["comment"] = $rec["u_comment"];
1631  }
1632  }
1633  return $mem;
1634  }
1635 
1643  public function getExerciseMemberAssignmentData($a_user_id, $a_grade = "")
1644  {
1645  global $DIC;
1646  $ilDB = $DIC->database();
1647 
1648  if (in_array($a_grade, array("notgraded", "passed", "failed"))) {
1649  $and_grade = " AND status = " . $ilDB->quote($a_grade, "text");
1650  }
1651 
1652  $q = "SELECT * FROM exc_mem_ass_status " .
1653  "WHERE ass_id = " . $ilDB->quote($this->getId(), "integer") .
1654  " AND usr_id = " . $ilDB->quote($a_user_id, "integer") .
1655  $and_grade;
1656 
1657  $set = $ilDB->query($q);
1658 
1659  while ($rec = $ilDB->fetchAssoc($set)) {
1660  $sub = new ilExSubmission($this, $a_user_id);
1661 
1662  $data["sent_time"] = $rec["sent_time"];
1663  $data["submission"] = $sub->getLastSubmission();
1664  $data["status_time"] = $rec["status_time"];
1665  $data["feedback_time"] = $rec["feedback_time"];
1666  $data["notice"] = $rec["notice"];
1667  $data["status"] = $rec["status"];
1668  $data["mark"] = $rec["mark"];
1669  $data["comment"] = $rec["u_comment"];
1670  }
1671 
1672  return $data;
1673  }
1674 
1678  public static function createNewUserRecords($a_user_id, $a_exc_id)
1679  {
1680  global $DIC;
1681 
1682  $ilDB = $DIC->database();
1683 
1684  $ass_data = self::getAssignmentDataOfExercise($a_exc_id);
1685  foreach ($ass_data as $ass) {
1686  //echo "-".$ass["id"]."-".$a_user_id."-";
1687  $ilDB->replace("exc_mem_ass_status", array(
1688  "ass_id" => array("integer", $ass["id"]),
1689  "usr_id" => array("integer", $a_user_id)
1690  ), array(
1691  "status" => array("text", "notgraded")
1692  ));
1693  }
1694  }
1695 
1699  public static function createNewAssignmentRecords($a_ass_id, $a_exc)
1700  {
1701  global $DIC;
1702 
1703  $ilDB = $DIC->database();
1704 
1705  $exmem = new ilExerciseMembers($a_exc);
1706  $mems = $exmem->getMembers();
1707 
1708  foreach ($mems as $mem) {
1709  $ilDB->replace("exc_mem_ass_status", array(
1710  "ass_id" => array("integer", $a_ass_id),
1711  "usr_id" => array("integer", $mem)
1712  ), array(
1713  "status" => array("text", "notgraded")
1714  ));
1715  }
1716  }
1717 
1722  public function uploadAssignmentFiles($a_files)
1723  {
1724  ilLoggerFactory::getLogger("exc")->debug("upload assignment files files = ", $a_files);
1725  $storage = new ilFSWebStorageExercise($this->getExerciseId(), $this->getId());
1726  $storage->create();
1727  $storage->uploadAssignmentFiles($a_files);
1728  }
1729 
1730 
1734 
1739  {
1740  global $DIC;
1741 
1742 
1743  // send and delete the zip file
1744  $deliverFilename = trim(str_replace(" ", "_", $this->getTitle() . "_" . $this->getId()));
1745  $deliverFilename = ilUtil::getASCIIFilename($deliverFilename);
1746  $deliverFilename = "multi_feedback_" . $deliverFilename;
1747 
1748  $exc = new ilObjExercise($this->getExerciseId(), false);
1749 
1750  $cdir = getcwd();
1751 
1752  // create temporary directoy
1753  $tmpdir = ilUtil::ilTempnam();
1754  ilUtil::makeDir($tmpdir);
1755  $mfdir = $tmpdir . "/" . $deliverFilename;
1756  ilUtil::makeDir($mfdir);
1757 
1758  // create subfolders <lastname>_<firstname>_<id> for each participant
1759  $exmem = new ilExerciseMembers($exc);
1760  $mems = $exmem->getMembers();
1761 
1762  $mems = $DIC->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
1763  'edit_submissions_grades',
1764  'edit_submissions_grades',
1765  $exercise->getRefId(),
1766  $mems
1767  );
1768  foreach ($mems as $mem) {
1769  $name = ilObjUser::_lookupName($mem);
1770  $subdir = $name["lastname"] . "_" . $name["firstname"] . "_" . $name["login"] . "_" . $name["user_id"];
1771  $subdir = ilUtil::getASCIIFilename($subdir);
1772  ilUtil::makeDir($mfdir . "/" . $subdir);
1773  }
1774 
1775  // create the zip file
1776  chdir($tmpdir);
1777  $tmpzipfile = $tmpdir . "/multi_feedback.zip";
1778  ilUtil::zip($tmpdir, $tmpzipfile, true);
1779  chdir($cdir);
1780 
1781 
1782  ilUtil::deliverFile($tmpzipfile, $deliverFilename . ".zip", "", false, true);
1783  }
1784 
1791  public function uploadMultiFeedbackFile($a_file)
1792  {
1793  $lng = $this->lng;
1794  $ilUser = $this->user;
1795 
1796  if (!is_file($a_file["tmp_name"])) {
1797  throw new ilExerciseException($lng->txt("exc_feedback_file_could_not_be_uploaded"));
1798  }
1799 
1800  $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1801  $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
1802  ilUtil::delDir($mfu, true);
1803  ilUtil::moveUploadedFile($a_file["tmp_name"], "multi_feedback.zip", $mfu . "/" . "multi_feedback.zip");
1804  ilUtil::unzip($mfu . "/multi_feedback.zip", true);
1805  $subdirs = ilUtil::getDir($mfu);
1806  $subdir = "notfound";
1807  foreach ($subdirs as $s => $j) {
1808  if ($j["type"] == "dir" && substr($s, 0, 14) == "multi_feedback") {
1809  $subdir = $s;
1810  }
1811  }
1812 
1813  if (!is_dir($mfu . "/" . $subdir)) {
1814  throw new ilExerciseException($lng->txt("exc_no_feedback_dir_found_in_zip"));
1815  }
1816 
1817  return true;
1818  }
1819 
1826  public function getMultiFeedbackFiles($a_user_id = 0)
1827  {
1828  $ilUser = $this->user;
1829 
1830  if ($a_user_id == 0) {
1831  $a_user_id = $ilUser->getId();
1832  }
1833 
1834  $mf_files = array();
1835 
1836  // get members
1837  $exc = new ilObjExercise($this->getExerciseId(), false);
1838  $exmem = new ilExerciseMembers($exc);
1839  $mems = $exmem->getMembers();
1840 
1841  // read mf directory
1842  $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1843  $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
1844 
1845  // get subdir that starts with multi_feedback
1846  $subdirs = ilUtil::getDir($mfu);
1847  $subdir = "notfound";
1848  foreach ($subdirs as $s => $j) {
1849  if ($j["type"] == "dir" && substr($s, 0, 14) == "multi_feedback") {
1850  $subdir = $s;
1851  }
1852  }
1853 
1854  $items = ilUtil::getDir($mfu . "/" . $subdir);
1855  foreach ($items as $k => $i) {
1856  // check directory
1857  if ($i["type"] == "dir" && !in_array($k, array(".", ".."))) {
1858  // check if valid member id is given
1859  $parts = explode("_", $i["entry"]);
1860  $user_id = (int) $parts[count($parts) - 1];
1861  if (in_array($user_id, $mems)) {
1862  // read dir of user
1863  $name = ilObjUser::_lookupName($user_id);
1864  $files = ilUtil::getDir($mfu . "/" . $subdir . "/" . $k);
1865  foreach ($files as $k2 => $f) {
1866  // append files to array
1867  if ($f["type"] == "file" && substr($k2, 0, 1) != ".") {
1868  $mf_files[] = array(
1869  "lastname" => $name["lastname"],
1870  "firstname" => $name["firstname"],
1871  "login" => $name["login"],
1872  "user_id" => $name["user_id"],
1873  "full_path" => $mfu . "/" . $subdir . "/" . $k . "/" . $k2,
1874  "file" => $k2);
1875  }
1876  }
1877  }
1878  }
1879  }
1880  return $mf_files;
1881  }
1882 
1890  {
1891  $lng = $this->lng;
1892  $ilUser = $this->user;
1893 
1894  $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1895  $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
1896  ilUtil::delDir($mfu);
1897  }
1898 
1905  public function saveMultiFeedbackFiles($a_files, ilObjExercise $a_exc)
1906  {
1907  if ($this->getExerciseId() != $a_exc->getId()) {
1908  return;
1909  }
1910 
1911  $fstorage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1912  $fstorage->create();
1913 
1914  $team_map = array();
1915 
1916  $mf_files = $this->getMultiFeedbackFiles();
1917  foreach ($mf_files as $f) {
1918  $user_id = $f["user_id"];
1919  $file_path = $f["full_path"];
1920  $file_name = $f["file"];
1921 
1922  // if checked in confirmation gui
1923  if ($a_files[$user_id][md5($file_name)] != "") {
1924  $submission = new ilExSubmission($this, $user_id);
1925  $feedback_id = $submission->getFeedbackId();
1926  $noti_rec_ids = $submission->getUserIds();
1927 
1928  if ($feedback_id) {
1929  $fb_path = $fstorage->getFeedbackPath($feedback_id);
1930  $target = $fb_path . "/" . $file_name;
1931  if (is_file($target)) {
1932  unlink($target);
1933  }
1934  // rename file
1935  rename($file_path, $target);
1936 
1937  if ($noti_rec_ids) {
1938  foreach ($noti_rec_ids as $user_id) {
1939  $member_status = $this->getMemberStatus($user_id);
1940  $member_status->setFeedback(true);
1941  $member_status->update();
1942  }
1943 
1945  $file_name,
1946  $noti_rec_ids,
1947  (int) $this->getId()
1948  );
1949  }
1950  }
1951  }
1952  }
1953 
1954  $this->clearMultiFeedbackDirectory();
1955  }
1956 
1957 
1958 
1959 
1965  protected function handleCalendarEntries($a_event)
1966  {
1967  $ilAppEventHandler = $this->app_event_handler;
1968 
1969  $dl_id = $this->getId() . "0";
1970  $fbdl_id = $this->getId() . "1";
1971 
1972  $context_ids = array($dl_id, $fbdl_id);
1973  $apps = array();
1974 
1975  if ($a_event != "delete") {
1976  // deadline or relative deadline given
1977  if ($this->getDeadline() || $this->getDeadlineMode() == ilExAssignment::DEADLINE_RELATIVE) {
1978  $app = new ilCalendarAppointmentTemplate($dl_id);
1979  $app->setTranslationType(IL_CAL_TRANSLATION_SYSTEM);
1980  $app->setSubtitle("cal_exc_deadline");
1981  $app->setTitle($this->getTitle());
1982  $app->setFullday(false);
1983  // note: in the case of a relative deadline this will be set to 0 / 1970...)
1984  // see ilCalendarScheduleFilterExercise for appointment modification
1985  $app->setStart(new ilDateTime($this->getDeadline(), IL_CAL_UNIX));
1986 
1987  $apps[] = $app;
1988  }
1989 
1990  if ($this->getPeerReview() &&
1991  $this->getPeerReviewDeadline()) {
1992  $app = new ilCalendarAppointmentTemplate($fbdl_id);
1993  $app->setTranslationType(IL_CAL_TRANSLATION_SYSTEM);
1994  $app->setSubtitle("cal_exc_peer_review_deadline");
1995  $app->setTitle($this->getTitle());
1996  $app->setFullday(false);
1997  $app->setStart(new ilDateTime($this->getPeerReviewDeadline(), IL_CAL_UNIX));
1998 
1999  $apps[] = $app;
2000  }
2001  }
2002 
2003  $exc = new ilObjExercise($this->getExerciseId(), false);
2004 
2005  $ilAppEventHandler->raise(
2006  'Modules/Exercise',
2007  $a_event . 'Assignment',
2008  array(
2009  'object' => $exc,
2010  'obj_id' => $exc->getId(),
2011  'context_ids' => $context_ids,
2012  'appointments' => $apps)
2013  );
2014  }
2015 
2016 
2017  public static function getPendingFeedbackNotifications()
2018  {
2019  global $DIC;
2020 
2021  $ilDB = $DIC->database();
2022 
2023  $res = array();
2024 
2025  $set = $ilDB->query("SELECT id,fb_file,time_stamp,deadline2,fb_date FROM exc_assignment" .
2026  " WHERE fb_cron = " . $ilDB->quote(1, "integer") .
2027  " AND (fb_date = " . $ilDB->quote(self::FEEDBACK_DATE_DEADLINE, "integer") .
2028  " AND time_stamp IS NOT NULL" .
2029  " AND time_stamp > " . $ilDB->quote(0, "integer") .
2030  " AND time_stamp < " . $ilDB->quote(time(), "integer") .
2031  " AND fb_cron_done = " . $ilDB->quote(0, "integer") .
2032  ") OR (fb_date = " . $ilDB->quote(self::FEEDBACK_DATE_CUSTOM, "integer") .
2033  " AND fb_date_custom IS NOT NULL" .
2034  " AND fb_date_custom > " . $ilDB->quote(0, "integer") .
2035  " AND fb_date_custom < " . $ilDB->quote(time(), "integer") .
2036  " AND fb_cron_done = " . $ilDB->quote(0, "integer") . ")");
2037 
2038 
2039 
2040  while ($row = $ilDB->fetchAssoc($set)) {
2041  if ($row['fb_date'] == self::FEEDBACK_DATE_DEADLINE) {
2042  $max = max($row['time_stamp'], $row['deadline2']);
2043  if (trim($row["fb_file"]) && $max <= time()) {
2044  $res[] = $row["id"];
2045  }
2046  } elseif ($row['fb_date'] == self::FEEDBACK_DATE_CUSTOM) {
2047  if (trim($row["fb_file"]) && $row['fb_date_custom'] <= time()) {
2048  $res[] = $row["id"];
2049  }
2050  }
2051  }
2052 
2053  return $res;
2054  }
2055 
2056  public static function sendFeedbackNotifications($a_ass_id, $a_user_id = null)
2057  {
2058  global $DIC;
2059 
2060  $ilDB = $DIC->database();
2061 
2062  $ass = new self($a_ass_id);
2063 
2064  // valid assignment?
2065  if (!$ass->hasFeedbackCron() || !$ass->getFeedbackFile()) {
2066  return false;
2067  }
2068 
2069  if (!$a_user_id) {
2070  // already done?
2071  $set = $ilDB->query("SELECT fb_cron_done" .
2072  " FROM exc_assignment" .
2073  " WHERE id = " . $ilDB->quote($a_ass_id, "integer"));
2074  $row = $ilDB->fetchAssoc($set);
2075  if ($row["fb_cron_done"]) {
2076  return false;
2077  }
2078  }
2079 
2080  $ntf = new ilSystemNotification();
2081  $ntf->setLangModules(array("exc"));
2082  $ntf->setObjId($ass->getExerciseId());
2083  $ntf->setSubjectLangId("exc_feedback_notification_subject");
2084  $ntf->setIntroductionLangId("exc_feedback_notification_body");
2085  $ntf->addAdditionalInfo("exc_assignment", $ass->getTitle());
2086  $ntf->setGotoLangId("exc_feedback_notification_link");
2087  $ntf->setReasonLangId("exc_feedback_notification_reason");
2088 
2089  if (!$a_user_id) {
2090  $ntf->sendMail(ilExerciseMembers::_getMembers($ass->getExerciseId()));
2091 
2092  $ilDB->manipulate("UPDATE exc_assignment" .
2093  " SET fb_cron_done = " . $ilDB->quote(1, "integer") .
2094  " WHERE id = " . $ilDB->quote($a_ass_id, "integer"));
2095  } else {
2096  $ntf->sendMail(array($a_user_id));
2097  }
2098 
2099  return true;
2100  }
2101 
2102 
2103  // status
2104 
2105  public function afterDeadline() // like: after effective deadline (for single user), no deadline: true
2106  {
2107  $ilUser = $this->user;
2108 
2109  // :TODO: always current user?
2110  $idl = $this->getPersonalDeadline($ilUser->getId()); // official deadline
2111 
2112  // no deadline === true
2113  $deadline = max($this->deadline, $this->deadline2, $idl); // includes grace period
2114  return ($deadline - time() <= 0);
2115  }
2116 
2117  public function afterDeadlineStrict($a_include_personal = true)
2118  {
2119  // :TODO: this means that peer feedback, global feedback is available
2120  // after LAST personal deadline
2121  // team management is currently ignoring personal deadlines
2122  $idl = (bool) $a_include_personal
2123  ? $this->getLastPersonalDeadline()
2124  : null;
2125 
2126  // no deadline === false
2127  $deadline = max($this->deadline, $this->deadline2, $idl);
2128 
2129  // #18271 - afterDeadline() does not handle last personal deadline
2130  if ($idl && $deadline == $idl) { // after effective deadline of all users
2131  return ($deadline - time() <= 0);
2132  }
2133 
2134  return ($deadline > 0 && // like: after effective deadline (for single user), except: no deadline false
2135  $this->afterDeadline());
2136  }
2137 
2141  public function afterCustomDate()
2142  {
2143  $date_custom = $this->getFeedbackDateCustom();
2144  //if the solution will be displayed only after reach all the deadlines.
2145  //$final_deadline = $this->afterDeadlineStrict();
2146  //$dl = max($final_deadline, time());
2147  //return ($date_custom - $dl <= 0);
2148  return ($date_custom - time() <= 0);
2149  }
2150 
2151  public function beforeDeadline() // like: before effective deadline (for all users), no deadline: true
2152  {
2153  // no deadline === true
2154  return !$this->afterDeadlineStrict();
2155  }
2156 
2157  public function notStartedYet()
2158  {
2159  return (time() - $this->start_time <= 0);
2160  }
2161 
2162 
2163  //
2164  // FEEDBACK FILES
2165  //
2166 
2168  {
2169  $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
2170  return $storage->getGlobalFeedbackPath();
2171  }
2172 
2173  public function deleteGlobalFeedbackFile()
2174  {
2176  }
2177 
2178  public function handleGlobalFeedbackFileUpload(array $a_file)
2179  {
2180  $path = $this->getGlobalFeedbackFileStoragePath();
2181  ilUtil::delDir($path, true);
2182  if (ilUtil::moveUploadedFile($a_file["tmp_name"], $a_file["name"], $path . "/" . $a_file["name"])) {
2183  $this->setFeedbackFile($a_file["name"]);
2184  return true;
2185  }
2186  return false;
2187  }
2188 
2189  public function getGlobalFeedbackFilePath()
2190  {
2191  $file = $this->getFeedbackFile();
2192  if ($file) {
2193  $path = $this->getGlobalFeedbackFileStoragePath();
2194  return $path . "/" . $file;
2195  }
2196  }
2197 
2202  public function getMemberStatus($a_user_id = null)
2203  {
2204  $ilUser = $this->user;
2205 
2206  if (!$a_user_id) {
2207  $a_user_id = $ilUser->getId();
2208  }
2209  if (!array_key_exists($a_user_id, $this->member_status)) {
2210  $this->member_status[$a_user_id] = new ilExAssignmentMemberStatus($this->getId(), $a_user_id);
2211  }
2212  return $this->member_status[$a_user_id];
2213  }
2214 
2215  public function recalculateLateSubmissions()
2216  {
2217  $ilDB = $this->db;
2218 
2219  // see JF, 2015-05-11
2220 
2221  $ext_deadline = $this->getExtendedDeadline();
2222 
2223  foreach (ilExSubmission::getAllAssignmentFiles($this->exc_id, $this->getId()) as $file) {
2224  $id = $file["returned_id"];
2225  $uploaded = new ilDateTime($file["ts"], IL_CAL_DATETIME);
2226  $uploaded = $uploaded->get(IL_CAL_UNIX);
2227 
2228  $deadline = $this->getPersonalDeadline($file["user_id"]);
2229  $last_deadline = max($deadline, $this->getExtendedDeadline());
2230 
2231  $late = null;
2232 
2233  // upload is not late anymore
2234  if ($file["late"] &&
2235  (!$last_deadline ||
2236  !$ext_deadline ||
2237  $uploaded < $deadline)) {
2238  $late = false;
2239  }
2240  // upload is now late
2241  elseif (!$file["late"] &&
2242  $ext_deadline &&
2243  $deadline &&
2244  $uploaded > $deadline) {
2245  $late = true;
2246  } elseif ($last_deadline && $uploaded > $last_deadline) {
2247  // do nothing, we do not remove submissions?
2248  }
2249 
2250  if ($late !== null) {
2251  $ilDB->manipulate("UPDATE exc_returned" .
2252  " SET late = " . $ilDB->quote($late, "integer") .
2253  " WHERE returned_id = " . $ilDB->quote($id, "integer"));
2254  }
2255  }
2256  }
2257 
2258 
2259  //
2260  // individual deadlines
2261  //
2262 
2263  public function setIndividualDeadline($id, ilDateTime $date)
2264  {
2265  $ilDB = $this->db;
2266 
2267  $is_team = false;
2268  if (!is_numeric($id)) {
2269  $id = substr($id, 1);
2270  $is_team = true;
2271  }
2272 
2273  $idl = ilExcIndividualDeadline::getInstance($this->getId(), $id, $is_team);
2274  $idl->setIndividualDeadline($date->get(IL_CAL_UNIX));
2275  $idl->save();
2276 
2277  /*
2278  $ilDB->replace("exc_idl",
2279  array(
2280  "ass_id" => array("integer", $this->getId()),
2281  "member_id" => array("integer", $id),
2282  "is_team" => array("integer", $is_team)
2283  ),
2284  array(
2285  "tstamp" => array("integer", $date->get(IL_CAL_UNIX))
2286  )
2287  );*/
2288  }
2289 
2290  public function getIndividualDeadlines()
2291  {
2292  $ilDB = $this->db;
2293 
2294  $res = array();
2295 
2296  $set = $ilDB->query("SELECT * FROM exc_idl" .
2297  " WHERE ass_id = " . $ilDB->quote($this->getId(), "integer"));
2298  while ($row = $ilDB->fetchAssoc($set)) {
2299  if ($row["is_team"]) {
2300  $row["member_id"] = "t" . $row["member_id"];
2301  }
2302 
2303  $res[$row["member_id"]] = $row["tstamp"];
2304  }
2305 
2306  return $res;
2307  }
2308 
2309  public function hasActiveIDl()
2310  {
2311  return (bool) $this->getDeadline() || (bool) $this->getRelativeDeadline();
2312  }
2313 
2314  public function hasReadOnlyIDl()
2315  {
2316  if (!$this->ass_type->usesTeams() &&
2317  $this->getPeerReview()) {
2318  // all deadlines are read-only if we have peer feedback
2319  $peer_review = new ilExPeerReview($this);
2320  if ($peer_review->hasPeerReviewGroups()) {
2321  return true;
2322  }
2323  }
2324 
2325  return false;
2326  }
2327 
2333  public static function saveInstructionFilesOrderOfAssignment($a_ass_id, $a_order)
2334  {
2335  global $DIC;
2336 
2337  $db = $DIC->database();
2338 
2339  asort($a_order, SORT_NUMERIC);
2340 
2341  $nr = 10;
2342  foreach ($a_order as $k => $v) {
2343  // the check for exc_id is for security reasons. ass ids are unique.
2344  $db->manipulate(
2345  $t = "UPDATE exc_ass_file_order SET " .
2346  " order_nr = " . $db->quote($nr, "integer") .
2347  " WHERE id = " . $db->quote((int) $k, "integer") .
2348  " AND assignment_id = " . $db->quote((int) $a_ass_id, "integer")
2349  );
2350  $nr += 10;
2351  }
2352  }
2353 
2354  public static function insertFileOrderNr(int $a_ass_id, string $a_filename, int $a_order_nr)
2355  {
2356  global $DIC;
2357  $db = $DIC->database();
2358  $id = $db->nextId("exc_ass_file_order");
2359  $db->insert(
2360  "exc_ass_file_order",
2361  [
2362  "id" => ["integer", $id],
2363  "order_nr" => ["integer", $a_order_nr],
2364  "assignment_id" => ["integer", $a_ass_id],
2365  "filename" => ["text", $a_filename]
2366  ]
2367  );
2368  }
2369 
2375  public static function instructionFileInsertOrder($a_filename, $a_ass_id, $a_order_nr = 0)
2376  {
2377  global $DIC;
2378 
2379  $db = $DIC->database();
2380 
2381  $order = 0;
2382  $order_val = 0;
2383 
2384  if ($a_ass_id) {
2385  //first of all check the suffix and change if necessary
2386  $filename = ilUtil::getSafeFilename($a_filename);
2387 
2388  if (!self::instructionFileExistsInDb($filename, $a_ass_id)) {
2389  if ($a_order_nr == 0) {
2390  $order_val = self::instructionFileOrderGetMax($a_ass_id);
2391  $order = $order_val + 10;
2392  } else {
2393  $order = $a_order_nr;
2394  }
2395 
2396  $id = $db->nextID('exc_ass_file_order');
2397  $db->manipulate("INSERT INTO exc_ass_file_order " .
2398  "(id, assignment_id, filename, order_nr) VALUES (" .
2399  $db->quote($id, "integer") . "," .
2400  $db->quote($a_ass_id, "integer") . "," .
2401  $db->quote($filename, "text") . "," .
2402  $db->quote($order, "integer") .
2403  ")");
2404  }
2405  }
2406  }
2407 
2408  public static function instructionFileDeleteOrder($a_ass_id, $a_file)
2409  {
2410  global $DIC;
2411 
2412  $db = $DIC->database();
2413 
2414  //now its done by filename. We need to figure how to get the order id in the confirmdelete method
2415  foreach ($a_file as $k => $v) {
2416  $db->manipulate(
2417  "DELETE FROM exc_ass_file_order " .
2418  //"WHERE id = " . $ilDB->quote((int)$k, "integer") .
2419  "WHERE filename = " . $db->quote($v, "string") .
2420  " AND assignment_id = " . $db->quote($a_ass_id, 'integer')
2421  );
2422  }
2423  }
2424 
2430  public static function renameInstructionFile($a_old_name, $a_new_name, $a_ass_id)
2431  {
2432  global $DIC;
2433 
2434  $db = $DIC->database();
2435 
2436  if ($a_ass_id) {
2437  $db->manipulate(
2438  "DELETE FROM exc_ass_file_order" .
2439  " WHERE assignment_id = " . $db->quote((int) $a_ass_id, 'integer') .
2440  " AND filename = " . $db->quote($a_new_name, 'string')
2441  );
2442 
2443  $db->manipulate(
2444  "UPDATE exc_ass_file_order SET" .
2445  " filename = " . $db->quote($a_new_name, 'string') .
2446  " WHERE assignment_id = " . $db->quote((int) $a_ass_id, 'integer') .
2447  " AND filename = " . $db->quote($a_old_name, 'string')
2448  );
2449  }
2450  }
2451 
2457  public static function instructionFileExistsInDb($a_filename, $a_ass_id)
2458  {
2459  global $DIC;
2460 
2461  $db = $DIC->database();
2462 
2463  if ($a_ass_id) {
2464  $result = $db->query(
2465  "SELECT id FROM exc_ass_file_order" .
2466  " WHERE assignment_id = " . $db->quote((int) $a_ass_id, 'integer') .
2467  " AND filename = " . $db->quote($a_filename, 'string')
2468  );
2469 
2470  return $db->numRows($result);
2471  }
2472  }
2473 
2474  public function fixInstructionFileOrdering()
2475  {
2476  global $DIC;
2477 
2478  $db = $DIC->database();
2479 
2480  $files = array_map(function ($v) {
2481  return $v["name"];
2482  }, $this->getFiles());
2483 
2484  $set = $db->query("SELECT * FROM exc_ass_file_order " .
2485  " WHERE assignment_id = " . $db->quote($this->getId(), "integer") .
2486  " ORDER BY order_nr");
2487  $order_nr = 10;
2488  $numbered_files = array();
2489  while ($rec = $db->fetchAssoc($set)) {
2490  // file exists, set correct order nr
2491  if (in_array($rec["filename"], $files)) {
2492  $db->manipulate(
2493  "UPDATE exc_ass_file_order SET " .
2494  " order_nr = " . $db->quote($order_nr, "integer") .
2495  " WHERE assignment_id = " . $db->quote($this->getId(), "integer") .
2496  " AND id = " . $db->quote($rec["id"], "integer")
2497  );
2498  $order_nr += 10;
2499  $numbered_files[] = $rec["filename"];
2500  } else { // file does not exist, delete entry
2501  $db->manipulate(
2502  "DELETE FROM exc_ass_file_order " .
2503  " WHERE assignment_id = " . $db->quote($this->getId(), "integer") .
2504  " AND id = " . $db->quote($rec["id"], "integer")
2505  );
2506  }
2507  }
2508  foreach ($files as $f) {
2509  if (!in_array($f, $numbered_files)) {
2510  self::instructionFileInsertOrder($f, $this->getId());
2511  }
2512  }
2513  }
2514 
2520  public function fileAddOrder($a_entries = array())
2521  {
2522  $this->fixInstructionFileOrdering();
2523 
2524  $order = $this->getInstructionFilesOrder();
2525  foreach ($a_entries as $k => $e) {
2526  $a_entries[$k]["order_val"] = $order[$e["file"]]["order_nr"];
2527  $a_entries[$k]["order_id"] = $order[$e["file"]]["id"];
2528  }
2529 
2530  return $a_entries;
2531  }
2532 
2537  public static function instructionFileOrderGetMax($a_ass_id)
2538  {
2539  global $DIC;
2540 
2541  $db = $DIC->database();
2542 
2543  //get max order number
2544  $result = $db->queryF(
2545  "SELECT max(order_nr) as max_order FROM exc_ass_file_order WHERE assignment_id = %s",
2546  array('integer'),
2547  array($db->quote($a_ass_id, 'integer'))
2548  );
2549 
2550  while ($row = $db->fetchAssoc($result)) {
2551  $order_val = (int) $row['max_order'];
2552  }
2553  return $order_val;
2554  }
2555 
2556 
2562  public function setMinCharLimit($a_val)
2563  {
2564  $this->min_char_limit = $a_val;
2565  }
2566 
2572  public function getMinCharLimit()
2573  {
2574  return $this->min_char_limit;
2575  }
2576 
2581  public function setMaxCharLimit($a_val)
2582  {
2583  $this->max_char_limit = $a_val;
2584  }
2585 
2590  public function getMaxCharLimit()
2591  {
2592  return $this->max_char_limit;
2593  }
2594 
2602  public function getCalculatedDeadlines()
2603  {
2604  $calculated_deadlines = array(
2605  "user" => array(),
2606  "team" => array()
2607  );
2608 
2609  if ($this->getRelativeDeadline() && $this->getDeadlineMode() == self::DEADLINE_RELATIVE) {
2610  foreach (ilExcIndividualDeadline::getStartingTimestamps($this->getId()) as $ts) {
2611  $type = $ts["is_team"]
2612  ? "team"
2613  : "user";
2614 
2615  $calculated_deadlines[$type][$ts["member_id"]] = array(
2616  "calculated_deadline" => $ts["starting_ts"] + ($this->getRelativeDeadline() * 24 * 60 * 60)
2617  );
2618  }
2619  }
2620  return $calculated_deadlines;
2621  }
2622 
2623  // see bug #36253
2624  public function canParticipantReceiveFeedback($part_id) : bool
2625  {
2626  if ($this->hasTeam()) {
2627  if (!ilExAssignmentTeam::getTeamId($this->getId(), $part_id)) {
2628  return false;
2629  }
2630  }
2631  return true;
2632  }
2633 }
getPortfolioTemplateId()
Get portfolio template id.
getLastPersonalDeadline()
Get last/final personal deadline (of assignment)
getPeerReview()
Get peer review status.
static getInstanceByType($a_type)
$app
Definition: cli.php:38
fileAddOrder($a_entries=array())
static _lookupName($a_user_id)
lookup user name
Exercise assignment member status.
setReminderStatus($a_status)
Set reminder for users without submission.
static getSafeFilename($a_initial_filename)
getMemberStatus($a_user_id=null)
getPersonalDeadline($a_user_id)
Get individual deadline (max of common or idl (team) deadline = Official Deadline) ...
saveMultiFeedbackFiles($a_files, ilObjExercise $a_exc)
Save multi feedback files.
static getAssignmentDataOfExercise($a_exc_id)
Get assignments data of an exercise in an array.
Exercise assignment.
static countMandatory($a_ex_id)
Count the number of mandatory assignments.
getInstructionPresentation()
Get instruction presentation.
static sendFeedbackNotifications($a_ass_id, $a_user_id=null)
$data
Definition: storeScorm.php:23
const IL_CAL_DATETIME
getMemberListData()
get member list data
Class ilExerciseMembers.
$result
setMaxFile($a_value)
Set max number of uploads.
getFeedbackDate()
Get (global) feedback file availability date.
setFeedbackFile($a_value)
Set (global) feedback file.
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
setPeerReviewMin($a_value)
Set peer review minimum.
setMaxCharLimit($a_val)
Set limit maximum characters.
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data
const IL_CAL_TRANSLATION_SYSTEM
static getTeamId($a_assignment_id, $a_user_id, $a_create_on_demand=false)
Get team id for member id.
static getPendingFeedbackNotifications()
setTeamTutor($a_value)
Set team management by tutor.
setPortfolioTemplateId($a_val)
Set portfolio template id.
sendMultiFeedbackStructureFile(ilObjExercise $exercise)
Create member status record for a new assignment for all participants.
setPeerReviewFileUpload($a_val)
Set peer review file upload.
static instructionFileInsertOrder($a_filename, $a_ass_id, $a_order_nr=0)
Store the file order in the database.
getStartTime()
Get start time (timestamp)
getId()
Get assignment id.
static instructionFileOrderGetMax($a_ass_id)
static count($a_ex_id)
Order assignments by deadline date.
initFromDB(array $a_set)
Import DB record.
setMinCharLimit($a_val)
Set limit minimum characters.
getMaxCharLimit()
get limit maximum characters return int max limit
setPeerReview($a_value)
Toggle peer review.
setPeerReviewDeadline($a_val)
Set peer review deadline (timestamp)
getDeadline()
Get deadline (timestamp)
save()
Save assignment.
hasPeerReviewRating()
Get peer review rating status.
static getDir($a_dir, $a_rec=false, $a_sub_dir="")
get directory
hasFeedbackCron()
Get (global) feedback file cron status.
setPeerReviewValid($a_value)
Set peer review validation.
setType($a_value)
Set type.
Apointment templates are used for automatic generated apointments.
setTitle($a_val)
Set title.
const IL_CAL_UNIX
setOrderNr($a_val)
Set order nr.
static lookup($a_id, $a_field)
Private lookup.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
setRelativeDeadline($a_val)
Set relative deadline.
setInstruction($a_val)
Set instruction.
user()
Definition: user.php:4
handleCalendarEntries($a_event)
Handle calendar entries for deadline(s)
getTeamTutor()
Get team management by tutor.
setDeadlineMode($a_val)
Set deadline mode.
uploadMultiFeedbackFile($a_file)
Upload multi feedback file.
if($format !==null) $name
Definition: metadata.php:230
static lookupAssignmentOnline($a_ass_id)
Check if assignment is online.
setStartTime($a_val)
Set start time (timestamp)
Exercise peer review.
getExerciseId()
Get exercise id.
getPeerReviewValid()
Get peer review validatiob.
Class ilObjExercise.
setDeadline($a_val)
Set deadline (timestamp)
foreach($_POST as $key=> $value) $res
static saveAssOrderOfExercise($a_ex_id, $a_order)
Save ordering of all assignments of an exercise.
hasPeerReviewPersonalized()
Get peer review personalized status.
getId()
get object id public
static getInstancesByParentId($a_parent_id)
setPeerReviewCriteriaCatalogue($a_value)
Set peer review criteria catalogue id.
static lookupUpdatedSubmission($ass_id, $member_id)
Check whether student has upload new files after tutor has set the exercise to another than notgraded...
setPeerReviewPersonalized($a_val)
Set peer review personalized.
getCalculatedDeadlines()
Get calculated deadlines for user/team members.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
setPeerReviewRating($a_val)
Set peer review rating.
TODO: import/export reminder data with the exercise/assignment.
static getInstance()
Get instance.
static makeClickable($a_text, $detectGotoLinks=false)
makeClickable In Texten enthaltene URLs und Mail-Adressen klickbar machen
static getInstance($a_ass_id, $a_participant_id, $a_is_team=false)
Get instance.
static getInstancesByExercise($a_exc_id)
uploadAssignmentFiles($a_files)
Upload assignment files (from creation form)
global $DIC
Definition: goto.php:24
setPeerReviewSimpleUnlock($a_value)
Set peer review simple unlock.
hasPeerReviewText()
Get peer review text status.
static instructionFileGetFileOrderData($a_file_data, $a_ass_id)
static instructionFileExistsInDb($a_filename, $a_ass_id)
setPeerReviewText($a_val)
Set peer review text.
static unzip(string $path_to_zip_file, bool $overwrite_existing=false, bool $unpack_flat=false)
handleGlobalFeedbackFileUpload(array $a_file)
$query
setExerciseId($a_val)
Set exercise id.
getFeedbackFile()
Get (global) feedback file.
getDeadlineMode()
Get deadline mode.
get($a_format, $a_format_str='', $a_tz='')
get formatted date
static zip($a_dir, $a_file, $compress_content=false)
zips given directory/file into given zip.file
getMandatory()
Get mandatory.
getPeerReviewMin()
Get peer review minimum.
$filename
Definition: buildRTE.php:89
getExtendedDeadline()
Get extended deadline (timestamp)
sendFeedbackFileNotification($a_feedback_file, $a_user_id, $a_ass_id, $a_is_text_feedback=false)
Send feedback file notification to user.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static cloneAssignmentsOfExercise($a_old_exc_id, $a_new_exc_id, array $a_crit_cat_map)
Clone assignments of exercise.
getExerciseMemberAssignmentData($a_user_id, $a_grade="")
Get submission data for an specific user,exercise and assignment.
static insertFileOrderNr(int $a_ass_id, string $a_filename, int $a_order_nr)
setFeedbackCron($a_value)
Toggle (global) feedback file cron.
static ilTempnam($a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
afterDeadlineStrict($a_include_personal=true)
getRelDeadlineLastSubmission()
Get relative deadline last submission.
static isInExercise($a_ass_id, $a_ex_id)
Is assignment in exercise?
static lookupType($a_id)
Lookup type.
static saveInstructionFilesOrderOfAssignment($a_ass_id, $a_order)
Save ordering of instruction files for an assignment.
clearMultiFeedbackDirectory()
Clear multi feedback directory.
setFeedbackDate($a_value)
Set (global) feedback file availability date.
static lookupMaxOrderNrForEx($a_exc_id)
Select the maximum order nr for an exercise.
getMultiFeedbackFiles($a_user_id=0)
Get multi feedback files (of uploader)
getInstruction()
Get instruction.
getPeerReviewSimpleUnlock()
Get peer review simple unlock.
static getStartingTimestamps($a_ass_id)
Get starting timestamp data for an assignment.
global $ilDB
setPeerReviewChars($a_value)
Set peer review minimum characters.
getRefId()
get reference id public
setId($a_val)
Set assignment id.
getPeerReviewDeadline()
Get peer review deadline (timestamp)
getFeedbackDateCustom()
Get feedback file availability using custom date.
Exercise submission //TODO: This class has to much static methods related to delivered "files"...
getMinCharLimit()
Get limit minimum characters.
hasPeerReviewFileUpload()
Get peer review file upload status.
static lookupExerciseId($a_ass_id)
Lookup excercise id for assignment id.
static getLogger($a_component_id)
Get component logger.
setFeedbackDateCustom($a_value)
Set (global) feedback file availability using a custom date.
getPeerReviewChars()
Get peer review minimum characters.
static getAllAssignmentFiles($a_exc_id, $a_ass_id)
$ilUser
Definition: imgupload.php:18
getMaxFile()
Get max number of uploads.
getAssignmentType()
Get assignment type.
static createNewUserRecords($a_user_id, $a_exc_id)
Create member status record for a new participant for all assignments.
setMandatory($a_val)
Set mandatory.
static orderAssByDeadline($a_ex_id)
Order assignments by deadline date.
setIndividualDeadline($id, ilDateTime $date)
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
getPeerReviewCriteriaCatalogue()
Get peer review criteria catalogue id.
canParticipantReceiveFeedback($part_id)
read()
Read from db.
Wrapper classes for system notifications.
setExtendedDeadline($a_val)
Set extended deadline (timestamp)
static renameInstructionFile($a_old_name, $a_new_name, $a_ass_id)
static instructionFileDeleteOrder($a_ass_id, $a_file)
setRelDeadlineLastSubmission($a_val)
Set relative deadline last submission.
static _getMembers($a_obj_id)
isValidType($a_value)
Is given type valid?
static createNewAssignmentRecords($a_ass_id, $a_exc)
Create member status record for a new assignment for all participants.
__construct($a_id=0)
Constructor.
for($i=6; $i< 13; $i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
static lookupTitle($a_id)
Lookup title.
getOrderNr()
Get order nr.
static deliverFile( $a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
$i
Definition: metadata.php:24
getRelativeDeadline()
Get relative deadline.
Exercise exceptions class.