ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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
12{
16 protected $db;
17
21 protected $lng;
22
26 protected $user;
27
32
33 const TYPE_UPLOAD = 1;
34 const TYPE_BLOG = 2;
35 const TYPE_PORTFOLIO = 3;
37 const TYPE_TEXT = 5;
38
41
45
46 protected $id;
47 protected $exc_id;
48 protected $type;
49 protected $start_time;
50 protected $deadline;
51 protected $deadline2;
52 protected $instruction;
53 protected $title;
54 protected $mandatory;
55 protected $order_nr;
56 protected $peer;
57 protected $peer_min;
58 protected $peer_unlock;
59 protected $peer_dl;
60 protected $peer_valid;
61 protected $peer_file;
62 protected $peer_personal;
63 protected $peer_char;
64 protected $peer_text;
65 protected $peer_rating;
66 protected $peer_crit_cat;
67 protected $feedback_file;
68 protected $feedback_cron;
69 protected $feedback_date;
70 protected $team_tutor = false;
71 protected $max_file;
73 protected $min_char_limit;
74 protected $max_char_limit;
75
76 protected $member_status = array(); // [array]
77
78 protected $log;
79
83 public function __construct($a_id = 0)
84 {
85 global $DIC;
86
87 $this->db = $DIC->database();
88 $this->lng = $DIC->language();
89 $this->user = $DIC->user();
90 $this->app_event_handler = $DIC["ilAppEventHandler"];
91 $this->setType(self::TYPE_UPLOAD);
92 $this->setFeedbackDate(self::FEEDBACK_DATE_DEADLINE);
93
94 $this->log = ilLoggerFactory::getLogger("exc");
95
96 if ($a_id > 0) {
97 $this->setId($a_id);
98 $this->read();
99 }
100 }
101
102 public static function getInstancesByExercise($a_exc_id)
103 {
104 global $DIC;
105
106 $ilDB = $DIC->database();
107
108 $set = $ilDB->query("SELECT * FROM exc_assignment " .
109 " WHERE exc_id = " . $ilDB->quote($a_exc_id, "integer") .
110 " ORDER BY order_nr ASC");
111 $data = array();
112
113 $order_val = 10;
114 while ($rec = $ilDB->fetchAssoc($set)) {
115 // ???
116 $rec["order_val"] = $order_val;
117
118 $ass = new self();
119 $ass->initFromDB($rec);
120 $data[] = $ass;
121
122 $order_val += 10;
123 }
124
125 return $data;
126 }
127
133 public static function instructionFileGetFileOrderData($a_file_data, $a_ass_id)
134 {
135 global $DIC;
136
137 $db = $DIC->database();
138 $db->setLimit(1, 0);
139
140 $result_order_val = $db->query("
141 SELECT id, order_nr
142 FROM exc_ass_file_order
143 WHERE assignment_id = {$db->quote($a_ass_id, 'integer')}
144 AND filename = {$db->quote($a_file_data['entry'], 'string')}
145 ");
146
147 $order_val = 0;
148 $order_id = 0;
149 while ($row = $db->fetchAssoc($result_order_val)) {
150 $order_val = (int) $row['order_nr'];
151 $order_id = (int) $row['id'];
152 }
153 return array($order_val, $order_id);
154 }
155
156 public function hasTeam()
157 {
158 return $this->type == self::TYPE_UPLOAD_TEAM;
159 }
160
166 public function setId($a_val)
167 {
168 $this->id = $a_val;
169 }
170
176 public function getId()
177 {
178 return $this->id;
179 }
180
186 public function setExerciseId($a_val)
187 {
188 $this->exc_id = $a_val;
189 }
190
196 public function getExerciseId()
197 {
198 return $this->exc_id;
199 }
200
206 public function setStartTime($a_val)
207 {
208 $this->start_time = $a_val;
209 }
210
216 public function getStartTime()
217 {
218 return $this->start_time;
219 }
220
226 public function setDeadline($a_val)
227 {
228 $this->deadline = $a_val;
229 }
230
236 public function getDeadline()
237 {
238 return $this->deadline;
239 }
240
246 public function getPersonalDeadline($a_user_id)
247 {
249
250 $is_team = false;
251 if ($this->getType() == self::TYPE_UPLOAD_TEAM) {
252 include_once("./Modules/Exercise/classes/class.ilExAssignmentTeam.php");
253 $team_id = ilExAssignmentTeam::getTeamId($this->getId(), $a_user_id);
254 if (!$team_id) {
255 // #0021043
256 $this->getDeadline();
257 }
258 $a_user_id = $team_id;
259 $is_team = true;
260 }
261
262 $set = $ilDB->query("SELECT tstamp FROM exc_idl" .
263 " WHERE ass_id = " . $ilDB->quote($this->getId(), "integer") .
264 " AND member_id = " . $ilDB->quote($a_user_id, "integer") .
265 " AND is_team = " . $ilDB->quote($is_team, "integer"));
266 $row = $ilDB->fetchAssoc($set);
267
268 // use assignment deadline if no direct personal
269 return max($row["tstamp"], $this->getDeadline());
270 }
271
277 protected function getLastPersonalDeadline()
278 {
280
281 $set = $ilDB->query("SELECT MAX(tstamp) FROM exc_idl" .
282 " WHERE ass_id = " . $ilDB->quote($this->getId(), "integer"));
283 $row = $ilDB->fetchAssoc($set);
284 return $row["tstamp"];
285 }
286
292 public function setExtendedDeadline($a_val)
293 {
294 if ($a_val !== null) {
295 $a_val = (int) $a_val;
296 }
297 $this->deadline2 = $a_val;
298 }
299
305 public function getExtendedDeadline()
306 {
307 return $this->deadline2;
308 }
309
315 public function setInstruction($a_val)
316 {
317 $this->instruction = $a_val;
318 }
319
325 public function getInstruction()
326 {
327 return $this->instruction;
328 }
329
335 public function setTitle($a_val)
336 {
337 $this->title = $a_val;
338 }
339
345 public function getTitle()
346 {
347 return $this->title;
348 }
349
355 public function setMandatory($a_val)
356 {
357 $this->mandatory = $a_val;
358 }
359
365 public function getMandatory()
366 {
367 return $this->mandatory;
368 }
369
375 public function setOrderNr($a_val)
376 {
377 $this->order_nr = $a_val;
378 }
379
385 public function getOrderNr()
386 {
387 return $this->order_nr;
388 }
389
395 public function setType($a_value)
396 {
397 if ($this->isValidType($a_value)) {
398 $this->type = (int) $a_value;
399
400 if ($this->type == self::TYPE_UPLOAD_TEAM) {
401 $this->setPeerReview(false);
402 }
403 }
404 }
405
411 public function getType()
412 {
413 return $this->type;
414 }
415
422 public function isValidType($a_value)
423 {
424 if (in_array((int) $a_value, array(self::TYPE_UPLOAD, self::TYPE_BLOG,
425 self::TYPE_PORTFOLIO, self::TYPE_UPLOAD_TEAM, self::TYPE_TEXT))) {
426 return true;
427 }
428 return false;
429 }
430
436 public function setPeerReview($a_value)
437 {
438 $this->peer = (bool) $a_value;
439 }
440
446 public function getPeerReview()
447 {
448 return (bool) $this->peer;
449 }
450
456 public function setPeerReviewMin($a_value)
457 {
458 $this->peer_min = (int) $a_value;
459 }
460
466 public function getPeerReviewMin()
467 {
468 return (int) $this->peer_min;
469 }
470
476 public function setPeerReviewSimpleUnlock($a_value)
477 {
478 $this->peer_unlock = (bool) $a_value;
479 }
480
487 {
488 return (bool) $this->peer_unlock;
489 }
490
496 public function setPeerReviewDeadline($a_val)
497 {
498 $this->peer_dl = $a_val;
499 }
500
506 public function getPeerReviewDeadline()
507 {
508 return $this->peer_dl;
509 }
510
516 public function setPeerReviewValid($a_value)
517 {
518 $this->peer_valid = (int) $a_value;
519 }
520
526 public function getPeerReviewValid()
527 {
528 return (int) $this->peer_valid;
529 }
530
536 public function setPeerReviewRating($a_val)
537 {
538 $this->peer_rating = (bool) $a_val;
539 }
540
546 public function hasPeerReviewRating()
547 {
548 return $this->peer_rating;
549 }
550
556 public function setPeerReviewText($a_val)
557 {
558 $this->peer_text = (bool) $a_val;
559 }
560
566 public function hasPeerReviewText()
567 {
568 return $this->peer_text;
569 }
570
576 public function setPeerReviewFileUpload($a_val)
577 {
578 $this->peer_file = (bool) $a_val;
579 }
580
586 public function hasPeerReviewFileUpload()
587 {
588 return $this->peer_file;
589 }
590
596 public function setPeerReviewPersonalized($a_val)
597 {
598 $this->peer_personal = (bool) $a_val;
599 }
600
607 {
609 }
610
616 public function setPeerReviewChars($a_value)
617 {
618 $a_value = (is_numeric($a_value) && (int) $a_value > 0)
619 ? (int) $a_value
620 : null;
621 $this->peer_char = $a_value;
622 }
623
629 public function getPeerReviewChars()
630 {
631 return $this->peer_char;
632 }
633
639 public function setPeerReviewCriteriaCatalogue($a_value)
640 {
641 $a_value = is_numeric($a_value)
642 ? (int) $a_value
643 : null;
644 $this->crit_cat = $a_value;
645 }
646
653 {
654 return $this->crit_cat;
655 }
656
658 {
659 include_once "Modules/Exercise/classes/class.ilExcCriteria.php";
660
661 if ($this->crit_cat) {
662 return ilExcCriteria::getInstancesByParentId($this->crit_cat);
663 } else {
664 $res = array();
665
666 if ($this->peer_rating) {
668 }
669
670 if ($this->peer_text) {
671 $crit = ilExcCriteria::getInstanceByType("text");
672 if ($this->peer_char) {
673 $crit->setMinChars($this->peer_char);
674 }
675 $res[] = $crit;
676 }
677
678 if ($this->peer_file) {
680 }
681
682 return $res;
683 }
684 }
685
691 public function setFeedbackFile($a_value)
692 {
693 $this->feedback_file = (string) $a_value;
694 }
695
701 public function getFeedbackFile()
702 {
703 return (string) $this->feedback_file;
704 }
705
711 public function setFeedbackCron($a_value)
712 {
713 $this->feedback_cron = (string) $a_value;
714 }
715
721 public function hasFeedbackCron()
722 {
723 return (bool) $this->feedback_cron;
724 }
725
731 public function setFeedbackDate($a_value)
732 {
733 $this->feedback_date = (int) $a_value;
734 }
735
741 public function getFeedbackDate()
742 {
743 return (int) $this->feedback_date;
744 }
745
751 public function setTeamTutor($a_value)
752 {
753 $this->team_tutor = (bool) $a_value;
754 }
755
761 public function getTeamTutor()
762 {
763 return $this->team_tutor;
764 }
765
771 public function setMaxFile($a_value)
772 {
773 if ($a_value !== null) {
774 $a_value = (int) $a_value;
775 }
776 $this->max_file = $a_value;
777 }
778
784 public function getMaxFile()
785 {
786 return $this->max_file;
787 }
788
794 public function setPortfolioTemplateId($a_val)
795 {
796 $this->portfolio_template = $a_val;
797 }
798
804 public function getPortfolioTemplateId()
805 {
807 }
808
809
813 public function read()
814 {
816
817 $set = $ilDB->query(
818 "SELECT * FROM exc_assignment " .
819 " WHERE id = " . $ilDB->quote($this->getId(), "integer")
820 );
821 $rec = $ilDB->fetchAssoc($set);
822
823 // #16172 - might be deleted
824 if (is_array($rec)) {
825 $this->initFromDB($rec);
826 }
827 }
828
835 protected function initFromDB(array $a_set)
836 {
837 $this->setId($a_set["id"]);
838 $this->setExerciseId($a_set["exc_id"]);
839 $this->setDeadline($a_set["time_stamp"]);
840 $this->setExtendedDeadline($a_set["deadline2"]);
841 $this->setInstruction($a_set["instruction"]);
842 $this->setTitle($a_set["title"]);
843 $this->setStartTime($a_set["start_time"]);
844 $this->setOrderNr($a_set["order_nr"]);
845 $this->setMandatory($a_set["mandatory"]);
846 $this->setType($a_set["type"]);
847 $this->setPeerReview($a_set["peer"]);
848 $this->setPeerReviewMin($a_set["peer_min"]);
849 $this->setPeerReviewSimpleUnlock($a_set["peer_unlock"]);
850 $this->setPeerReviewDeadline($a_set["peer_dl"]);
851 $this->setPeerReviewValid($a_set["peer_valid"]);
852 $this->setPeerReviewFileUpload($a_set["peer_file"]);
853 $this->setPeerReviewPersonalized($a_set["peer_prsl"]);
854 $this->setPeerReviewChars($a_set["peer_char"]);
855 $this->setPeerReviewText($a_set["peer_text"]);
856 $this->setPeerReviewRating($a_set["peer_rating"]);
857 $this->setPeerReviewCriteriaCatalogue($a_set["peer_crit_cat"]);
858 $this->setFeedbackFile($a_set["fb_file"]);
859 $this->setFeedbackDate($a_set["fb_date"]);
860 $this->setFeedbackCron($a_set["fb_cron"]);
861 $this->setTeamTutor($a_set["team_tutor"]);
862 $this->setMaxFile($a_set["max_file"]);
863 $this->setPortfolioTemplateId($a_set["portfolio_template"]);
864 $this->setMinCharLimit($a_set["min_char_limit"]);
865 $this->setMaxCharLimit($a_set["max_char_limit"]);
866 }
867
871 public function save()
872 {
874
875 if ($this->getOrderNr() == 0) {
876 $this->setOrderNr(
877 self::lookupMaxOrderNrForEx($this->getExerciseId())
878 + 10
879 );
880 }
881
882 $next_id = $ilDB->nextId("exc_assignment");
883 $ilDB->insert("exc_assignment", array(
884 "id" => array("integer", $next_id),
885 "exc_id" => array("integer", $this->getExerciseId()),
886 "time_stamp" => array("integer", $this->getDeadline()),
887 "deadline2" => array("integer", $this->getExtendedDeadline()),
888 "instruction" => array("clob", $this->getInstruction()),
889 "title" => array("text", $this->getTitle()),
890 "start_time" => array("integer", $this->getStartTime()),
891 "order_nr" => array("integer", $this->getOrderNr()),
892 "mandatory" => array("integer", $this->getMandatory()),
893 "type" => array("integer", $this->getType()),
894 "peer" => array("integer", $this->getPeerReview()),
895 "peer_min" => array("integer", $this->getPeerReviewMin()),
896 "peer_unlock" => array("integer", $this->getPeerReviewSimpleUnlock()),
897 "peer_dl" => array("integer", $this->getPeerReviewDeadline()),
898 "peer_valid" => array("integer", $this->getPeerReviewValid()),
899 "peer_file" => array("integer", $this->hasPeerReviewFileUpload()),
900 "peer_prsl" => array("integer", $this->hasPeerReviewPersonalized()),
901 "peer_char" => array("integer", $this->getPeerReviewChars()),
902 "peer_text" => array("integer", (int) $this->hasPeerReviewText()),
903 "peer_rating" => array("integer", (int) $this->hasPeerReviewRating()),
904 "peer_crit_cat" => array("integer", $this->getPeerReviewCriteriaCatalogue()),
905 "fb_file" => array("text", $this->getFeedbackFile()),
906 "fb_date" => array("integer", $this->getFeedbackDate()),
907 "fb_cron" => array("integer", $this->hasFeedbackCron()),
908 "team_tutor" => array("integer", $this->getTeamTutor()),
909 "max_file" => array("integer", $this->getMaxFile()),
910 "portfolio_template" => array("integer", $this->getPortFolioTemplateId()),
911 "min_char_limit" => array("integer", $this->getMinCharLimit()),
912 "max_char_limit" => array("integer", $this->getMaxCharLimit())
913 ));
914 $this->setId($next_id);
915 $exc = new ilObjExercise($this->getExerciseId(), false);
916 $exc->updateAllUsersStatus();
917 self::createNewAssignmentRecords($next_id, $exc);
918
919 $this->handleCalendarEntries("create");
920 }
921
925 public function update()
926 {
928
929 $ilDB->update(
930 "exc_assignment",
931 array(
932 "exc_id" => array("integer", $this->getExerciseId()),
933 "time_stamp" => array("integer", $this->getDeadline()),
934 "deadline2" => array("integer", $this->getExtendedDeadline()),
935 "instruction" => array("clob", $this->getInstruction()),
936 "title" => array("text", $this->getTitle()),
937 "start_time" => array("integer", $this->getStartTime()),
938 "order_nr" => array("integer", $this->getOrderNr()),
939 "mandatory" => array("integer", $this->getMandatory()),
940 "type" => array("integer", $this->getType()),
941 "peer" => array("integer", $this->getPeerReview()),
942 "peer_min" => array("integer", $this->getPeerReviewMin()),
943 "peer_unlock" => array("integer", $this->getPeerReviewSimpleUnlock()),
944 "peer_dl" => array("integer", $this->getPeerReviewDeadline()),
945 "peer_valid" => array("integer", $this->getPeerReviewValid()),
946 "peer_file" => array("integer", $this->hasPeerReviewFileUpload()),
947 "peer_prsl" => array("integer", $this->hasPeerReviewPersonalized()),
948 "peer_char" => array("integer", $this->getPeerReviewChars()),
949 "peer_text" => array("integer", (int) $this->hasPeerReviewText()),
950 "peer_rating" => array("integer", (int) $this->hasPeerReviewRating()),
951 "peer_crit_cat" => array("integer", $this->getPeerReviewCriteriaCatalogue()),
952 "fb_file" => array("text", $this->getFeedbackFile()),
953 "fb_date" => array("integer", $this->getFeedbackDate()),
954 "fb_cron" => array("integer", $this->hasFeedbackCron()),
955 "team_tutor" => array("integer", $this->getTeamTutor()),
956 "max_file" => array("integer", $this->getMaxFile()),
957 "portfolio_template" => array("integer", $this->getPortFolioTemplateId()),
958 "min_char_limit" => array("integer", $this->getMinCharLimit()),
959 "max_char_limit" => array("integer", $this->getMaxCharLimit())
960 ),
961 array(
962 "id" => array("integer", $this->getId()),
963 )
964 );
965 $exc = new ilObjExercise($this->getExerciseId(), false);
966 $exc->updateAllUsersStatus();
967
968 $this->handleCalendarEntries("update");
969 }
970
974 public function delete()
975 {
977
979
980 $ilDB->manipulate(
981 "DELETE FROM exc_assignment WHERE " .
982 " id = " . $ilDB->quote($this->getId(), "integer")
983 );
984 $exc = new ilObjExercise($this->getExerciseId(), false);
985 $exc->updateAllUsersStatus();
986
987 $this->handleCalendarEntries("delete");
988 }
989
990
994 public static function getAssignmentDataOfExercise($a_exc_id)
995 {
996 global $DIC;
997
998 $ilDB = $DIC->database();
999
1000 // should be changed to self::getInstancesByExerciseId()
1001
1002 $set = $ilDB->query("SELECT * FROM exc_assignment " .
1003 " WHERE exc_id = " . $ilDB->quote($a_exc_id, "integer") .
1004 " ORDER BY order_nr ASC");
1005 $data = array();
1006
1007 $order_val = 10;
1008 while ($rec = $ilDB->fetchAssoc($set)) {
1009 $data[] = array(
1010 "id" => $rec["id"],
1011 "exc_id" => $rec["exc_id"],
1012 "deadline" => $rec["time_stamp"],
1013 "deadline2" => $rec["deadline2"],
1014 "instruction" => $rec["instruction"],
1015 "title" => $rec["title"],
1016 "start_time" => $rec["start_time"],
1017 "order_val" => $order_val,
1018 "mandatory" => $rec["mandatory"],
1019 "type" => $rec["type"],
1020 "peer" => $rec["peer"],
1021 "peer_min" => $rec["peer_min"],
1022 "peer_dl" => $rec["peer_dl"],
1023 "peer_file" => $rec["peer_file"],
1024 "peer_prsl" => $rec["peer_prsl"],
1025 "fb_file" => $rec["fb_file"],
1026 "fb_date" => $rec["fb_date"],
1027 "fb_cron" => $rec["fb_cron"],
1028 );
1029 $order_val += 10;
1030 }
1031 return $data;
1032 }
1033
1040 public static function cloneAssignmentsOfExercise($a_old_exc_id, $a_new_exc_id, array $a_crit_cat_map)
1041 {
1042 $ass_data = self::getInstancesByExercise($a_old_exc_id);
1043 foreach ($ass_data as $d) {
1044 // clone assignment
1045 $new_ass = new ilExAssignment();
1046 $new_ass->setExerciseId($a_new_exc_id);
1047 $new_ass->setTitle($d->getTitle());
1048 $new_ass->setDeadline($d->getDeadline());
1049 $new_ass->setExtendedDeadline($d->getExtendedDeadline());
1050 $new_ass->setInstruction($d->getInstruction());
1051 $new_ass->setMandatory($d->getMandatory());
1052 $new_ass->setOrderNr($d->getOrderNr());
1053 $new_ass->setStartTime($d->getStartTime());
1054 $new_ass->setType($d->getType());
1055 $new_ass->setPeerReview($d->getPeerReview());
1056 $new_ass->setPeerReviewMin($d->getPeerReviewMin());
1057 $new_ass->setPeerReviewDeadline($d->getPeerReviewDeadline());
1058 $new_ass->setPeerReviewFileUpload($d->hasPeerReviewFileUpload());
1059 $new_ass->setPeerReviewPersonalized($d->hasPeerReviewPersonalized());
1060 $new_ass->setPeerReviewValid($d->getPeerReviewValid());
1061 $new_ass->setPeerReviewChars($d->getPeerReviewChars());
1062 $new_ass->setPeerReviewText($d->hasPeerReviewText());
1063 $new_ass->setPeerReviewRating($d->hasPeerReviewRating());
1064 $new_ass->setPeerReviewCriteriaCatalogue($d->getPeerReviewCriteriaCatalogue());
1065 $new_ass->setPeerReviewSimpleUnlock($d->getPeerReviewSimpleUnlock());
1066 $new_ass->setFeedbackFile($d->getFeedbackFile());
1067 $new_ass->setFeedbackDate($d->getFeedbackDate());
1068 $new_ass->setFeedbackCron($d->hasFeedbackCron()); // #16295
1069 $new_ass->setTeamTutor($d->getTeamTutor());
1070 $new_ass->setMaxFile($d->getMaxFile());
1071 $new_ass->setMinCharLimit($d->getMinCharLimit());
1072 $new_ass->setMaxCharLimit($d->getMaxCharLimit());
1073 $new_ass->setPortfolioTemplateId($d->getPortfolioTemplateId());
1074
1075
1076 // criteria catalogue(s)
1077 if ($d->getPeerReviewCriteriaCatalogue() &&
1078 array_key_exists($d->getPeerReviewCriteriaCatalogue(), $a_crit_cat_map)) {
1079 $new_ass->setPeerReviewCriteriaCatalogue($a_crit_cat_map[$d->getPeerReviewCriteriaCatalogue()]);
1080 }
1081
1082 $new_ass->save();
1083
1084
1085 // clone assignment files
1086 include_once("./Modules/Exercise/classes/class.ilFSWebStorageExercise.php");
1087 $old_web_storage = new ilFSWebStorageExercise($a_old_exc_id, (int) $d->getId());
1088 $new_web_storage = new ilFSWebStorageExercise($a_new_exc_id, (int) $new_ass->getId());
1089 $new_web_storage->create();
1090 if (is_dir($old_web_storage->getPath())) {
1091 ilUtil::rCopy($old_web_storage->getPath(), $new_web_storage->getPath());
1092 }
1093
1094 // clone global feedback file
1095 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1096 $old_storage = new ilFSStorageExercise($a_old_exc_id, (int) $d->getId());
1097 $new_storage = new ilFSStorageExercise($a_new_exc_id, (int) $new_ass->getId());
1098 $new_storage->create();
1099 if (is_dir($old_storage->getGlobalFeedbackPath())) {
1100 ilUtil::rCopy($old_storage->getGlobalFeedbackPath(), $new_storage->getGlobalFeedbackPath());
1101 }
1102 }
1103 }
1104
1108 public function getFiles()
1109 {
1110 $this->log->debug("getting files from class.ilExAssignment using ilFSWebStorageExercise");
1111 include_once("./Modules/Exercise/classes/class.ilFSWebStorageExercise.php");
1112 $storage = new ilFSWebStorageExercise($this->getExerciseId(), $this->getId());
1113 return $storage->getFiles();
1114 }
1115
1121 {
1122 $ilDB = $this->db;
1123
1124 $set = $ilDB->query(
1125 "SELECT filename, order_nr, id FROM exc_ass_file_order " .
1126 " WHERE assignment_id = " . $ilDB->quote($this->getId(), "integer")
1127 );
1128
1129 $data = array();
1130 while ($rec = $ilDB->fetchAssoc($set)) {
1131 $data[$rec['filename']] = $rec;
1132 }
1133
1134 return $data;
1135 }
1136
1140 public static function lookupMaxOrderNrForEx($a_exc_id)
1141 {
1142 global $DIC;
1143
1144 $ilDB = $DIC->database();
1145
1146 $set = $ilDB->query(
1147 "SELECT MAX(order_nr) mnr FROM exc_assignment " .
1148 " WHERE exc_id = " . $ilDB->quote($a_exc_id, "integer")
1149 );
1150 while ($rec = $ilDB->fetchAssoc($set)) {
1151 return (int) $rec["mnr"];
1152 }
1153 return 0;
1154 }
1155
1161 public static function lookupAssignmentOnline($a_ass_id)
1162 {
1163 global $DIC;
1164
1165 $ilDB = $DIC->database();
1166
1167 $query = "SELECT id FROM exc_assignment " .
1168 "WHERE start_time <= " . $ilDB->quote(time(), 'integer') . ' ' .
1169 "AND time_stamp >= " . $ilDB->quote(time(), 'integer') . ' ' .
1170 "AND id = " . $ilDB->quote($a_ass_id, 'integer');
1171 $res = $ilDB->query($query);
1172
1173 return $res->numRows() ? true : false;
1174 }
1175
1182 public static function lookupExerciseId($a_ass_id)
1183 {
1184 global $DIC;
1185
1186 $ilDB = $DIC->database();
1187
1188 $query = "SELECT exc_id FROM exc_assignment " .
1189 "WHERE id = " . $ilDB->quote($a_ass_id, 'integer');
1190 $res = $ilDB->fetchAssoc($ilDB->query($query));
1191
1192 return (int) $res["exc_id"];
1193 }
1194
1198 private static function lookup($a_id, $a_field)
1199 {
1200 global $DIC;
1201
1202 $ilDB = $DIC->database();
1203
1204 $set = $ilDB->query(
1205 "SELECT " . $a_field . " FROM exc_assignment " .
1206 " WHERE id = " . $ilDB->quote($a_id, "integer")
1207 );
1208
1209 $rec = $ilDB->fetchAssoc($set);
1210
1211 return $rec[$a_field];
1212 }
1213
1217 public static function lookupTitle($a_id)
1218 {
1219 return self::lookup($a_id, "title");
1220 }
1221
1225 public static function lookupType($a_id)
1226 {
1227 return self::lookup($a_id, "type");
1228 }
1229
1233 public static function saveAssOrderOfExercise($a_ex_id, $a_order)
1234 {
1235 global $DIC;
1236
1237 $ilDB = $DIC->database();
1238
1239 $result_order = array();
1240 asort($a_order);
1241 $nr = 10;
1242 foreach ($a_order as $k => $v) {
1243 // the check for exc_id is for security reasons. ass ids are unique.
1244 $ilDB->manipulate(
1245 $t = "UPDATE exc_assignment SET " .
1246 " order_nr = " . $ilDB->quote($nr, "integer") .
1247 " WHERE id = " . $ilDB->quote((int) $k, "integer") .
1248 " AND exc_id = " . $ilDB->quote((int) $a_ex_id, "integer")
1249 );
1250 $nr+=10;
1251 }
1252 }
1253
1257 public static function orderAssByDeadline($a_ex_id)
1258 {
1259 global $DIC;
1260
1261 $ilDB = $DIC->database();
1262
1263 $set = $ilDB->query(
1264 "SELECT id FROM exc_assignment " .
1265 " WHERE exc_id = " . $ilDB->quote($a_ex_id, "integer") .
1266 " ORDER BY time_stamp ASC"
1267 );
1268 $nr = 10;
1269 while ($rec = $ilDB->fetchAssoc($set)) {
1270 $ilDB->manipulate(
1271 "UPDATE exc_assignment SET " .
1272 " order_nr = " . $ilDB->quote($nr, "integer") .
1273 " WHERE id = " . $ilDB->quote($rec["id"], "integer")
1274 );
1275 $nr += 10;
1276 }
1277 }
1278
1282 public static function countMandatory($a_ex_id)
1283 {
1284 global $DIC;
1285
1286 $ilDB = $DIC->database();
1287
1288 $set = $ilDB->query(
1289 "SELECT count(*) cntm FROM exc_assignment " .
1290 " WHERE exc_id = " . $ilDB->quote($a_ex_id, "integer") .
1291 " AND mandatory = " . $ilDB->quote(1, "integer")
1292 );
1293 $rec = $ilDB->fetchAssoc($set);
1294 return $rec["cntm"];
1295 }
1296
1298
1302 public static function lookupUpdatedSubmission($ass_id, $member_id)
1303 {
1304 global $DIC;
1305
1306 $ilDB = $DIC->database();
1307 $lng = $DIC->language();
1308
1309 // team upload?
1310 $user_ids = self::getTeamMembersByAssignmentId($ass_id, $member_id);
1311 if (!$user_ids) {
1312 $user_ids = array($member_id);
1313 }
1314
1315 $q="SELECT exc_mem_ass_status.status_time, exc_returned.ts " .
1316 "FROM exc_mem_ass_status, exc_returned " .
1317 "WHERE exc_mem_ass_status.status_time < exc_returned.ts " .
1318 "AND NOT exc_mem_ass_status.status_time IS NULL " .
1319 "AND exc_returned.ass_id = exc_mem_ass_status.ass_id " .
1320 "AND exc_returned.user_id = exc_mem_ass_status.usr_id " .
1321 "AND exc_returned.ass_id=" . $ilDB->quote($ass_id, "integer") .
1322 " AND " . $ilDB->in("exc_returned.user_id", $user_ids, "", "integer");
1323
1324 $usr_set = $ilDB->query($q);
1325
1326 $array = $ilDB->fetchAssoc($usr_set);
1327
1328 if (count($array)==0) {
1329 return 0;
1330 } else {
1331 return 1;
1332 }
1333 }
1334
1338 public function getMemberListData()
1339 {
1340 $ilDB = $this->db;
1341
1342 $mem = array();
1343
1344 // first get list of members from member table
1345 $set = $ilDB->query("SELECT ud.usr_id, ud.lastname, ud.firstname, ud.login" .
1346 " FROM exc_members excm" .
1347 " JOIN usr_data ud ON (ud.usr_id = excm.usr_id)" .
1348 " WHERE excm.obj_id = " . $ilDB->quote($this->getExerciseId(), "integer"));
1349 while ($rec = $ilDB->fetchAssoc($set)) {
1350 $mem[$rec["usr_id"]] =
1351 array(
1352 "name" => $rec["lastname"] . ", " . $rec["firstname"],
1353 "login" => $rec["login"],
1354 "usr_id" => $rec["usr_id"],
1355 "lastname" => $rec["lastname"],
1356 "firstname" => $rec["firstname"]
1357 );
1358 }
1359
1360 include_once "Modules/Exercise/classes/class.ilExSubmission.php";
1361
1362 $q = "SELECT * FROM exc_mem_ass_status " .
1363 "WHERE ass_id = " . $ilDB->quote($this->getId(), "integer");
1364 $set = $ilDB->query($q);
1365 while ($rec = $ilDB->fetchAssoc($set)) {
1366 if (isset($mem[$rec["usr_id"]])) {
1367 $sub = new ilExSubmission($this, $rec["usr_id"]);
1368
1369 $mem[$rec["usr_id"]]["sent_time"] = $rec["sent_time"];
1370 $mem[$rec["usr_id"]]["submission"] = $sub->getLastSubmission();
1371 $mem[$rec["usr_id"]]["status_time"] = $rec["status_time"];
1372 $mem[$rec["usr_id"]]["feedback_time"] = $rec["feedback_time"];
1373 $mem[$rec["usr_id"]]["notice"] = $rec["notice"];
1374 $mem[$rec["usr_id"]]["status"] = $rec["status"];
1375 $mem[$rec["usr_id"]]["mark"] = $rec["mark"];
1376 $mem[$rec["usr_id"]]["comment"] = $rec["u_comment"];
1377 }
1378 }
1379 return $mem;
1380 }
1381
1385 public static function createNewUserRecords($a_user_id, $a_exc_id)
1386 {
1387 global $DIC;
1388
1389 $ilDB = $DIC->database();
1390
1391 $ass_data = self::getAssignmentDataOfExercise($a_exc_id);
1392 foreach ($ass_data as $ass) {
1393 //echo "-".$ass["id"]."-".$a_user_id."-";
1394 $ilDB->replace("exc_mem_ass_status", array(
1395 "ass_id" => array("integer", $ass["id"]),
1396 "usr_id" => array("integer", $a_user_id)
1397 ), array(
1398 "status" => array("text", "notgraded")
1399 ));
1400 }
1401 }
1402
1406 public static function createNewAssignmentRecords($a_ass_id, $a_exc)
1407 {
1408 global $DIC;
1409
1410 $ilDB = $DIC->database();
1411
1412 include_once("./Modules/Exercise/classes/class.ilExerciseMembers.php");
1413 $exmem = new ilExerciseMembers($a_exc);
1414 $mems = $exmem->getMembers();
1415
1416 foreach ($mems as $mem) {
1417 $ilDB->replace("exc_mem_ass_status", array(
1418 "ass_id" => array("integer", $a_ass_id),
1419 "usr_id" => array("integer", $mem)
1420 ), array(
1421 "status" => array("text", "notgraded")
1422 ));
1423 }
1424 }
1425
1430 public function uploadAssignmentFiles($a_files)
1431 {
1432 ilLoggerFactory::getLogger("exc")->debug("upload assignment files files = ", $a_files);
1433 include_once("./Modules/Exercise/classes/class.ilFSWebStorageExercise.php");
1434 $storage = new ilFSWebStorageExercise($this->getExerciseId(), $this->getId());
1435 $storage->create();
1436 $storage->uploadAssignmentFiles($a_files);
1437 }
1438
1439
1443
1448 {
1449 global $DIC;
1450
1451
1452 // send and delete the zip file
1453 $deliverFilename = trim(str_replace(" ", "_", $this->getTitle() . "_" . $this->getId()));
1454 $deliverFilename = ilUtil::getASCIIFilename($deliverFilename);
1455 $deliverFilename = "multi_feedback_" . $deliverFilename;
1456
1457 $exc = new ilObjExercise($this->getExerciseId(), false);
1458
1459 $cdir = getcwd();
1460
1461 // create temporary directoy
1462 $tmpdir = ilUtil::ilTempnam();
1463 ilUtil::makeDir($tmpdir);
1464 $mfdir = $tmpdir . "/" . $deliverFilename;
1465 ilUtil::makeDir($mfdir);
1466
1467 // create subfolders <lastname>_<firstname>_<id> for each participant
1468 include_once("./Modules/Exercise/classes/class.ilExerciseMembers.php");
1469 $exmem = new ilExerciseMembers($exc);
1470 $mems = $exmem->getMembers();
1471
1472 $mems = $DIC->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
1473 'edit_submissions_grades',
1474 'edit_submissions_grades',
1475 $exercise->getRefId(),
1476 $mems
1477 );
1478 foreach ($mems as $mem) {
1480 $subdir = $name["lastname"] . "_" . $name["firstname"] . "_" . $name["login"] . "_" . $name["user_id"];
1481 $subdir = ilUtil::getASCIIFilename($subdir);
1482 ilUtil::makeDir($mfdir . "/" . $subdir);
1483 }
1484
1485 // create the zip file
1486 chdir($tmpdir);
1487 $tmpzipfile = $tmpdir . "/multi_feedback.zip";
1488 ilUtil::zip($tmpdir, $tmpzipfile, true);
1489 chdir($cdir);
1490
1491
1492 ilUtil::deliverFile($tmpzipfile, $deliverFilename . ".zip", "", false, true);
1493 }
1494
1501 public function uploadMultiFeedbackFile($a_file)
1502 {
1503 $lng = $this->lng;
1505
1506 include_once("./Modules/Exercise/exceptions/class.ilExerciseException.php");
1507 if (!is_file($a_file["tmp_name"])) {
1508 throw new ilExerciseException($lng->txt("exc_feedback_file_could_not_be_uploaded"));
1509 }
1510
1511 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1512 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1513 $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
1514 ilUtil::delDir($mfu, true);
1515 ilUtil::moveUploadedFile($a_file["tmp_name"], "multi_feedback.zip", $mfu . "/" . "multi_feedback.zip");
1516 ilUtil::unzip($mfu . "/multi_feedback.zip", true);
1517 $subdirs = ilUtil::getDir($mfu);
1518 $subdir = "notfound";
1519 foreach ($subdirs as $s => $j) {
1520 if ($j["type"] == "dir" && substr($s, 0, 14) == "multi_feedback") {
1521 $subdir = $s;
1522 }
1523 }
1524
1525 if (!is_dir($mfu . "/" . $subdir)) {
1526 throw new ilExerciseException($lng->txt("exc_no_feedback_dir_found_in_zip"));
1527 }
1528
1529 return true;
1530 }
1531
1538 public function getMultiFeedbackFiles($a_user_id = 0)
1539 {
1541
1542 if ($a_user_id == 0) {
1543 $a_user_id = $ilUser->getId();
1544 }
1545
1546 $mf_files = array();
1547
1548 // get members
1549 $exc = new ilObjExercise($this->getExerciseId(), false);
1550 include_once("./Modules/Exercise/classes/class.ilExerciseMembers.php");
1551 $exmem = new ilExerciseMembers($exc);
1552 $mems = $exmem->getMembers();
1553
1554 // read mf directory
1555 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1556 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1557 $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
1558
1559 // get subdir that starts with multi_feedback
1560 $subdirs = ilUtil::getDir($mfu);
1561 $subdir = "notfound";
1562 foreach ($subdirs as $s => $j) {
1563 if ($j["type"] == "dir" && substr($s, 0, 14) == "multi_feedback") {
1564 $subdir = $s;
1565 }
1566 }
1567
1568 $items = ilUtil::getDir($mfu . "/" . $subdir);
1569 foreach ($items as $k => $i) {
1570 // check directory
1571 if ($i["type"] == "dir" && !in_array($k, array(".", ".."))) {
1572 // check if valid member id is given
1573 $parts = explode("_", $i["entry"]);
1574 $user_id = (int) $parts[count($parts) - 1];
1575 if (in_array($user_id, $mems)) {
1576 // read dir of user
1577 $name = ilObjUser::_lookupName($user_id);
1578 $files = ilUtil::getDir($mfu . "/" . $subdir . "/" . $k);
1579 foreach ($files as $k2 => $f) {
1580 // append files to array
1581 if ($f["type"] == "file" && substr($k2, 0, 1) != ".") {
1582 $mf_files[] = array(
1583 "lastname" => $name["lastname"],
1584 "firstname" => $name["firstname"],
1585 "login" => $name["login"],
1586 "user_id" => $name["user_id"],
1587 "full_path" => $mfu . "/" . $subdir . "/" . $k . "/" . $k2,
1588 "file" => $k2);
1589 }
1590 }
1591 }
1592 }
1593 }
1594 return $mf_files;
1595 }
1596
1604 {
1605 $lng = $this->lng;
1607
1608 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1609 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1610 $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
1611 ilUtil::delDir($mfu);
1612 }
1613
1620 public function saveMultiFeedbackFiles($a_files, ilObjExercise $a_exc)
1621 {
1622 if ($this->getExerciseId() != $a_exc->getId()) {
1623 return;
1624 }
1625
1626 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1627 $fstorage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1628 $fstorage->create();
1629
1630 $team_map = array();
1631
1632 $mf_files = $this->getMultiFeedbackFiles();
1633 foreach ($mf_files as $f) {
1634 $user_id = $f["user_id"];
1635 $file_path = $f["full_path"];
1636 $file_name = $f["file"];
1637
1638 // if checked in confirmation gui
1639 if ($a_files[$user_id][md5($file_name)] != "") {
1640 $submission = new ilExSubmission($this, $user_id);
1641 $feedback_id = $submission->getFeedbackId();
1642 $noti_rec_ids = $submission->getUserIds();
1643
1644 if ($feedback_id) {
1645 $fb_path = $fstorage->getFeedbackPath($feedback_id);
1646 $target = $fb_path . "/" . $file_name;
1647 if (is_file($target)) {
1648 unlink($target);
1649 }
1650 // rename file
1651 rename($file_path, $target);
1652
1653 if ($noti_rec_ids) {
1654 foreach ($noti_rec_ids as $user_id) {
1655 $member_status = $this->getMemberStatus($user_id);
1656 $member_status->setFeedback(true);
1657 $member_status->update();
1658 }
1659
1661 $file_name,
1662 $noti_rec_ids,
1663 (int) $this->getId()
1664 );
1665 }
1666 }
1667 }
1668 }
1669
1671 }
1672
1673
1674
1675
1681 protected function handleCalendarEntries($a_event)
1682 {
1683 $ilAppEventHandler = $this->app_event_handler;
1684
1685 $dl_id = $this->getId() . "0";
1686 $fbdl_id = $this->getId() . "1";
1687
1688 $context_ids = array($dl_id, $fbdl_id);
1689 $apps = array();
1690
1691 if ($a_event != "delete") {
1692 include_once "Services/Calendar/classes/class.ilCalendarAppointmentTemplate.php";
1693
1694 if ($this->getDeadline()) {
1695 $app = new ilCalendarAppointmentTemplate($dl_id);
1696 $app->setTranslationType(IL_CAL_TRANSLATION_SYSTEM);
1697 $app->setSubtitle("cal_exc_deadline");
1698 $app->setTitle($this->getTitle());
1699 $app->setFullday(false);
1700 $app->setStart(new ilDateTime($this->getDeadline(), IL_CAL_UNIX));
1701
1702 $apps[] = $app;
1703 }
1704
1705 if ($this->getPeerReview() &&
1706 $this->getPeerReviewDeadline()) {
1707 $app = new ilCalendarAppointmentTemplate($fbdl_id);
1708 $app->setTranslationType(IL_CAL_TRANSLATION_SYSTEM);
1709 $app->setSubtitle("cal_exc_peer_review_deadline");
1710 $app->setTitle($this->getTitle());
1711 $app->setFullday(false);
1712 $app->setStart(new ilDateTime($this->getPeerReviewDeadline(), IL_CAL_UNIX));
1713
1714 $apps[] = $app;
1715 }
1716 }
1717
1718 include_once "Modules/Exercise/classes/class.ilObjExercise.php";
1719 $exc = new ilObjExercise($this->getExerciseId(), false);
1720
1721 $ilAppEventHandler->raise(
1722 'Modules/Exercise',
1723 $a_event . 'Assignment',
1724 array(
1725 'object' => $exc,
1726 'obj_id' => $exc->getId(),
1727 'context_ids' => $context_ids,
1728 'appointments' => $apps)
1729 );
1730 }
1731
1732
1733 public static function getPendingFeedbackNotifications()
1734 {
1735 global $DIC;
1736
1737 $ilDB = $DIC->database();
1738
1739 $res = array();
1740
1741 $set = $ilDB->query("SELECT id,fb_file,time_stamp,deadline2 FROM exc_assignment" .
1742 " WHERE fb_cron = " . $ilDB->quote(1, "integer") .
1743 " AND fb_date = " . $ilDB->quote(self::FEEDBACK_DATE_DEADLINE, "integer") .
1744 " AND time_stamp IS NOT NULL" .
1745 " AND time_stamp > " . $ilDB->quote(0, "integer") .
1746 " AND time_stamp < " . $ilDB->quote(time(), "integer") .
1747 " AND fb_cron_done = " . $ilDB->quote(0, "integer"));
1748 while ($row = $ilDB->fetchAssoc($set)) {
1749 $max = max($row['time_stamp'], $row['deadline2']);
1750
1751 if (trim($row["fb_file"]) && $max <= time()) {
1752 $res[] = $row["id"];
1753 }
1754 }
1755
1756 return $res;
1757 }
1758
1759 public static function sendFeedbackNotifications($a_ass_id, $a_user_id = null)
1760 {
1761 global $DIC;
1762
1763 $ilDB = $DIC->database();
1764
1765 $ass = new self($a_ass_id);
1766
1767 // valid assignment?
1768 if (!$ass->hasFeedbackCron() || !$ass->getFeedbackFile()) {
1769 return false;
1770 }
1771
1772 if (!$a_user_id) {
1773 // already done?
1774 $set = $ilDB->query("SELECT fb_cron_done" .
1775 " FROM exc_assignment" .
1776 " WHERE id = " . $ilDB->quote($a_ass_id, "integer"));
1777 $row = $ilDB->fetchAssoc($set);
1778 if ($row["fb_cron_done"]) {
1779 return false;
1780 }
1781 }
1782
1783 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
1784 $ntf = new ilSystemNotification();
1785 $ntf->setLangModules(array("exc"));
1786 $ntf->setObjId($ass->getExerciseId());
1787 $ntf->setSubjectLangId("exc_feedback_notification_subject");
1788 $ntf->setIntroductionLangId("exc_feedback_notification_body");
1789 $ntf->addAdditionalInfo("exc_assignment", $ass->getTitle());
1790 $ntf->setGotoLangId("exc_feedback_notification_link");
1791 $ntf->setReasonLangId("exc_feedback_notification_reason");
1792
1793 if (!$a_user_id) {
1794 include_once "./Modules/Exercise/classes/class.ilExerciseMembers.php";
1795 $ntf->sendMail(ilExerciseMembers::_getMembers($ass->getExerciseId()));
1796
1797 $ilDB->manipulate("UPDATE exc_assignment" .
1798 " SET fb_cron_done = " . $ilDB->quote(1, "integer") .
1799 " WHERE id = " . $ilDB->quote($a_ass_id, "integer"));
1800 } else {
1801 $ntf->sendMail(array($a_user_id));
1802 }
1803
1804 return true;
1805 }
1806
1807
1808 // status
1809
1810 public function afterDeadline()
1811 {
1813
1814 // :TODO: always current user?
1815 $idl = $this->getPersonalDeadline($ilUser->getId());
1816
1817 // no deadline === true
1818 $deadline = max($this->deadline, $this->deadline2, $idl);
1819 return ($deadline - time() <= 0);
1820 }
1821
1822 public function afterDeadlineStrict($a_include_personal = true)
1823 {
1824 // :TODO: this means that peer feedback, global feedback is available
1825 // after LAST personal deadline
1826 // team management is currently ignoring personal deadlines
1827 $idl = (bool) $a_include_personal
1828 ? $this->getLastPersonalDeadline()
1829 : null;
1830
1831 // no deadline === false
1832 $deadline = max($this->deadline, $this->deadline2, $idl);
1833
1834 // #18271 - afterDeadline() does not handle last personal deadline
1835 if ($idl && $deadline == $idl) {
1836 return ($deadline - time() <= 0);
1837 }
1838
1839 return ($deadline > 0 &&
1840 $this->afterDeadline());
1841 }
1842
1843 public function beforeDeadline()
1844 {
1845 // no deadline === true
1846 return !$this->afterDeadlineStrict();
1847 }
1848
1849 public function notStartedYet()
1850 {
1851 return (time() - $this->start_time <= 0);
1852 }
1853
1854
1855 //
1856 // FEEDBACK FILES
1857 //
1858
1860 {
1861 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1862 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
1863 return $storage->getGlobalFeedbackPath();
1864 }
1865
1867 {
1869 }
1870
1871 public function handleGlobalFeedbackFileUpload(array $a_file)
1872 {
1874 ilUtil::delDir($path, true);
1875 if (ilUtil::moveUploadedFile($a_file["tmp_name"], $a_file["name"], $path . "/" . $a_file["name"])) {
1876 $this->setFeedbackFile($a_file["name"]);
1877 return true;
1878 }
1879 return false;
1880 }
1881
1883 {
1884 $file = $this->getFeedbackFile();
1885 if ($file) {
1887 return $path . "/" . $file;
1888 }
1889 }
1890
1895 public function getMemberStatus($a_user_id = null)
1896 {
1898
1899 if (!$a_user_id) {
1900 $a_user_id = $ilUser->getId();
1901 }
1902 if (!array_key_exists($a_user_id, $this->member_status)) {
1903 include_once "Modules/Exercise/classes/class.ilExAssignmentMemberStatus.php";
1904 $this->member_status[$a_user_id] = new ilExAssignmentMemberStatus($this->getId(), $a_user_id);
1905 }
1906 return $this->member_status[$a_user_id];
1907 }
1908
1910 {
1911 $ilDB = $this->db;
1912
1913 // see JF, 2015-05-11
1914
1915 $ext_deadline = $this->getExtendedDeadline();
1916
1917 include_once "Modules/Exercise/classes/class.ilExSubmission.php";
1918 foreach (ilExSubmission::getAllAssignmentFiles($this->exc_id, $this->getId()) as $file) {
1919 $id = $file["returned_id"];
1920 $uploaded = new ilDateTime($file["ts"], IL_CAL_DATETIME);
1921 $uploaded = $uploaded->get(IL_CAL_UNIX);
1922
1923 $deadline = $this->getPersonalDeadline($file["user_id"]);
1924 $last_deadline = max($deadline, $this->getExtendedDeadline());
1925
1926 $late = null;
1927
1928 // upload is not late anymore
1929 if ($file["late"] &&
1930 (!$last_deadline ||
1931 !$ext_deadline ||
1932 $uploaded < $deadline)) {
1933 $late = false;
1934 }
1935 // upload is now late
1936 elseif (!$file["late"] &&
1937 $ext_deadline &&
1938 $deadline &&
1939 $uploaded > $deadline) {
1940 $late = true;
1941 } elseif ($last_deadline && $uploaded > $last_deadline) {
1942 // do nothing, we do not remove submissions?
1943 }
1944
1945 if ($late !== null) {
1946 $ilDB->manipulate("UPDATE exc_returned" .
1947 " SET late = " . $ilDB->quote($late, "integer") .
1948 " WHERE returned_id = " . $ilDB->quote($id, "integer"));
1949 }
1950 }
1951 }
1952
1953
1954 //
1955 // individual deadlines
1956 //
1957
1958 public function setIndividualDeadline($id, ilDateTime $date)
1959 {
1960 $ilDB = $this->db;
1961
1962 $is_team = false;
1963 if (!is_numeric($id)) {
1964 $id = substr($id, 1);
1965 $is_team = true;
1966 }
1967
1968 $ilDB->replace(
1969 "exc_idl",
1970 array(
1971 "ass_id" => array("integer", $this->getId()),
1972 "member_id" => array("integer", $id),
1973 "is_team" => array("integer", $is_team)
1974 ),
1975 array(
1976 "tstamp" => array("integer", $date->get(IL_CAL_UNIX))
1977 )
1978 );
1979 }
1980
1981 public function getIndividualDeadlines()
1982 {
1983 $ilDB = $this->db;
1984
1985 $res = array();
1986
1987 $set = $ilDB->query("SELECT * FROM exc_idl" .
1988 " WHERE ass_id = " . $ilDB->quote($this->getId(), "integer"));
1989 while ($row = $ilDB->fetchAssoc($set)) {
1990 if ($row["is_team"]) {
1991 $row["member_id"] = "t" . $row["member_id"];
1992 }
1993
1994 $res[$row["member_id"]] = $row["tstamp"];
1995 }
1996
1997 return $res;
1998 }
1999
2000 public function hasActiveIDl()
2001 {
2002 return (bool) $this->getDeadline();
2003 }
2004
2005 public function hasReadOnlyIDl()
2006 {
2007 if ($this->getType() != ilExAssignment::TYPE_UPLOAD_TEAM &&
2008 $this->getPeerReview()) {
2009 // all deadlines are read-only if we have peer feedback
2010 include_once "Modules/Exercise/classes/class.ilExPeerReview.php";
2011 $peer_review = new ilExPeerReview($this);
2012 if ($peer_review->hasPeerReviewGroups()) {
2013 return true;
2014 }
2015 }
2016
2017 return false;
2018 }
2019
2025 public static function saveInstructionFilesOrderOfAssignment($a_ass_id, $a_order)
2026 {
2027 global $DIC;
2028
2029 $db = $DIC->database();
2030
2031 asort($a_order, SORT_NUMERIC);
2032
2033 $nr = 10;
2034 foreach ($a_order as $k => $v) {
2035 // the check for exc_id is for security reasons. ass ids are unique.
2036 $db->manipulate(
2037 $t = "UPDATE exc_ass_file_order SET " .
2038 " order_nr = " . $db->quote($nr, "integer") .
2039 " WHERE id = " . $db->quote((int) $k, "integer") .
2040 " AND assignment_id = " . $db->quote((int) $a_ass_id, "integer")
2041 );
2042 $nr+=10;
2043 }
2044 }
2045
2051 public static function instructionFileInsertOrder($a_filename, $a_ass_id, $a_order_nr = 0)
2052 {
2053 global $DIC;
2054
2055 $db = $DIC->database();
2056
2057 $order = 0;
2058 $order_val = 0;
2059
2060 if ($a_ass_id) {
2061 //first of all check the suffix and change if necessary
2062 $filename = ilUtil::getSafeFilename($a_filename);
2063
2064 if (!self::instructionFileExistsInDb($filename, $a_ass_id)) {
2065 if ($a_order_nr == 0) {
2066 $order_val = self::instructionFileOrderGetMax($a_ass_id);
2067 $order = $order_val + 10;
2068 } else {
2069 $order = $a_order_nr;
2070 }
2071
2072 $id = $db->nextID('exc_ass_file_order');
2073 $db->manipulate("INSERT INTO exc_ass_file_order " .
2074 "(id, assignment_id, filename, order_nr) VALUES (" .
2075 $db->quote($id, "integer") . "," .
2076 $db->quote($a_ass_id, "integer") . "," .
2077 $db->quote($filename, "text") . "," .
2078 $db->quote($order, "integer") .
2079 ")");
2080 }
2081 }
2082 }
2083
2084 public static function instructionFileDeleteOrder($a_ass_id, $a_file)
2085 {
2086 global $DIC;
2087
2088 $db = $DIC->database();
2089
2090 //now its done by filename. We need to figure how to get the order id in the confirmdelete method
2091 foreach ($a_file as $k => $v) {
2092 $db->manipulate(
2093 "DELETE FROM exc_ass_file_order " .
2094 //"WHERE id = " . $ilDB->quote((int)$k, "integer") .
2095 "WHERE filename = " . $db->quote($v, "string") .
2096 " AND assignment_id = " . $db->quote($a_ass_id, 'integer')
2097 );
2098 }
2099 }
2100
2106 public static function renameInstructionFile($a_old_name, $a_new_name, $a_ass_id)
2107 {
2108 global $DIC;
2109
2110 $db = $DIC->database();
2111
2112 if ($a_ass_id) {
2113 $db->manipulate(
2114 "DELETE FROM exc_ass_file_order" .
2115 " WHERE assignment_id = " . $db->quote((int) $a_ass_id, 'integer') .
2116 " AND filename = " . $db->quote($a_new_name, 'string')
2117 );
2118
2119 $db->manipulate(
2120 "UPDATE exc_ass_file_order SET" .
2121 " filename = " . $db->quote($a_new_name, 'string') .
2122 " WHERE assignment_id = " . $db->quote((int) $a_ass_id, 'integer') .
2123 " AND filename = " . $db->quote($a_old_name, 'string')
2124 );
2125 }
2126 }
2127
2133 public static function instructionFileExistsInDb($a_filename, $a_ass_id)
2134 {
2135 global $DIC;
2136
2137 $db = $DIC->database();
2138
2139 if ($a_ass_id) {
2140 $result = $db->query(
2141 "SELECT id FROM exc_ass_file_order" .
2142 " WHERE assignment_id = " . $db->quote((int) $a_ass_id, 'integer') .
2143 " AND filename = " . $db->quote($a_filename, 'string')
2144 );
2145
2146 return $db->numRows($result);
2147 }
2148 }
2149
2151 {
2152 global $DIC;
2153
2154 $db = $DIC->database();
2155
2156 $files = array_map(function ($v) {
2157 return $v["name"];
2158 }, $this->getFiles());
2159
2160 $set = $db->query("SELECT * FROM exc_ass_file_order " .
2161 " WHERE assignment_id = " . $db->quote($this->getId(), "integer") .
2162 " ORDER BY order_nr");
2163 $order_nr = 10;
2164 $numbered_files = array();
2165 while ($rec = $db->fetchAssoc($set)) {
2166 // file exists, set correct order nr
2167 if (in_array($rec["filename"], $files)) {
2168 $db->manipulate(
2169 "UPDATE exc_ass_file_order SET " .
2170 " order_nr = " . $db->quote($order_nr, "integer") .
2171 " WHERE assignment_id = " . $db->quote($this->getId(), "integer") .
2172 " AND id = " . $db->quote($rec["id"], "integer")
2173 );
2174 $order_nr+=10;
2175 $numbered_files[] = $rec["filename"];
2176 } else { // file does not exist, delete entry
2177 $db->manipulate(
2178 "DELETE FROM exc_ass_file_order " .
2179 " WHERE assignment_id = " . $db->quote($this->getId(), "integer") .
2180 " AND id = " . $db->quote($rec["id"], "integer")
2181 );
2182 }
2183 }
2184 foreach ($files as $f) {
2185 if (!in_array($f, $numbered_files)) {
2187 }
2188 }
2189 }
2190
2196 public function fileAddOrder($a_entries = array())
2197 {
2199
2200 $order = $this->getInstructionFilesOrder();
2201 foreach ($a_entries as $k => $e) {
2202 $a_entries[$k]["order_val"] = $order[$e["file"]]["order_nr"];
2203 $a_entries[$k]["order_id"] = $order[$e["file"]]["id"];
2204 }
2205
2206 return $a_entries;
2207 }
2208
2213 public static function instructionFileOrderGetMax($a_ass_id)
2214 {
2215 global $DIC;
2216
2217 $db = $DIC->database();
2218
2219 //get max order number
2220 $result = $db->queryF(
2221 "SELECT max(order_nr) as max_order FROM exc_ass_file_order WHERE assignment_id = %s",
2222 array('integer'),
2223 array($db->quote($a_ass_id, 'integer'))
2224 );
2225
2226 while ($row = $db->fetchAssoc($result)) {
2227 $order_val = (int) $row['max_order'];
2228 }
2229 return $order_val;
2230 }
2231
2232
2238 public function setMinCharLimit($a_val)
2239 {
2240 $this->min_char_limit = $a_val;
2241 }
2242
2248 public function getMinCharLimit()
2249 {
2250 return $this->min_char_limit;
2251 }
2252
2257 public function setMaxCharLimit($a_val)
2258 {
2259 $this->max_char_limit = $a_val;
2260 }
2261
2266 public function getMaxCharLimit()
2267 {
2268 return $this->max_char_limit;
2269 }
2270}
$result
user()
Definition: user.php:4
$files
Definition: add-vimline.php:18
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_TRANSLATION_SYSTEM
const IL_CAL_UNIX
const IL_CAL_DATETIME
Apointment templates are used for automatic generated apointments.
@classDescription Date and time handling
get($a_format, $a_format_str='', $a_tz='')
get formatted date
Exercise assignment member status.
static getTeamId($a_assignment_id, $a_user_id, $a_create_on_demand=false)
Get team id for member id.
Exercise assignment.
getMinCharLimit()
Get limit minimum characters.
static orderAssByDeadline($a_ex_id)
Order assignments by deadline date.
getPersonalDeadline($a_user_id)
Get individual deadline.
hasPeerReviewText()
Get peer review text status.
afterDeadlineStrict($a_include_personal=true)
getPeerReviewChars()
Get peer review minimum characters.
hasPeerReviewPersonalized()
Get peer review personalized status.
setDeadline($a_val)
Set deadline (timestamp)
static lookupMaxOrderNrForEx($a_exc_id)
Select the maximum order nr for an exercise.
static instructionFileInsertOrder($a_filename, $a_ass_id, $a_order_nr=0)
Store the file order in the database.
setOrderNr($a_val)
Set order nr.
clearMultiFeedbackDirectory()
Clear multi feedback directory.
getLastPersonalDeadline()
Get last/final personal deadline (of assignment)
setPeerReviewRating($a_val)
Set peer review rating.
setPeerReview($a_value)
Toggle peer review.
setPortfolioTemplateId($a_val)
Set portfolio template id.
getFeedbackDate()
Get (global) feedback file availability date.
getPeerReviewValid()
Get peer review validatiob.
getMemberListData()
get member list data
getMultiFeedbackFiles($a_user_id=0)
Get multi feedback files (of uploader)
getExerciseId()
Get exercise id.
static saveInstructionFilesOrderOfAssignment($a_ass_id, $a_order)
Save ordering of instruction files for an assignment.
static lookup($a_id, $a_field)
Private lookup.
setTeamTutor($a_value)
Set team management by tutor.
setFeedbackCron($a_value)
Toggle (global) feedback file cron.
setTitle($a_val)
Set title.
fileAddOrder($a_entries=array())
uploadMultiFeedbackFile($a_file)
Upload multi feedback file.
handleCalendarEntries($a_event)
Handle calendar entries for deadline(s)
static renameInstructionFile($a_old_name, $a_new_name, $a_ass_id)
getId()
Get assignment id.
getInstruction()
Get instruction.
static lookupUpdatedSubmission($ass_id, $member_id)
Check whether student has upload new files after tutor has set the exercise to another than notgraded...
static instructionFileGetFileOrderData($a_file_data, $a_ass_id)
static countMandatory($a_ex_id)
Order assignments by deadline date.
getTeamTutor()
Get team management by tutor.
getPeerReviewMin()
Get peer review minimum.
static getInstancesByExercise($a_exc_id)
setPeerReviewPersonalized($a_val)
Set peer review personalized.
isValidType($a_value)
Is given type valid?
setPeerReviewValid($a_value)
Set peer review validation.
handleGlobalFeedbackFileUpload(array $a_file)
setPeerReviewText($a_val)
Set peer review text.
setPeerReviewSimpleUnlock($a_value)
Set peer review simple unlock.
getMaxFile()
Get max number of uploads.
static lookupExerciseId($a_ass_id)
Lookup excercise id for assignment id.
saveMultiFeedbackFiles($a_files, ilObjExercise $a_exc)
Save multi feedback files.
setExtendedDeadline($a_val)
Set extended deadline (timestamp)
setIndividualDeadline($id, ilDateTime $date)
setPeerReviewMin($a_value)
Set peer review minimum.
setInstruction($a_val)
Set instruction.
static createNewAssignmentRecords($a_ass_id, $a_exc)
Create member status record for a new assignment for all participants.
static getPendingFeedbackNotifications()
initFromDB(array $a_set)
Import DB record.
uploadAssignmentFiles($a_files)
Upload assignment files (from creation form)
__construct($a_id=0)
Constructor.
getPeerReview()
Get peer review status.
hasPeerReviewFileUpload()
Get peer review file upload status.
static sendFeedbackNotifications($a_ass_id, $a_user_id=null)
sendMultiFeedbackStructureFile(ilObjExercise $exercise)
Create member status record for a new assignment for all participants.
static cloneAssignmentsOfExercise($a_old_exc_id, $a_new_exc_id, array $a_crit_cat_map)
Clone assignments of exercise.
static getAssignmentDataOfExercise($a_exc_id)
Get assignments data of an exercise in an array.
setId($a_val)
Set assignment id.
setPeerReviewChars($a_value)
Set peer review minimum characters.
setMaxCharLimit($a_val)
Set limit maximum characters.
hasFeedbackCron()
Get (global) feedback file cron status.
getStartTime()
Get start time (timestamp)
setMaxFile($a_value)
Set max number of uploads.
getMemberStatus($a_user_id=null)
setStartTime($a_val)
Set start time (timestamp)
setMinCharLimit($a_val)
Set limit minimum characters.
setPeerReviewCriteriaCatalogue($a_value)
Set peer review criteria catalogue id.
getPeerReviewSimpleUnlock()
Get peer review simple unlock.
static instructionFileExistsInDb($a_filename, $a_ass_id)
static instructionFileOrderGetMax($a_ass_id)
getPeerReviewDeadline()
Get peer review deadline (timestamp)
getMaxCharLimit()
get limit maximum characters return int max limit
getOrderNr()
Get order nr.
setPeerReviewDeadline($a_val)
Set peer review deadline (timestamp)
setFeedbackDate($a_value)
Set (global) feedback file availability date.
static lookupTitle($a_id)
Lookup title.
getFeedbackFile()
Get (global) feedback file.
getPeerReviewCriteriaCatalogue()
Get peer review criteria catalogue id.
setPeerReviewFileUpload($a_val)
Set peer review file upload.
getPortfolioTemplateId()
Get portfolio template id.
static createNewUserRecords($a_user_id, $a_exc_id)
Create member status record for a new participant for all assignments.
setType($a_value)
Set type.
static lookupAssignmentOnline($a_ass_id)
Check if assignment is online.
save()
Save assignment.
getDeadline()
Get deadline (timestamp)
static instructionFileDeleteOrder($a_ass_id, $a_file)
getExtendedDeadline()
Get extended deadline (timestamp)
setExerciseId($a_val)
Set exercise id.
static saveAssOrderOfExercise($a_ex_id, $a_order)
Save ordering of all assignments of an exercise.
static lookupType($a_id)
Lookup type.
setFeedbackFile($a_value)
Set (global) feedback file.
setMandatory($a_val)
Set mandatory.
getMandatory()
Get mandatory.
hasPeerReviewRating()
Get peer review rating status.
Exercise peer review.
Exercise submission.
static getAllAssignmentFiles($a_exc_id, $a_ass_id)
static getInstancesByParentId($a_parent_id)
static getInstanceByType($a_type)
Exercise exceptions class.
Class ilExerciseMembers.
static _getMembers($a_obj_id)
static getLogger($a_component_id)
Get component logger.
Class ilObjExercise.
sendFeedbackFileNotification($a_feedback_file, $a_user_id, $a_ass_id, $a_is_text_feedback=false)
Send feedback file notification to user.
static _lookupName($a_user_id)
lookup user name
getRefId()
get reference id @access public
getId()
get object id @access public
Wrapper classes for system notifications.
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
static zip($a_dir, $a_file, $compress_content=false)
zips given directory/file into given zip.file
static getSafeFilename($a_initial_filename)
static getDir($a_dir, $a_rec=false, $a_sub_dir="")
get directory
static ilTempnam($a_temp_path=null)
Create a temporary file in an ILIAS writable directory.
static deliverFile( $a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
$i
Definition: disco.tpl.php:19
if($format !==null) $name
Definition: metadata.php:146
$query
$s
Definition: pwgen.php:45
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB
$ilUser
Definition: imgupload.php:18