ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f870
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{
13 const TYPE_UPLOAD = 1;
14 const TYPE_BLOG = 2;
15 const TYPE_PORTFOLIO = 3;
17 const TYPE_TEXT = 5;
18
24
27
28 protected $id;
29 protected $exc_id;
30 protected $type;
31 protected $start_time;
32 protected $deadline;
33 protected $instruction;
34 protected $title;
35 protected $mandatory;
36 protected $order_nr;
37 protected $peer;
38 protected $peer_min;
39 protected $peer_dl;
40 protected $peer_file;
41 protected $peer_personal;
42 protected $feedback_file;
43 protected $feedback_cron;
44 protected $feedback_date;
45
49 function __construct($a_id = 0)
50 {
51 $this->setType(self::TYPE_UPLOAD);
52 $this->setFeedbackDate(self::FEEDBACK_DATE_DEADLINE);
53
54 if ($a_id > 0)
55 {
56 $this->setId($a_id);
57 $this->read();
58 }
59 }
60
66 function setId($a_val)
67 {
68 $this->id = $a_val;
69 }
70
76 function getId()
77 {
78 return $this->id;
79 }
80
86 function setExerciseId($a_val)
87 {
88 $this->exc_id = $a_val;
89 }
90
96 function getExerciseId()
97 {
98 return $this->exc_id;
99 }
100
106 function setStartTime($a_val)
107 {
108 $this->start_time = $a_val;
109 }
110
116 function getStartTime()
117 {
118 return $this->start_time;
119 }
120
126 function setDeadline($a_val)
127 {
128 $this->deadline = $a_val;
129 }
130
136 function getDeadline()
137 {
138 return $this->deadline;
139 }
140
146 function setInstruction($a_val)
147 {
148 $this->instruction = $a_val;
149 }
150
156 function getInstruction()
157 {
158 return $this->instruction;
159 }
160
166 function setTitle($a_val)
167 {
168 $this->title = $a_val;
169 }
170
176 function getTitle()
177 {
178 return $this->title;
179 }
180
186 function setMandatory($a_val)
187 {
188 $this->mandatory = $a_val;
189 }
190
196 function getMandatory()
197 {
198 return $this->mandatory;
199 }
200
206 function setOrderNr($a_val)
207 {
208 $this->order_nr = $a_val;
209 }
210
216 function getOrderNr()
217 {
218 return $this->order_nr;
219 }
220
226 function setType($a_value)
227 {
228 if($this->isValidType($a_value))
229 {
230 $this->type = (int)$a_value;
231
232 if($this->type == self::TYPE_UPLOAD_TEAM)
233 {
234 $this->setPeerReview(false);
235 }
236 }
237 }
238
244 function getType()
245 {
246 return $this->type;
247 }
248
255 function isValidType($a_value)
256 {
257 if(in_array((int)$a_value, array(self::TYPE_UPLOAD, self::TYPE_BLOG,
258 self::TYPE_PORTFOLIO, self::TYPE_UPLOAD_TEAM, self::TYPE_TEXT)))
259 {
260 return true;
261 }
262 return false;
263 }
264
270 function setPeerReview($a_value)
271 {
272 $this->peer = (bool)$a_value;
273 }
274
280 function getPeerReview()
281 {
282 return (bool)$this->peer;
283 }
284
290 function setPeerReviewMin($a_value)
291 {
292 $this->peer_min = (int)$a_value;
293 }
294
301 {
302 return (int)$this->peer_min;
303 }
304
310 function setPeerReviewDeadline($a_val)
311 {
312 $this->peer_dl = $a_val;
313 }
314
321 {
322 return $this->peer_dl;
323 }
324
330 function setPeerReviewFileUpload($a_val)
331 {
332 $this->peer_file = (bool)$a_val;
333 }
334
341 {
342 return $this->peer_file;
343 }
344
351 {
352 $this->peer_personal = (bool)$a_val;
353 }
354
361 {
363 }
364
370 function setFeedbackFile($a_value)
371 {
372 $this->feedback_file = (string)$a_value;
373 }
374
381 {
382 return (string)$this->feedback_file;
383 }
384
390 function setFeedbackCron($a_value)
391 {
392 $this->feedback_cron = (string)$a_value;
393 }
394
401 {
402 return (bool)$this->feedback_cron;
403 }
404
410 function setFeedbackDate($a_value)
411 {
412 $this->feedback_date = (int)$a_value;
413 }
414
421 {
422 return (int)$this->feedback_date;
423 }
424
428 function read()
429 {
430 global $ilDB;
431
432 $set = $ilDB->query("SELECT * FROM exc_assignment ".
433 " WHERE id = ".$ilDB->quote($this->getId(), "integer")
434 );
435 while ($rec = $ilDB->fetchAssoc($set))
436 {
437 $this->setExerciseId($rec["exc_id"]);
438 $this->setDeadline($rec["time_stamp"]);
439 $this->setInstruction($rec["instruction"]);
440 $this->setTitle($rec["title"]);
441 $this->setStartTime($rec["start_time"]);
442 $this->setOrderNr($rec["order_nr"]);
443 $this->setMandatory($rec["mandatory"]);
444 $this->setType($rec["type"]);
445 $this->setPeerReview($rec["peer"]);
446 $this->setPeerReviewMin($rec["peer_min"]);
447 $this->setPeerReviewDeadline($rec["peer_dl"]);
448 $this->setPeerReviewFileUpload($rec["peer_file"]);
449 $this->setPeerReviewPersonalized($rec["peer_prsl"]);
450 $this->setFeedbackFile($rec["fb_file"]);
451 $this->setFeedbackDate($rec["fb_date"]);
452 $this->setFeedbackCron($rec["fb_cron"]);
453 }
454 }
455
459 function save()
460 {
461 global $ilDB;
462
463 if ($this->getOrderNr() == 0)
464 {
465 $this->setOrderNr(
467 + 10);
468 }
469
470 $next_id = $ilDB->nextId("exc_assignment");
471 $ilDB->insert("exc_assignment", array(
472 "id" => array("integer", $next_id),
473 "exc_id" => array("integer", $this->getExerciseId()),
474 "time_stamp" => array("integer", $this->getDeadline()),
475 "instruction" => array("clob", $this->getInstruction()),
476 "title" => array("text", $this->getTitle()),
477 "start_time" => array("integer", $this->getStartTime()),
478 "order_nr" => array("integer", $this->getOrderNr()),
479 "mandatory" => array("integer", $this->getMandatory()),
480 "type" => array("integer", $this->getType()),
481 "peer" => array("integer", $this->getPeerReview()),
482 "peer_min" => array("integer", $this->getPeerReviewMin()),
483 "peer_dl" => array("integer", $this->getPeerReviewDeadline()),
484 "peer_file" => array("integer", $this->hasPeerReviewFileUpload()),
485 "peer_prsl" => array("integer", $this->hasPeerReviewPersonalized()),
486 "fb_file" => array("text", $this->getFeedbackFile()),
487 "fb_date" => array("integer", $this->getFeedbackDate()),
488 "fb_cron" => array("integer", $this->hasFeedbackCron()))
489 );
490 $this->setId($next_id);
491 $exc = new ilObjExercise($this->getExerciseId(), false);
492 $exc->updateAllUsersStatus();
494
495 $this->handleCalendarEntries("create");
496 }
497
501 function update()
502 {
503 global $ilDB;
504
505 $ilDB->update("exc_assignment",
506 array(
507 "exc_id" => array("integer", $this->getExerciseId()),
508 "time_stamp" => array("integer", $this->getDeadline()),
509 "instruction" => array("clob", $this->getInstruction()),
510 "title" => array("text", $this->getTitle()),
511 "start_time" => array("integer", $this->getStartTime()),
512 "order_nr" => array("integer", $this->getOrderNr()),
513 "mandatory" => array("integer", $this->getMandatory()),
514 "type" => array("integer", $this->getType()),
515 "peer" => array("integer", $this->getPeerReview()),
516 "peer_min" => array("integer", $this->getPeerReviewMin()),
517 "peer_dl" => array("integer", $this->getPeerReviewDeadline()),
518 "peer_file" => array("integer", $this->hasPeerReviewFileUpload()),
519 "peer_prsl" => array("integer", $this->hasPeerReviewPersonalized()),
520 "fb_file" => array("text", $this->getFeedbackFile()),
521 "fb_date" => array("integer", $this->getFeedbackDate()),
522 "fb_cron" => array("integer", $this->hasFeedbackCron())
523 ),
524 array(
525 "id" => array("integer", $this->getId()),
526 ));
527 $exc = new ilObjExercise($this->getExerciseId(), false);
528 $exc->updateAllUsersStatus();
529
530 $this->handleCalendarEntries("update");
531 }
532
536 function delete()
537 {
538 global $ilDB;
539
540 $this->deleteFeedbackFile();
541
542 $ilDB->manipulate("DELETE FROM exc_assignment WHERE ".
543 " id = ".$ilDB->quote($this->getId(), "integer")
544 );
545 $exc = new ilObjExercise($this->getExerciseId(), false);
546 $exc->updateAllUsersStatus();
547
548 $this->handleCalendarEntries("delete");
549 }
550
552 {
553 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
554 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
555 $path = $storage->getGlobalFeedbackPath();
557 }
558
559 function handleFeedbackFileUpload(array $a_file)
560 {
561 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
562 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
563 $path = $storage->getGlobalFeedbackPath();
564 ilUtil::delDir($path, true);
565 if(@move_uploaded_file($a_file["tmp_name"], $path."/".$a_file["name"]))
566 {
567 $this->setFeedbackFile($a_file["name"]);
568 return true;
569 }
570 return false;
571 }
572
574 {
575 $file = $this->getFeedbackFile();
576 if($file)
577 {
578 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
579 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
580 $path = $storage->getGlobalFeedbackPath();
581 return $path."/".$file;
582 }
583 }
584
588 static function getAssignmentDataOfExercise($a_exc_id)
589 {
590 global $ilDB;
591
592 $set = $ilDB->query("SELECT * FROM exc_assignment ".
593 " WHERE exc_id = ".$ilDB->quote($a_exc_id, "integer").
594 " ORDER BY order_nr ASC");
595 $data = array();
596
597 $order_val = 10;
598 while ($rec = $ilDB->fetchAssoc($set))
599 {
600
601 $data[] = array(
602 "id" => $rec["id"],
603 "exc_id" => $rec["exc_id"],
604 "deadline" => $rec["time_stamp"],
605 "instruction" => $rec["instruction"],
606 "title" => $rec["title"],
607 "start_time" => $rec["start_time"],
608 "order_val" => $order_val,
609 "mandatory" => $rec["mandatory"],
610 "type" => $rec["type"],
611 "peer" => $rec["peer"],
612 "peer_min" => $rec["peer_min"],
613 "peer_dl" => $rec["peer_dl"],
614 "peer_file" => $rec["peer_file"],
615 "peer_prsl" => $rec["peer_prsl"],
616 "fb_file" => $rec["fb_file"],
617 "fb_date" => $rec["fb_date"],
618 "fb_cron" => $rec["fb_cron"],
619 );
620 $order_val += 10;
621 }
622 return $data;
623 }
624
631 function cloneAssignmentsOfExercise($a_old_exc_id, $a_new_exc_id)
632 {
633 $ass_data = ilExAssignment::getAssignmentDataOfExercise($a_old_exc_id);
634 foreach ($ass_data as $d)
635 {
636 // clone assignment
637 $new_ass = new ilExAssignment();
638 $new_ass->setExerciseId($a_new_exc_id);
639 $new_ass->setTitle($d["title"]);
640 $new_ass->setDeadline($d["deadline"]);
641 $new_ass->setInstruction($d["instruction"]);
642 $new_ass->setMandatory($d["mandatory"]);
643 $new_ass->setOrderNr($d["order_val"]);
644 $new_ass->setStartTime($d["start_time"]);
645 $new_ass->setType($d["type"]);
646 $new_ass->setPeerReview($d["peer"]);
647 $new_ass->setPeerReviewMin($d["peer_min"]);
648 $new_ass->setPeerReviewDeadline($d["peer_dl"]);
649 $new_ass->setPeerReviewFileUpload($d["peer_file"]);
650 $new_ass->setPeerReviewPersonalized($d["peer_prsl"]);
651 $new_ass->setFeedbackFile($d["fb_file"]);
652 $new_ass->setFeedbackDate($d["fb_date"]);
653 $new_ass->setFeedbackCron($d["fb_cron"]);
654 $new_ass->save();
655
656 // clone assignment files
657 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
658 $old_storage = new ilFSStorageExercise($a_old_exc_id, (int) $d["id"]);
659 $new_storage = new ilFSStorageExercise($a_new_exc_id, (int) $new_ass->getId());
660 $new_storage->create();
661
662 if (is_dir($old_storage->getPath()))
663 {
664 ilUtil::rCopy($old_storage->getPath(), $new_storage->getPath());
665 }
666 }
667 }
668
672 static function getFiles($a_exc_id, $a_ass_id)
673 {
674 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
675 $storage = new ilFSStorageExercise($a_exc_id, $a_ass_id);
676 return $storage->getFiles();
677 }
678
682 static function lookupMaxOrderNrForEx($a_exc_id)
683 {
684 global $ilDB;
685
686 $set = $ilDB->query("SELECT MAX(order_nr) mnr FROM exc_assignment ".
687 " WHERE exc_id = ".$ilDB->quote($a_exc_id, "integer")
688 );
689 while ($rec = $ilDB->fetchAssoc($set))
690 {
691 return (int) $rec["mnr"];
692 }
693 return 0;
694 }
695
701 public static function lookupAssignmentOnline($a_ass_id)
702 {
703 global $ilDB;
704
705 $query = "SELECT id FROM exc_assignment ".
706 "WHERE start_time <= ".$ilDB->quote(time(),'integer').' '.
707 "AND time_stamp >= ".$ilDB->quote(time(),'integer').' '.
708 "AND id = ".$ilDB->quote($a_ass_id,'integer');
709 $res = $ilDB->query($query);
710
711 return $res->numRows() ? true : false;
712 }
713
714
718 private static function lookup($a_id, $a_field)
719 {
720 global $ilDB;
721
722 $set = $ilDB->query("SELECT ".$a_field." FROM exc_assignment ".
723 " WHERE id = ".$ilDB->quote($a_id, "integer")
724 );
725
726 $rec = $ilDB->fetchAssoc($set);
727
728 return $rec[$a_field];
729 }
730
734 static function lookupTitle($a_id)
735 {
736 return ilExAssignment::lookup($a_id, "title");
737 }
738
742 static function lookupType($a_id)
743 {
744 return ilExAssignment::lookup($a_id, "type");
745 }
746
750 function saveAssOrderOfExercise($a_ex_id, $a_order)
751 {
752 global $ilDB;
753
754 $result_order = array();
755 asort($a_order);
756 $nr = 10;
757 foreach ($a_order as $k => $v)
758 {
759 // the check for exc_id is for security reasons. ass ids are unique.
760 $ilDB->manipulate($t = "UPDATE exc_assignment SET ".
761 " order_nr = ".$ilDB->quote($nr, "integer").
762 " WHERE id = ".$ilDB->quote((int) $k, "integer").
763 " AND exc_id = ".$ilDB->quote((int) $a_ex_id, "integer")
764 );
765 $nr+=10;
766 }
767 }
768
772 function orderAssByDeadline($a_ex_id)
773 {
774 global $ilDB;
775
776 $set = $ilDB->query("SELECT id FROM exc_assignment ".
777 " WHERE exc_id = ".$ilDB->quote($a_ex_id, "integer").
778 " ORDER BY time_stamp ASC"
779 );
780 $nr = 10;
781 while ($rec = $ilDB->fetchAssoc($set))
782 {
783 $ilDB->manipulate("UPDATE exc_assignment SET ".
784 " order_nr = ".$ilDB->quote($nr, "integer").
785 " WHERE id = ".$ilDB->quote($rec["id"], "integer")
786 );
787 $nr += 10;
788 }
789 }
790
794 function countMandatory($a_ex_id)
795 {
796 global $ilDB;
797
798 $set = $ilDB->query("SELECT count(*) cntm FROM exc_assignment ".
799 " WHERE exc_id = ".$ilDB->quote($a_ex_id, "integer").
800 " AND mandatory = ".$ilDB->quote(1, "integer")
801 );
802 $rec = $ilDB->fetchAssoc($set);
803 return $rec["cntm"];
804 }
805
809
813 private function lookupAssMemberField($a_ass_id, $a_user_id, $a_field)
814 {
815 global $ilDB;
816
817 $set = $ilDB->query("SELECT ".$a_field." FROM exc_mem_ass_status ".
818 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
819 " AND usr_id = ".$ilDB->quote($a_user_id, "integer")
820 );
821 $rec = $ilDB->fetchAssoc($set);
822
823 return $rec[$a_field];
824 }
825
829 private function updateAssMemberField($a_ass_id, $a_user_id, $a_field, $a_value, $a_type)
830 {
831 global $ilDB;
832
833 $ilDB->manipulate("UPDATE exc_mem_ass_status SET ".
834 " ".$a_field." = ".$ilDB->quote($a_value, $a_type).
835 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
836 " AND usr_id = ".$ilDB->quote($a_user_id, "integer")
837 );
838 }
839
840
841/* function setStatus($a_status)
842 {
843 if(is_array($a_status))
844 {
845 $this->status = $a_status;
846 return true;
847 }
848 }
849 function getStatus()
850 {
851 return $this->status ? $this->status : array();
852 }*/
853
857 function lookupCommentForUser($a_ass_id, $a_user_id)
858 {
859 return ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "u_comment");
860 }
861
865 function updateCommentForUser($a_ass_id, $a_user_id, $a_value)
866 {
867 ilExAssignment::updateAssMemberField($a_ass_id, $a_user_id,
868 "u_comment", $a_value, "text");
869 }
870
874 function lookupMarkOfUser($a_ass_id, $a_user_id)
875 {
876 return ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "mark");
877 }
878
882 function updateMarkOfUser($a_ass_id, $a_user_id, $a_value)
883 {
884 ilExAssignment::updateAssMemberField($a_ass_id, $a_user_id,
885 "mark", $a_value, "text");
886 }
887
891 function lookupStatusOfUser($a_ass_id, $a_user_id)
892 {
893 $stat = ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "status");
894 if ($stat == "")
895 {
896 $stat = "notgraded";
897 }
898 return $stat;
899 }
900
904 function updateStatusOfUser($a_ass_id, $a_user_id, $a_status)
905 {
906 global $ilDB;
907
908 $ilDB->manipulateF("UPDATE exc_mem_ass_status ".
909 "SET status = %s, status_time= %s ".
910 " WHERE ass_id = %s AND usr_id = %s AND status <> %s ",
911 array("text", "timestamp", "integer", "integer", "text"),
912 array($a_status, ilUtil::now(), $a_ass_id, $a_user_id, $a_status));
913
914 $ass = new ilExAssignment($a_ass_id);
915 $exc = new ilObjExercise($ass->getExerciseId(), false);
916 $exc->updateUserStatus($a_user_id);
917 }
918
922 function updateStatusTimeOfUser($a_ass_id, $a_user_id)
923 {
924 // #13741 - is only used for mark
925 ilExAssignment::updateAssMemberField($a_ass_id, $a_user_id,
926 "status_time", ilUtil::now(), "timestamp");
927 }
928
929
930 /*function setStatusSent($a_status)
931 {
932 if(is_array($a_status))
933 {
934 $this->status_sent = $a_status;
935 return true;
936 }
937 }
938 function getStatusSent()
939 {
940 return $this->status_sent ? $this->status_sent : array(0 => 0);
941 }*/
942
946 function lookupStatusSentOfUser($a_ass_id, $a_user_id)
947 {
948 return ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "sent");
949 }
950
954 function updateStatusSentForUser($a_ass_id, $a_user_id, $a_status)
955 {
956 global $ilDB;
957
958 // #13741
959 $ilDB->manipulateF("UPDATE exc_mem_ass_status ".
960 "SET sent = %s, sent_time = %s ".
961 " WHERE ass_id = %s AND usr_id = %s ",
962 array("integer", "timestamp", "integer", "integer"),
963 array((int) $a_status, ($a_status ? ilUtil::now() : null),
964 $a_ass_id, $a_user_id));
965 }
966
967 /*function getStatusReturned()
968 {
969 return $this->status_returned ? $this->status_returned : array(0 => 0);
970 }
971 function setStatusReturned($a_status)
972 {
973 if(is_array($a_status))
974 {
975 $this->status_returned = $a_status;
976 return true;
977 }
978 return false;
979 }*/
980
984 function lookupStatusReturnedOfUser($a_ass_id, $a_user_id)
985 {
986 return ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "returned");
987 }
988
992 function updateStatusReturnedForUser($a_ass_id, $a_user_id, $a_status)
993 {
994 global $ilDB;
995
996 // first upload => notification on submission?
997 if($a_status &&
998 !self::lookupStatusReturnedOfUser($a_ass_id, $a_user_id))
999 {
1000 $set = $ilDB->query("SELECT fb_cron, fb_date, fb_file".
1001 " FROM exc_assignment".
1002 " WHERE id = ".$ilDB->quote($a_ass_id, "integer"));
1003 $row = $ilDB->fetchAssoc($set);
1004 if($row["fb_cron"] &&
1005 $row["fb_file"] &&
1006 $row["fb_date"] == self::FEEDBACK_DATE_SUBMISSION)
1007 {
1008 ilExAssignment::sendFeedbackNotifications($a_ass_id, $a_user_id);
1009 }
1010 }
1011
1012 // #13741
1013 $ilDB->manipulateF("UPDATE exc_mem_ass_status".
1014 " SET returned = %s".
1015 " WHERE ass_id = %s AND usr_id = %s",
1016 array("integer", "integer", "integer"),
1017 array((int) $a_status, $a_ass_id, $a_user_id));
1018 }
1019
1020/* // feedback functions
1021 function setStatusFeedback($a_status)
1022 {
1023 if(is_array($a_status))
1024 {
1025 $this->status_feedback = $a_status;
1026 return true;
1027 }
1028 }
1029 function getStatusFeedback()
1030 {
1031 return $this->status_feedback ? $this->status_feedback : array(0 => 0);
1032 }*/
1033
1037 function lookupStatusFeedbackOfUser($a_ass_id, $a_user_id)
1038 {
1039 return ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "feedback");
1040 }
1041
1045 function updateStatusFeedbackForUser($a_ass_id, $a_user_id, $a_status)
1046 {
1047 global $ilDB;
1048
1049 // #13741
1050 $ilDB->manipulateF("UPDATE exc_mem_ass_status ".
1051 "SET feedback = %s, feedback_time = %s ".
1052 " WHERE ass_id = %s AND usr_id = %s",
1053 array("integer", "timestamp", "integer", "integer"),
1054 array((int) $a_status, ($a_status ? ilUtil::now() : null),
1055 $a_ass_id, $a_user_id));
1056 }
1057
1061 static function lookupSentTimeOfUser($a_ass_id, $a_user_id)
1062 {
1064 ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "sent_time"));
1065 }
1066
1070 static function lookupFeedbackTimeOfUser($a_ass_id, $a_user_id)
1071 {
1073 ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "feedback_time"));
1074 }
1075
1079 static function lookupStatusTimeOfUser($a_ass_id, $a_user_id)
1080 {
1082 ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "status_time"));
1083 }
1084
1085 /*function getNotice()
1086 {
1087 return $this->notice ? $this->notice : array(0 => 0);
1088 }
1089
1090 function setNotice($a_notice)
1091 {
1092 if(is_array($a_notice))
1093 {
1094 $this->notice = $a_notice;
1095 return true;
1096 }
1097 return false;
1098 }*/
1099
1103 function lookupNoticeOfUser($a_ass_id, $a_user_id)
1104 {
1105 return ilExAssignment::lookupAssMemberField($a_ass_id, $a_user_id, "notice");
1106 }
1107
1111 function hasReturned($a_ass_id, $a_user_id)
1112 {
1113 global $ilDB;
1114
1115 $user_ids = self::getTeamMembersByAssignmentId($a_ass_id, $a_user_id);
1116 if(!$user_ids)
1117 {
1118 $user_ids = array($a_user_id);
1119 }
1120
1121 $result = $ilDB->query("SELECT returned_id FROM exc_returned".
1122 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
1123 " AND ".$ilDB->in("user_id", $user_ids, "", "integer"));
1124 return $ilDB->numRows($result);
1125 }
1126
1130 function getAllDeliveredFiles($a_exc_id, $a_ass_id)
1131 {
1132 global $ilDB;
1133
1134 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1135 $fs = new ilFSStorageExercise($a_exc_id, $a_ass_id);
1136
1137 $query = "SELECT * FROM exc_returned WHERE ass_id = ".
1138 $ilDB->quote($a_ass_id, "integer");
1139
1140 $res = $ilDB->query($query);
1141 while($row = $ilDB->fetchAssoc($res))
1142 {
1143 $row["timestamp"] = $row["ts"];
1144 $row["filename"] = $fs->getAbsoluteSubmissionPath().
1145 "/".$row["user_id"]."/".basename($row["filename"]);
1146 $delivered[] = $row;
1147 }
1148
1149 //$delivered = ilObjExercise::_fixFilenameArray($delivered);
1150
1151 return $delivered ? $delivered : array();
1152 }
1153
1157 function getDeliveredFiles($a_exc_id, $a_ass_id, $a_user_id, $a_filter_empty_filename = false)
1158 {
1159 global $ilDB;
1160
1161 $user_ids = self::getTeamMembersByAssignmentId($a_ass_id, $a_user_id);
1162 if(!$user_ids)
1163 {
1164 $user_ids = array($a_user_id);
1165 }
1166
1167 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1168 $fs = new ilFSStorageExercise($a_exc_id, $a_ass_id);
1169
1170 $result = $ilDB->query("SELECT * FROM exc_returned".
1171 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
1172 " AND ".$ilDB->in("user_id", $user_ids, "", "integer"));
1173
1174 $delivered_files = array();
1175 if ($ilDB->numRows($result))
1176 {
1177 while ($row = $ilDB->fetchAssoc($result))
1178 {
1179 if($a_filter_empty_filename && !$row["filename"])
1180 {
1181 continue;
1182 }
1183 $row["owner_id"] = $row["user_id"];
1184 $row["timestamp"] = $row["ts"];
1185 $row["timestamp14"] = substr($row["ts"], 0, 4).
1186 substr($row["ts"], 5, 2).substr($row["ts"], 8, 2).
1187 substr($row["ts"], 11, 2).substr($row["ts"], 14, 2).
1188 substr($row["ts"], 17, 2);
1189 $row["filename"] = $fs->getAbsoluteSubmissionPath().
1190 "/".$row["user_id"]."/".basename($row["filename"]);
1191 array_push($delivered_files, $row);
1192 }
1193 }
1194
1195 //$delivered_files = ilObjExercise::_fixFilenameArray($delivered_files);
1196 return $delivered_files;
1197 }
1198
1202 function deleteDeliveredFiles($a_exc_id, $a_ass_id, $file_id_array, $a_user_id)
1203 {
1204 global $ilDB;
1205
1206 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1207 $fs = new ilFSStorageExercise($a_exc_id, $a_ass_id);
1208
1209 if (count($file_id_array))
1210 {
1211 $team_id = self::getTeamIdByAssignment($a_ass_id, $a_user_id);
1212 if($team_id)
1213 {
1214 // #11733
1215 $user_ids = self::getTeamMembersByAssignmentId($a_ass_id, $a_user_id);
1216 if(!$user_ids)
1217 {
1218 return;
1219 }
1220 }
1221 else
1222 {
1223 $user_ids = array($a_user_id);
1224 }
1225
1226 $result = $ilDB->query("SELECT * FROM exc_returned".
1227 " WHERE ".$ilDB->in("returned_id", $file_id_array, false, "integer").
1228 " AND ".$ilDB->in("user_id", $user_ids, "", "integer"));
1229
1230 if ($ilDB->numRows($result))
1231 {
1232 $result_array = array();
1233 while ($row = $ilDB->fetchAssoc($result))
1234 {
1235 $row["timestamp"] = $row["ts"];
1236 array_push($result_array, $row);
1237 }
1238
1239 // delete the entries in the database
1240 $ilDB->manipulate("DELETE FROM exc_returned".
1241 " WHERE ".$ilDB->in("returned_id", $file_id_array, false, "integer").
1242 " AND ".$ilDB->in("user_id", $user_ids, "", "integer"));
1243
1244 // delete the files
1245 foreach ($result_array as $key => $value)
1246 {
1247 if($value["filename"])
1248 {
1249 if($team_id)
1250 {
1252 ilExAssignment::TEAM_LOG_REMOVE_FILE, $value["filetitle"]);
1253 }
1254
1255 $filename = $fs->getAbsoluteSubmissionPath().
1256 "/".$value["user_id"]."/".basename($value["filename"]);
1257 unlink($filename);
1258 }
1259 }
1260 }
1261 }
1262 }
1263
1270 static function deleteAllDeliveredFilesOfUser($a_exc_id, $a_user_id)
1271 {
1272 global $ilDB;
1273
1274 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1275
1276 $delete_ids = array();
1277
1278 // get the files and...
1279 $set = $ilDB->query("SELECT * FROM exc_returned ".
1280 " WHERE obj_id = ".$ilDB->quote($a_exc_id, "integer").
1281 " AND user_id = ".$ilDB->quote($a_user_id, "integer")
1282 );
1283 while ($rec = $ilDB->fetchAssoc($set))
1284 {
1285 $ass = new self($rec["ass_id"]);
1286 if($ass->getType() == self::TYPE_UPLOAD_TEAM)
1287 {
1288 // switch upload to other team member
1289 $team = self::getTeamMembersByAssignmentId($ass->getId(), $a_user_id);
1290 if(sizeof($team) > 1)
1291 {
1292 $new_owner = array_pop($team);
1293 while($new_owner == $a_user_id && sizeof($team))
1294 {
1295 $new_owner = array_pop($team);
1296 }
1297
1298 $ilDB->manipulate("UPDATE exc_returned".
1299 " SET user_id = ".$ilDB->quote($new_owner, "integer").
1300 " WHERE returned_id = ".$ilDB->quote($rec["returned_id"], "integer")
1301 );
1302
1303 // no need to delete
1304 continue;
1305 }
1306 }
1307
1308 $delete_ids[] = $rec["returned_id"];
1309
1310 $fs = new ilFSStorageExercise($a_exc_id, $rec["ass_id"]);
1311
1312 // ...delete files
1313 $filename = $fs->getAbsoluteSubmissionPath().
1314 "/".$a_user_id."/".basename($rec["filename"]);
1315 if (is_file($filename))
1316 {
1317 unlink($filename);
1318 }
1319 }
1320
1321 // delete exc_returned records
1322 if($delete_ids)
1323 {
1324 $ilDB->manipulate("DELETE FROM exc_returned".
1325 " WHERE ".$ilDB->in("returned_id", $delete_ids, "", "integer"));
1326 }
1327
1328 // delete il_exc_team records
1329 $ass_ids = array();
1330 foreach(self::getAssignmentDataOfExercise($a_exc_id) as $item)
1331 {
1332 self::updateStatusOfUser($item["id"], $a_user_id, "notgraded"); // #14900
1333
1334 $ass_ids[] = $item["id"];
1335 }
1336 if($ass_ids)
1337 {
1338 $ilDB->manipulate($d = "DELETE FROM il_exc_team WHERE ".
1339 "user_id = ".$ilDB->quote($a_user_id, "integer").
1340 " AND ".$ilDB->in("ass_id", $ass_ids, "", "integer")
1341 );
1342 }
1343 }
1344
1345
1349 function deliverReturnedFiles($a_exc_id, $a_ass_id, $a_user_id, $a_only_new = false, $a_peer_review_mask_filename = false)
1350 {
1351 global $ilUser, $ilDB;
1352
1353 // #11000 / #11785
1354 $is_team = true;
1355 $user_ids = self::getTeamMembersByAssignmentId($a_ass_id, $a_user_id);
1356 if(!$user_ids)
1357 {
1358 $is_team = false;
1359 $user_ids = array($a_user_id);
1360 }
1361
1362 // get last download time
1363 $and_str = "";
1364 if ($a_only_new)
1365 {
1366 $q = "SELECT download_time FROM exc_usr_tutor WHERE ".
1367 " ass_id = ".$ilDB->quote($a_ass_id, "integer")." AND ".
1368 $ilDB->in("usr_id", $user_ids, "", "integer")." AND ".
1369 " tutor_id = ".$ilDB->quote($ilUser->getId(), "integer");
1370 $lu_set = $ilDB->query($q);
1371 if ($lu_rec = $ilDB->fetchAssoc($lu_set))
1372 {
1373 if ($lu_rec["download_time"] > 0)
1374 {
1375 $and_str = " AND ts > ".$ilDB->quote($lu_rec["download_time"], "timestamp");
1376 }
1377 }
1378 }
1379
1380 foreach($user_ids as $user_id)
1381 {
1382 ilExAssignment::updateTutorDownloadTime($a_exc_id, $a_ass_id, $user_id);
1383 }
1384
1385 if($a_peer_review_mask_filename)
1386 {
1387 // process peer review sequence id
1388 $peer_id = null;
1389 foreach($this->ass->getPeerReviewsByGiver($ilUser->getId()) as $idx => $item)
1390 {
1391 if($item["peer_id"] == $a_user_id)
1392 {
1393 $peer_id = $idx+1;
1394 break;
1395 }
1396 }
1397 }
1398
1399 $query = "SELECT * FROM exc_returned".
1400 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
1401 " AND ".$ilDB->in("user_id", $user_ids, "", "integer").
1402 $and_str;
1403
1404 $result = $ilDB->query($query);
1405 $count = $ilDB->numRows($result);
1406 if ($count == 1)
1407 {
1408 $row = $ilDB->fetchAssoc($result);
1409
1410 switch(self::lookupType($a_ass_id))
1411 {
1412 case self::TYPE_BLOG:
1414 $row["filetitle"] = ilObjUser::_lookupName($row["user_id"]);
1415 $row["filetitle"] = ilObject::_lookupTitle($a_exc_id)." - ".
1416 self::lookupTitle($a_ass_id)." - ".
1417 $row["filetitle"]["firstname"]." ".
1418 $row["filetitle"]["lastname"]." (".
1419 $row["filetitle"]["login"].").zip";
1420 break;
1421
1422 default:
1423 break;
1424 }
1425
1426 if($a_peer_review_mask_filename)
1427 {
1428 $suffix = array_pop(explode(".", $row["filetitle"]));
1429 $row["filetitle"] = self::lookupTitle($a_ass_id)."_peer".$peer_id.".".$suffix;
1430 }
1431
1432 ilExAssignment::downloadSingleFile($a_exc_id, $a_ass_id, $row["user_id"],
1433 $row["filename"], $row["filetitle"]);
1434 }
1435 else if ($count > 0)
1436 {
1437 $array_files = array();
1438 $seq = 0;
1439 while ($row = $ilDB->fetchAssoc($result))
1440 {
1441 $src = basename($row["filename"]);
1442 if($a_peer_review_mask_filename)
1443 {
1444 $suffix = array_pop(explode(".", $src));
1445 $tgt = self::lookupTitle($a_ass_id)."_peer".$peer_id.
1446 "_".(++$seq).".".$suffix;
1447
1448 $array_files[$row["user_id"]][] = array($src, $tgt);
1449 }
1450 else
1451 {
1452 $array_files[$row["user_id"]][] = $src;
1453 }
1454 }
1455 ilExAssignment::downloadMultipleFiles($a_exc_id, $a_ass_id, $array_files,
1456 ($is_team ? null : $a_user_id), $is_team);
1457 }
1458 else
1459 {
1460 return false;
1461 }
1462
1463 return true;
1464 }
1465
1466 // Update the timestamp of the last download of current user (=tutor)
1470 function updateTutorDownloadTime($a_exc_id, $a_ass_id, $a_user_id)
1471 {
1472 global $ilUser, $ilDB;
1473
1474 $ilDB->manipulateF("DELETE FROM exc_usr_tutor ".
1475 "WHERE ass_id = %s AND usr_id = %s AND tutor_id = %s",
1476 array("integer", "integer", "integer"),
1477 array($a_ass_id, $a_user_id, $ilUser->getId()));
1478
1479 $ilDB->manipulateF("INSERT INTO exc_usr_tutor (ass_id, obj_id, usr_id, tutor_id, download_time) VALUES ".
1480 "(%s, %s, %s, %s, %s)",
1481 array("integer", "integer", "integer", "integer", "timestamp"),
1482 array($a_ass_id, $a_exc_id, $a_user_id, $ilUser->getId(), ilUtil::now()));
1483 }
1484
1488 function downloadSelectedFiles($a_exc_id, $a_ass_id, $a_user_id, $array_file_id)
1489 {
1490 global $ilDB;
1491
1492 if (count($array_file_id))
1493 {
1494 // #11785
1495 $is_team = true;
1496 $user_ids = self::getTeamMembersByAssignmentId($a_ass_id, $a_user_id);
1497 if(!$user_ids)
1498 {
1499 $is_team = false;
1500 $user_ids = array($a_user_id);
1501 }
1502
1503 $result = $ilDB->query("SELECT * FROM exc_returned WHERE ".
1504 $ilDB->in("returned_id", $array_file_id, false, "integer").
1505 " AND ".$ilDB->in("user_id", $user_ids, "", "integer"));
1506 if ($ilDB->numRows($result))
1507 {
1508 $array_found = array();
1509 while ($row = $ilDB->fetchAssoc($result))
1510 {
1511 $row["timestamp"] = $row["ts"];
1512 array_push($array_found, $row);
1513 }
1514 if (count($array_found) == 1)
1515 {
1516 // blog/portfolio submission
1517 if(is_numeric($array_found[0]["filetitle"]))
1518 {
1519 $ass = new ilExAssignment($array_found[0]["ass_id"]);
1520 if($ass->getType() == ilExAssignment::TYPE_BLOG ||
1521 $ass->getType() == ilExAssignment::TYPE_PORTFOLIO)
1522 {
1523 $user_data = ilObjUser::_lookupName($array_found[0]["user_id"]);
1524 $array_found[0]["filetitle"] = ilObject::_lookupTitle($array_found[0]["obj_id"])." - ".
1525 $ass->getTitle()." - ".
1526 $user_data["firstname"]." ".
1527 $user_data["lastname"]." (".
1528 $user_data["login"].").zip";
1529 }
1530 }
1531
1532 ilExAssignment::downloadSingleFile($a_exc_id, $a_ass_id, $array_found[0]["user_id"],
1533 $array_found[0]["filename"], $array_found[0]["filetitle"]);
1534 }
1535 else
1536 {
1537 $filenames = array();
1538 foreach ($array_found as $value)
1539 {
1540 $filenames[$value["user_id"]][] = basename($value["filename"]);
1541 }
1542 ilExAssignment::downloadMultipleFiles($a_exc_id, $a_ass_id,
1543 $filenames, ($is_team ? null : $a_user_id), $is_team);
1544 }
1545 }
1546 }
1547 }
1548
1552 function downloadSingleFile($a_exc_id, $a_ass_id, $a_user_id, $filename, $filetitle)
1553 {
1554 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1555 $fs = new ilFSStorageExercise($a_exc_id, $a_ass_id);
1556
1557 $filename = $fs->getAbsoluteSubmissionPath().
1558 "/".$a_user_id."/".basename($filename);
1559
1560 require_once "./Services/Utilities/classes/class.ilUtil.php";
1561 ilUtil::deliverFile($filename, $filetitle);
1562 }
1563
1567// @todo: check whether files of multiple users are downloaded this way
1568 function downloadMultipleFiles($a_exc_id, $a_ass_id, $array_filenames,
1569 $a_user_id, $a_multi_user = false)
1570 {
1571 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1572 $fs = new ilFSStorageExercise($a_exc_id, $a_ass_id);
1573
1574 require_once "./Services/Utilities/classes/class.ilUtil.php";
1575 $cdir = getcwd();
1576
1577 $zip = PATH_TO_ZIP;
1578 $tmpdir = ilUtil::ilTempnam();
1579 $tmpfile = ilUtil::ilTempnam();
1580 $tmpzipfile = $tmpfile . ".zip";
1581
1582 ilUtil::makeDir($tmpdir);
1583 chdir($tmpdir);
1584
1585 $assTitle = ilExAssignment::lookupTitle($a_ass_id);
1586 $deliverFilename = str_replace(" ", "_", $assTitle);
1587 if ($a_user_id > 0 && !$a_multi_user)
1588 {
1589 $userName = ilObjUser::_lookupName($a_user_id);
1590 $deliverFilename .= "_".$userName["lastname"]."_".$userName["firstname"];
1591 }
1592 else
1593 {
1594 $deliverFilename .= "_files";
1595 }
1596 $orgDeliverFilename = trim($deliverFilename);
1597 $deliverFilename = ilUtil::getASCIIFilename($orgDeliverFilename);
1598 ilUtil::makeDir($tmpdir."/".$deliverFilename);
1599 chdir($tmpdir."/".$deliverFilename);
1600
1601 //copy all files to a temporary directory and remove them afterwards
1602 $parsed_files = $duplicates = array();
1603 foreach ($array_filenames as $user_id => $files)
1604 {
1605 $pathname = $fs->getAbsoluteSubmissionPath()."/".$user_id;
1606
1607 foreach($files as $filename)
1608 {
1609 // peer review masked filenames, see deliverReturnedFiles()
1610 if(is_array($filename))
1611 {
1612 $newFilename = $filename[1];
1613 $filename = $filename[0];
1614 }
1615 else
1616 {
1617 // remove timestamp
1618 $newFilename = trim($filename);
1619 $pos = strpos($newFilename , "_");
1620 if ($pos !== false)
1621 {
1622 $newFilename = substr($newFilename, $pos + 1);
1623 }
1624 // #11070
1625 $chkName = strtolower($newFilename);
1626 if(array_key_exists($chkName, $duplicates))
1627 {
1628 $suffix = strrpos($newFilename, ".");
1629 $newFilename = substr($newFilename, 0, $suffix).
1630 " (".(++$duplicates[$chkName]).")".
1631 substr($newFilename, $suffix);
1632 }
1633 else
1634 {
1635 $duplicates[$chkName] = 1;
1636 }
1637 }
1638 $newFilename = $tmpdir.DIRECTORY_SEPARATOR.$deliverFilename.DIRECTORY_SEPARATOR.$newFilename;
1639 // copy to temporal directory
1640 $oldFilename = $pathname.DIRECTORY_SEPARATOR.$filename;
1641 if (!copy ($oldFilename, $newFilename))
1642 {
1643 echo 'Could not copy '.$oldFilename.' to '.$newFilename;
1644 }
1645 touch($newFilename, filectime($oldFilename));
1646 $parsed_files[] = ilUtil::escapeShellArg($deliverFilename.DIRECTORY_SEPARATOR.basename($newFilename));
1647 }
1648 }
1649
1650 chdir($tmpdir);
1651 $zipcmd = $zip." ".ilUtil::escapeShellArg($tmpzipfile)." ".join($parsed_files, " ");
1652
1653 exec($zipcmd);
1654 ilUtil::delDir($tmpdir);
1655
1656 chdir($cdir);
1657 ilUtil::deliverFile($tmpzipfile, $orgDeliverFilename.".zip", "", false, true);
1658 exit;
1659 }
1660
1666 function downloadAllDeliveredFiles($a_exc_id, $a_ass_id, $members)
1667 {
1668 global $lng, $ilObjDataCache, $ilias;
1669
1670 include_once "./Services/Utilities/classes/class.ilUtil.php";
1671 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1672
1673 $storage = new ilFSStorageExercise($a_exc_id, $a_ass_id);
1674 $storage->create();
1675
1676 ksort($members);
1677 //$savepath = $this->getExercisePath() . "/" . $this->obj_id . "/";
1678 $savepath = $storage->getAbsoluteSubmissionPath();
1679 $cdir = getcwd();
1680
1681
1682 // important check: if the directory does not exist
1683 // ILIAS stays in the current directory (echoing only a warning)
1684 // and the zip command below archives the whole ILIAS directory
1685 // (including the data directory) and sends a mega file to the user :-o
1686 if (!is_dir($savepath))
1687 {
1688 return;
1689 }
1690 // Safe mode fix
1691// chdir($this->getExercisePath());
1692 chdir($storage->getTempPath());
1693 $zip = PATH_TO_ZIP;
1694
1695 // check first, if we have enough free disk space to copy all files to temporary directory
1696 $tmpdir = ilUtil::ilTempnam();
1697 ilUtil::makeDir($tmpdir);
1698 chdir($tmpdir);
1699
1700
1701 $dirsize = 0;
1702 foreach ($members as $id => $object) {
1703 $directory = $savepath.DIRECTORY_SEPARATOR.$id;
1704 $dirsize += ilUtil::dirsize($directory);
1705 }
1706 if ($dirsize > disk_free_space($tmpdir)) {
1707 return -1;
1708 }
1709
1710 $ass_type = self::lookupType($a_ass_id);
1711
1712 // copy all member directories to the temporary folder
1713 // switch from id to member name and append the login if the member name is double
1714 // ensure that no illegal filenames will be created
1715 // remove timestamp from filename
1716 $cache = array();
1717 foreach ($members as $id => $user)
1718 {
1719 $sourcedir = $savepath.DIRECTORY_SEPARATOR.$id;
1720 if (!is_dir($sourcedir))
1721 continue;
1722 $userName = ilObjUser::_lookupName($id);
1723 //$directory = ilUtil::getASCIIFilename(trim($userName["lastname"])."_".trim($userName["firstname"]));
1724 $directory = ilUtil::getASCIIFilename(trim($userName["lastname"])."_".
1725 trim($userName["firstname"])."_".trim($userName["login"])."_".$userName["user_id"]);
1726 /*if (array_key_exists($directory, $cache))
1727 {
1728 // first try is to append the login;
1729 $directory = ilUtil::getASCIIFilename($directory."_".trim(ilObjUser::_lookupLogin($id)));
1730 if (array_key_exists($directory, $cache)) {
1731 // second and secure: append the user id as well.
1732 $directory .= "_".$id;
1733 }
1734 }*/
1735
1736 $cache[$directory] = $directory;
1737 ilUtil::makeDir ($directory);
1738 $sourcefiles = scandir($sourcedir);
1739 $duplicates = array();
1740 foreach ($sourcefiles as $sourcefile) {
1741 if ($sourcefile == "." || $sourcefile == "..")
1742 {
1743 continue;
1744 }
1745
1746 $targetfile = trim(basename($sourcefile));
1747 $pos = strpos($targetfile, "_");
1748 if ($pos !== false)
1749 {
1750 $targetfile= substr($targetfile, $pos + 1);
1751 }
1752
1753 // #14536
1754 if(array_key_exists($targetfile, $duplicates))
1755 {
1756 $suffix = strrpos($targetfile, ".");
1757 $targetfile = substr($targetfile, 0, $suffix).
1758 " (".(++$duplicates[$targetfile]).")".
1759 substr($targetfile, $suffix);
1760 }
1761 else
1762 {
1763 $duplicates[$targetfile] = 1;
1764 }
1765
1766 $targetfile = $directory.DIRECTORY_SEPARATOR.$targetfile;
1767 $sourcefile = $sourcedir.DIRECTORY_SEPARATOR.$sourcefile;
1768
1769 if (!copy ($sourcefile, $targetfile))
1770 {
1771 //echo 'Could not copy '.$sourcefile.' to '.$targetfile;
1772 $ilias->raiseError('Could not copy '.basename($sourcefile)." to '".$targetfile."'.",
1773 $ilias->error_obj->MESSAGE);
1774 }
1775 else
1776 {
1777 // preserve time stamp
1778 touch($targetfile, filectime($sourcefile));
1779
1780 // blogs and portfolios are stored as zip and have to be unzipped
1781 if($ass_type == ilExAssignment::TYPE_PORTFOLIO ||
1782 $ass_type == ilExAssignment::TYPE_BLOG)
1783 {
1784 ilUtil::unzip($targetfile);
1785 unlink($targetfile);
1786 }
1787 }
1788
1789 }
1790 }
1791
1792 $tmpfile = ilUtil::ilTempnam();
1793 $tmpzipfile = $tmpfile . ".zip";
1794 // Safe mode fix
1795 $zipcmd = $zip." -r ".ilUtil::escapeShellArg($tmpzipfile)." .";
1796 exec($zipcmd);
1797 ilUtil::delDir($tmpdir);
1798
1799 $assTitle = ilExAssignment::lookupTitle($a_ass_id)."_".$a_ass_id;
1800 chdir($cdir);
1801 ilUtil::deliverFile($tmpzipfile, (strlen($assTitle) == 0
1802 ? strtolower($lng->txt("exc_assignment"))
1803 : $assTitle). ".zip", "", false, true);
1804 }
1805
1809 function updateNoticeForUser($a_ass_id, $a_user_id, $a_notice)
1810 {
1811 global $ilDB;
1812
1813 // #12181 / #13741
1814 $ilDB->manipulate("UPDATE exc_mem_ass_status".
1815 " SET notice = ".$ilDB->quote($a_notice, "text").
1816 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
1817 " AND usr_id = ".$ilDB->quote($a_user_id, "integer").
1818 " AND ".$ilDB->equalsNot("notice", $a_notice, "text", true));
1819 }
1820
1824 function _getReturned($a_ass_id)
1825 {
1826 global $ilDB;
1827
1828 $query = "SELECT DISTINCT(usr_id) as ud FROM exc_mem_ass_status ".
1829 "WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer")." ".
1830 "AND returned = 1";
1831
1832 $res = $ilDB->query($query);
1833 while($row = $ilDB->fetchObject($res))
1834 {
1835 $usr_ids[] = $row->ud;
1836 }
1837
1838 return $usr_ids ? $usr_ids : array();
1839 }
1840
1848 static function getLastSubmission($a_ass_id, $a_user_id)
1849 {
1850 global $ilDB, $lng;
1851
1852 // team upload?
1853 $user_ids = self::getTeamMembersByAssignmentId($a_ass_id, $a_user_id);
1854 if(!$user_ids)
1855 {
1856 $user_ids = array($a_user_id);
1857 }
1858
1859 $ilDB->setLimit(1);
1860
1861 $q = "SELECT obj_id,user_id,ts FROM exc_returned".
1862 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
1863 " AND ".$ilDB->in("user_id", $user_ids, "", "integer").
1864 " ORDER BY ts DESC";
1865
1866 $usr_set = $ilDB->query($q);
1867
1868 $array = $ilDB->fetchAssoc($usr_set);
1869 if ($array["ts"]==NULL)
1870 {
1871 return false;
1872 }
1873 else
1874 {
1875 return ilUtil::getMySQLTimestamp($array["ts"]);
1876 }
1877 }
1878
1882 static function lookupAnyExerciseSent($a_exc_id, $a_ass_id)
1883 {
1884 global $ilDB;
1885
1886 $q = "SELECT count(*) AS cnt FROM exc_mem_ass_status".
1887 " WHERE NOT sent_time IS NULL".
1888 " AND ass_id = ".$ilDB->quote($a_ass_id, "integer")." ".
1889 " ";
1890 $set = $ilDB->query($q);
1891 $rec = $ilDB->fetchAssoc($set);
1892
1893 if ($rec["cnt"] > 0)
1894 {
1895 return true;
1896 }
1897 else
1898 {
1899 return false;
1900 }
1901 }
1902
1907 static function lookupUpdatedSubmission($ass_id, $member_id)
1908 {
1909 global $ilDB, $lng;
1910
1911 // team upload?
1912 $user_ids = self::getTeamMembersByAssignmentId($ass_id, $member_id);
1913 if(!$user_ids)
1914 {
1915 $user_ids = array($member_id);
1916 }
1917
1918 $q="SELECT exc_mem_ass_status.status_time, exc_returned.ts ".
1919 "FROM exc_mem_ass_status, exc_returned ".
1920 "WHERE exc_mem_ass_status.status_time < exc_returned.ts ".
1921 "AND NOT exc_mem_ass_status.status_time IS NULL ".
1922 "AND exc_returned.ass_id = exc_mem_ass_status.ass_id ".
1923 "AND exc_returned.user_id = exc_mem_ass_status.usr_id ".
1924 "AND exc_returned.ass_id=".$ilDB->quote($ass_id, "integer").
1925 " AND ".$ilDB->in("exc_returned.user_id", $user_ids, "", "integer");
1926
1927 $usr_set = $ilDB->query($q);
1928
1929 $array = $ilDB->fetchAssoc($usr_set);
1930
1931 if (count($array)==0)
1932 {
1933 return 0;
1934 }
1935 else
1936 {
1937 return 1;
1938 }
1939
1940 }
1941
1946 static function lookupNewFiles($ass_id, $member_id)
1947 {
1948 global $ilDB, $ilUser;
1949
1950 // team upload?
1951 $user_ids = self::getTeamMembersByAssignmentId($ass_id, $member_id);
1952 if(!$user_ids)
1953 {
1954 $user_ids = array($member_id);
1955 }
1956
1957 $q = "SELECT exc_returned.returned_id AS id ".
1958 "FROM exc_usr_tutor, exc_returned ".
1959 "WHERE exc_returned.ass_id = exc_usr_tutor.ass_id ".
1960 " AND exc_returned.user_id = exc_usr_tutor.usr_id ".
1961 " AND exc_returned.ass_id = ".$ilDB->quote($ass_id, "integer").
1962 " AND ".$ilDB->in("exc_returned.user_id", $user_ids, "", "integer").
1963 " AND exc_usr_tutor.tutor_id = ".$ilDB->quote($ilUser->getId(), "integer").
1964 " AND exc_usr_tutor.download_time < exc_returned.ts ";
1965
1966 $new_up_set = $ilDB->query($q);
1967
1968 $new_up = array();
1969 while ($new_up_rec = $ilDB->fetchAssoc($new_up_set))
1970 {
1971 $new_up[] = $new_up_rec["id"];
1972 }
1973
1974 return $new_up;
1975 }
1976
1980 function getMemberListData($a_exc_id, $a_ass_id)
1981 {
1982 global $ilDB;
1983
1984 $mem = array();
1985
1986 // first get list of members from member table
1987 $set = $ilDB->query("SELECT ud.usr_id, ud.lastname, ud.firstname, ud.login".
1988 " FROM exc_members excm".
1989 " JOIN usr_data ud ON (ud.usr_id = excm.usr_id)".
1990 " WHERE excm.obj_id = ".$ilDB->quote($a_exc_id, "integer"));
1991 while($rec = $ilDB->fetchAssoc($set))
1992 {
1993 $mem[$rec["usr_id"]] =
1994 array(
1995 "name" => $rec["lastname"].", ".$rec["firstname"],
1996 "login" => $rec["login"],
1997 "usr_id" => $rec["usr_id"],
1998 "lastname" => $rec["lastname"],
1999 "firstname" => $rec["firstname"]
2000 );
2001 }
2002
2003 $q = "SELECT * FROM exc_mem_ass_status ".
2004 "WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer");
2005 $set = $ilDB->query($q);
2006 while($rec = $ilDB->fetchAssoc($set))
2007 {
2008 if (isset($mem[$rec["usr_id"]]))
2009 {
2010 $mem[$rec["usr_id"]]["sent_time"] = $rec["sent_time"];
2011 $mem[$rec["usr_id"]]["submission"] = ilExAssignment::getLastSubmission($a_ass_id, $rec["usr_id"]);
2012 $mem[$rec["usr_id"]]["status_time"] = $rec["status_time"];
2013 $mem[$rec["usr_id"]]["feedback_time"] = $rec["feedback_time"];
2014 $mem[$rec["usr_id"]]["notice"] = $rec["notice"];
2015 $mem[$rec["usr_id"]]["status"] = $rec["status"];
2016 }
2017 }
2018 return $mem;
2019 }
2020
2024 static function createNewUserRecords($a_user_id, $a_exc_id)
2025 {
2026 global $ilDB;
2027
2028 $ass_data = ilExAssignment::getAssignmentDataOfExercise($a_exc_id);
2029 foreach ($ass_data as $ass)
2030 {
2031//echo "-".$ass["id"]."-".$a_user_id."-";
2032 $ilDB->replace("exc_mem_ass_status", array(
2033 "ass_id" => array("integer", $ass["id"]),
2034 "usr_id" => array("integer", $a_user_id)
2035 ), array(
2036 "status" => array("text", "notgraded")
2037 ));
2038 }
2039 }
2040
2044 static function createNewAssignmentRecords($a_ass_id, $a_exc)
2045 {
2046 global $ilDB;
2047
2048 include_once("./Modules/Exercise/classes/class.ilExerciseMembers.php");
2049 $exmem = new ilExerciseMembers($a_exc);
2050 $mems = $exmem->getMembers();
2051
2052 foreach ($mems as $mem)
2053 {
2054 $ilDB->replace("exc_mem_ass_status", array(
2055 "ass_id" => array("integer", $a_ass_id),
2056 "usr_id" => array("integer", $mem)
2057 ), array(
2058 "status" => array("text", "notgraded")
2059 ));
2060 }
2061 }
2062
2067 function uploadAssignmentFiles($a_files)
2068 {
2069 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
2070 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
2071 $storage->create();
2072 $storage->uploadAssignmentFiles($a_files);
2073 }
2074
2075 //
2076 // TEAM UPLOAD
2077 //
2078
2088 function getTeamId($a_user_id, $a_create_on_demand = false)
2089 {
2090 global $ilDB;
2091
2092 $sql = "SELECT id FROM il_exc_team".
2093 " WHERE ass_id = ".$ilDB->quote($this->getId(), "integer").
2094 " AND user_id = ".$ilDB->quote($a_user_id, "integer");
2095 $set = $ilDB->query($sql);
2096 $row = $ilDB->fetchAssoc($set);
2097 $id = $row["id"];
2098
2099 if(!$id && $a_create_on_demand)
2100 {
2101 $id = $ilDB->nextId("il_exc_team");
2102
2103 $fields = array("id" => array("integer", $id),
2104 "ass_id" => array("integer", $this->getId()),
2105 "user_id" => array("integer", $a_user_id));
2106 $ilDB->insert("il_exc_team", $fields);
2107
2108 self::writeTeamLog($id, self::TEAM_LOG_CREATE_TEAM);
2109 self::writeTeamLog($id, self::TEAM_LOG_ADD_MEMBER,
2110 ilObjUser::_lookupFullname($a_user_id));
2111 }
2112
2113 return $id;
2114 }
2115
2122 function getTeamMembers($a_team_id)
2123 {
2124 global $ilDB;
2125
2126 $ids = array();
2127
2128 $sql = "SELECT user_id".
2129 " FROM il_exc_team".
2130 " WHERE ass_id = ".$ilDB->quote($this->getId(), "integer").
2131 " AND id = ".$ilDB->quote($a_team_id, "integer");
2132 $set = $ilDB->query($sql);
2133 while($row = $ilDB->fetchAssoc($set))
2134 {
2135 $ids[] = $row["user_id"];
2136 }
2137
2138 return $ids;
2139 }
2140
2147 {
2148 global $ilDB;
2149
2150 $ids = array();
2151
2152 $sql = "SELECT user_id".
2153 " FROM il_exc_team".
2154 " WHERE ass_id = ".$ilDB->quote($this->getId(), "integer");
2155 $set = $ilDB->query($sql);
2156 while($row = $ilDB->fetchAssoc($set))
2157 {
2158 $ids[] = $row["user_id"];
2159 }
2160
2161 return $ids;
2162 }
2163
2171 function addTeamMember($a_team_id, $a_user_id, $a_exc_ref_id = null)
2172 {
2173 global $ilDB;
2174
2175 $members = $this->getTeamMembers($a_team_id);
2176 if(!in_array($a_user_id, $members))
2177 {
2178 $fields = array("id" => array("integer", $a_team_id),
2179 "ass_id" => array("integer", $this->getId()),
2180 "user_id" => array("integer", $a_user_id));
2181 $ilDB->insert("il_exc_team", $fields);
2182
2183 if($a_exc_ref_id)
2184 {
2185 $this->sendNotification($a_exc_ref_id, $a_user_id, "add");
2186 }
2187
2188 self::writeTeamLog($a_team_id, self::TEAM_LOG_ADD_MEMBER,
2189 ilObjUser::_lookupFullname($a_user_id));
2190 }
2191 }
2192
2200 function removeTeamMember($a_team_id, $a_user_id, $a_exc_ref_id)
2201 {
2202 global $ilDB;
2203
2204 $sql = "DELETE FROM il_exc_team".
2205 " WHERE ass_id = ".$ilDB->quote($this->getId(), "integer").
2206 " AND id = ".$ilDB->quote($a_team_id, "integer").
2207 " AND user_id = ".$ilDB->quote($a_user_id, "integer");
2208 $ilDB->manipulate($sql);
2209
2210 $this->sendNotification($a_exc_ref_id, $a_user_id, "rmv");
2211
2212 self::writeTeamLog($a_team_id, self::TEAM_LOG_REMOVE_MEMBER,
2213 ilObjUser::_lookupFullname($a_user_id));
2214 }
2215
2223 public static function getTeamMembersByAssignmentId($a_ass_id, $a_user_id)
2224 {
2225 global $ilDB;
2226
2227 $ids = array();
2228
2229 $team_id = self::getTeamIdByAssignment($a_ass_id, $a_user_id);
2230 if($team_id)
2231 {
2232 $set = $ilDB->query("SELECT user_id".
2233 " FROM il_exc_team".
2234 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
2235 " AND id = ". $ilDB->quote($team_id, "integer"));
2236 while($row = $ilDB->fetchAssoc($set))
2237 {
2238 $ids[] = $row["user_id"];
2239 }
2240 }
2241
2242 return $ids;
2243 }
2244
2252 public static function getTeamIdByAssignment($a_ass_id, $a_user_id)
2253 {
2254 global $ilDB;
2255
2256 $result = $ilDB->query("SELECT type".
2257 " FROM exc_assignment".
2258 " WHERE id = ".$ilDB->quote($a_ass_id, "integer"));
2259 $type = $ilDB->fetchAssoc($result);
2260
2261 if($type["type"] == self::TYPE_UPLOAD_TEAM)
2262 {
2263 $set = $ilDB->query("SELECT id".
2264 " FROM il_exc_team".
2265 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
2266 " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
2267 $team_id = $ilDB->fetchAssoc($set);
2268 return $team_id["id"];
2269 }
2270 }
2271
2278 public static function getAssignmentTeamMap($a_ass_id)
2279 {
2280 global $ilDB;
2281
2282 $map = array();
2283
2284 $sql = "SELECT * FROM il_exc_team".
2285 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer");
2286 $set = $ilDB->query($sql);
2287 while($row = $ilDB->fetchAssoc($set))
2288 {
2289 $map[$row["user_id"]] = $row["id"];
2290 }
2291
2292 return $map;
2293 }
2294
2302 public static function writeTeamLog($a_team_id, $a_action, $a_details = null)
2303 {
2304 global $ilDB, $ilUser;
2305
2306 $fields = array(
2307 "team_id" => array("integer", $a_team_id),
2308 "user_id" => array("integer", $ilUser->getId()),
2309 "action" => array("integer", $a_action),
2310 "details" => array("text", $a_details),
2311 "tstamp" => array("integer", time())
2312 );
2313
2314 $ilDB->insert("il_exc_team_log", $fields);
2315 }
2316
2323 public static function getTeamLog($a_team_id)
2324 {
2325 global $ilDB;
2326
2327 $res = array();
2328
2329 $sql = "SELECT * FROM il_exc_team_log".
2330 " WHERE team_id = ".$ilDB->quote($a_team_id, "integer").
2331 " ORDER BY tstamp DESC";
2332 $set = $ilDB->query($sql);
2333 while($row = $ilDB->fetchAssoc($set))
2334 {
2335 $res[] = $row;
2336 }
2337 return $res;
2338 }
2339
2347 public function sendNotification($a_exc_ref_id, $a_user_id, $a_action)
2348 {
2349 global $ilUser;
2350
2351 // no need to notify current user
2352 if($ilUser->getId() == $a_user_id)
2353 {
2354 return;
2355 }
2356
2357 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
2358 $ntf = new ilSystemNotification();
2359 $ntf->setLangModules(array("exc"));
2360 $ntf->setRefId($a_exc_ref_id);
2361 $ntf->setChangedByUserId($ilUser->getId());
2362 $ntf->setSubjectLangId('exc_team_notification_subject_'.$a_action);
2363 $ntf->setIntroductionLangId('exc_team_notification_body_'.$a_action);
2364 $ntf->addAdditionalInfo("exc_assignment", $this->getTitle());
2365 $ntf->setGotoLangId('exc_team_notification_link');
2366 $ntf->setReasonLangId('exc_team_notification_reason');
2367 $ntf->sendMail(array($a_user_id));
2368 }
2369
2370 public static function getDownloadedFilesInfoForTableGUIS($a_parent_obj, $a_exercise_id, $a_ass_type, $a_ass_id, $a_user_id, $a_parent_cmd = null)
2371 {
2372 global $lng, $ilCtrl;
2373
2374 $result = array();
2375 $result["files"]["count"] = "---";
2376
2377 $ilCtrl->setParameter($a_parent_obj, "ass_id", $a_ass_id);
2378
2379 // submission:
2380 // see if files have been resubmmited after solved
2381 $last_sub = self::getLastSubmission($a_ass_id, $a_user_id);
2382 if ($last_sub)
2383 {
2384 $last_sub = ilDatePresentation::formatDate(new ilDateTime($last_sub,IL_CAL_DATETIME));
2385 }
2386 else
2387 {
2388 $last_sub = "---";
2389 }
2390 /* #13741 - status_time has been reduced to grading (mark/status)
2391 if (ilExAssignment::lookupUpdatedSubmission($a_ass_id, $a_user_id) == 1)
2392 {
2393 $last_sub = "<b>".$last_sub."</b>";
2394 }
2395 */
2396 $result["last_submission"]["txt"] = $lng->txt("exc_last_submission");
2397 $result["last_submission"]["value"] = $last_sub;
2398
2399 // assignment type specific
2400 switch($a_ass_type)
2401 {
2403 // data is merged by team - see above
2404 // fallthrough
2405
2407 // nr of submitted files
2408 $result["files"]["txt"] = $lng->txt("exc_files_returned");
2409 $sub_cnt = count(ilExAssignment::getDeliveredFiles($a_exercise_id, $a_ass_id, $a_user_id));
2410 $new = ilExAssignment::lookupNewFiles($a_ass_id, $a_user_id);
2411 if (count($new) > 0)
2412 {
2413 $sub_cnt.= " ".sprintf($lng->txt("cnt_new"),count($new));
2414 }
2415 $result["files"]["count"] = $sub_cnt;
2416
2417 // download command
2418 $ilCtrl->setParameter($a_parent_obj, "member_id", $a_user_id);
2419
2420 if ($sub_cnt > 0)
2421 {
2422 $result["files"]["download_url"] =
2423 $ilCtrl->getLinkTarget($a_parent_obj, "downloadReturned");
2424
2425 if (count($new) <= 0)
2426 {
2427 $result["files"]["download_txt"] = $lng->txt("exc_download_files");
2428 }
2429 else
2430 {
2431 $result["files"]["download_txt"] = $lng->txt("exc_download_all");
2432 }
2433
2434 // download new files only
2435 if (count($new) > 0)
2436 {
2437 $result["files"]["download_new_url"] =
2438 $ilCtrl->getLinkTarget($a_parent_obj, "downloadNewReturned");
2439
2440 $result["files"]["download_new_txt"] = $lng->txt("exc_download_new");
2441 }
2442 }
2443 break;
2444
2446 $result["files"]["txt"] =$lng->txt("exc_blog_returned");
2447 $blogs = ilExAssignment::getDeliveredFiles($a_exercise_id, $a_ass_id, $a_user_id);
2448 if($blogs)
2449 {
2450 $blogs = array_pop($blogs);
2451 if($blogs && substr($blogs["filename"], -1) != "/")
2452 {
2453 $result["files"]["count"] = 1;
2454
2455 $ilCtrl->setParameter($a_parent_obj, "member_id", $a_user_id);
2456 $result["files"]["download_url"] =
2457 $ilCtrl->getLinkTarget($a_parent_obj, "downloadReturned");
2458 $ilCtrl->setParameter($a_parent_obj, "member_id", "");
2459
2460 $result["files"]["download_txt"] = $lng->txt("exc_download_files");
2461 }
2462 }
2463 break;
2464
2466 $result["files"]["txt"] = $lng->txt("exc_portfolio_returned");
2467 $portfolios = ilExAssignment::getDeliveredFiles($a_exercise_id, $a_ass_id, $a_user_id);
2468 if($portfolios)
2469 {
2470 $portfolios = array_pop($portfolios);
2471 if($portfolios && substr($portfolios["filename"], -1) != "/")
2472 {
2473 $result["files"]["count"] = 1;
2474
2475 $ilCtrl->setParameter($a_parent_obj, "member_id", $a_user_id);
2476 $result["files"]["download_url"] =
2477 $ilCtrl->getLinkTarget($a_parent_obj, "downloadReturned");
2478 $ilCtrl->setParameter($a_parent_obj, "member_id", "");
2479
2480 $result["files"]["download_txt"] = $lng->txt("exc_download_files");
2481 }
2482 }
2483 break;
2484
2486 $result["files"]["txt"] = $lng->txt("exc_files_returned_text");
2487 $files = ilExAssignment::getDeliveredFiles($a_exercise_id, $a_ass_id, $a_user_id);
2488 if($files)
2489 {
2490 $result["files"]["count"] = 1;
2491
2492 $files = array_shift($files);
2493 if(trim($files["atext"]))
2494 {
2495 // #11397
2496 if($a_parent_cmd)
2497 {
2498 $ilCtrl->setParameter($a_parent_obj, "grd", (($a_parent_cmd == "members") ? 1 : 2));
2499 }
2500 $ilCtrl->setParameter($a_parent_obj, "member_id", $a_user_id);
2501 $result["files"]["download_url"] =
2502 $ilCtrl->getLinkTarget($a_parent_obj, "showAssignmentText");
2503 $ilCtrl->setParameter($a_parent_obj, "member_id", "");
2504 $ilCtrl->setParameter($a_parent_obj, "grd", "");
2505
2506 $result["files"]["download_txt"] = $lng->txt("exc_text_assignment_show");
2507 }
2508 }
2509 break;
2510 }
2511
2512 return $result;
2513 }
2514
2515 public function hasPeerReviewGroups()
2516 {
2517 global $ilDB;
2518
2519 $set = $ilDB->query("SELECT count(*) cnt".
2520 " FROM exc_assignment_peer".
2521 " WHERE ass_id = ".$ilDB->quote($this->getId(), "integer"));
2522 $cnt = $ilDB->fetchAssoc($set);
2523 return (bool)$cnt["cnt"];
2524 }
2525
2526 protected function getValidPeerReviewUsers()
2527 {
2528 global $ilDB;
2529
2530 $user_ids = array();
2531
2532 // returned / assigned ?!
2533 $set = $ilDB->query("SELECT DISTINCT(user_id)".
2534 " FROM exc_returned".
2535 " WHERE ass_id = ".$ilDB->quote($this->getId(), "integer"));
2536 while($row = $ilDB->fetchAssoc($set))
2537 {
2538 $user_ids[] = $row["user_id"];
2539 }
2540
2541 return $user_ids;
2542 }
2543
2544 protected function initPeerReviews()
2545 {
2546 global $ilDB;
2547
2548 // only if assignment is through
2549 if(!$this->getDeadline() || $this->getDeadline() > time())
2550 {
2551 return false;
2552 }
2553
2554 if(!$this->hasPeerReviewGroups())
2555 {
2556 $user_ids = $this->getValidPeerReviewUsers();
2557
2558 // forever alone
2559 if(sizeof($user_ids) < 2)
2560 {
2561 return false;
2562 }
2563
2564 $rater_ids = $user_ids;
2565 $matrix = array();
2566
2567 $max = min(sizeof($user_ids)-1, $this->getPeerReviewMin());
2568 for($loop = 0; $loop < $max; $loop++)
2569 {
2570 $run_ids = array_combine($user_ids, $user_ids);
2571
2572 foreach($rater_ids as $rater_id)
2573 {
2574 $possible_peer_ids = $run_ids;
2575
2576 // may not rate himself
2577 unset($possible_peer_ids[$rater_id]);
2578
2579 // already has linked peers
2580 if(array_key_exists($rater_id, $matrix))
2581 {
2582 $possible_peer_ids = array_diff($possible_peer_ids, $matrix[$rater_id]);
2583 }
2584
2585 // #15665 / #15883
2586 if(!sizeof($possible_peer_ids))
2587 {
2588 // no more possible peers left? start over with all valid users
2589 $run_ids = array_combine($user_ids, $user_ids);
2590
2591 // see above
2592 $possible_peer_ids = $run_ids;
2593
2594 // may not rate himself
2595 unset($possible_peer_ids[$rater_id]);
2596
2597 // already has linked peers
2598 if(array_key_exists($rater_id, $matrix))
2599 {
2600 $possible_peer_ids = array_diff($possible_peer_ids, $matrix[$rater_id]);
2601 }
2602 }
2603
2604 // #14947
2605 if(sizeof($possible_peer_ids))
2606 {
2607 $peer_id = array_rand($possible_peer_ids);
2608 if(!array_key_exists($rater_id, $matrix))
2609 {
2610 $matrix[$rater_id] = array();
2611 }
2612 $matrix[$rater_id][] = $peer_id;
2613 }
2614
2615 // remove peer_id from possible ids in this run
2616 unset($run_ids[$peer_id]);
2617 }
2618 }
2619
2620 foreach($matrix as $rater_id => $peer_ids)
2621 {
2622 foreach($peer_ids as $peer_id)
2623 {
2624 $ilDB->manipulate("INSERT INTO exc_assignment_peer".
2625 " (ass_id, giver_id, peer_id)".
2626 " VALUES (".$ilDB->quote($this->getId(), "integer").
2627 ", ".$ilDB->quote($rater_id, "integer").
2628 ", ".$ilDB->quote($peer_id, "integer").")");
2629 }
2630 }
2631
2632 }
2633 return true;
2634 }
2635
2637 {
2638 if($this->hasPeerReviewFileUpload())
2639 {
2640 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
2641 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
2642 $storage->deletePeerReviewUploads();
2643 }
2644 }
2645
2646 public function resetPeerReviews()
2647 {
2648 global $ilDB;
2649
2650 if($this->hasPeerReviewGroups())
2651 {
2652 // ratings
2653 foreach($this->getAllPeerReviews(false) as $peer_id => $reviews)
2654 {
2655 foreach($reviews as $giver_id => $review)
2656 {
2658 $peer_id, "peer", $giver_id);
2659 }
2660 }
2661
2662 // files
2664
2665 // peer groups
2666 $ilDB->manipulate("DELETE FROM exc_assignment_peer".
2667 " WHERE ass_id = ".$ilDB->quote($this->getId(), "integer"));
2668 }
2669 }
2670
2672 {
2673 if($this->hasPeerReviewGroups())
2674 {
2675 include_once "./Modules/Exercise/classes/class.ilExerciseMembers.php";
2676 $all_exc = ilExerciseMembers::_getMembers($this->getExerciseId());
2677 $all_valid = $this->getValidPeerReviewUsers(); // only returned
2678
2679 $peer_ids = $invalid_peer_ids = $invalid_giver_ids = $all_reviews = array();
2680 foreach($this->getAllPeerReviews(false) as $peer_id => $reviews)
2681 {
2682 $peer_ids[] = $peer_id;
2683
2684 if(!in_array($peer_id, $all_valid) ||
2685 !in_array($peer_id, $all_exc))
2686 {
2687 $invalid_peer_ids[] = $peer_id;
2688 }
2689 foreach($reviews as $giver_id => $review)
2690 {
2691 if(!in_array($giver_id, $all_valid) ||
2692 !in_array($giver_id, $all_exc))
2693 {
2694 $invalid_giver_ids[] = $giver_id;
2695 }
2696 else
2697 {
2698 $valid = (trim($review[0]) || $review[1]);
2699 $all_reviews[$peer_id][$giver_id] = $valid;
2700 }
2701 }
2702 }
2703 $invalid_giver_ids = array_unique($invalid_giver_ids);
2704
2705 $missing_user_ids = array();
2706 foreach($all_valid as $user_id)
2707 {
2708 // a missing peer is also a missing giver
2709 if(!in_array($user_id, $peer_ids))
2710 {
2711 $missing_user_ids[] = $user_id;
2712 }
2713 }
2714
2715 $not_returned_ids = array();
2716 foreach($all_exc as $user_id)
2717 {
2718 if(!in_array($user_id, $all_valid))
2719 {
2720 $not_returned_ids[] = $user_id;
2721 }
2722 }
2723
2724 return array(
2725 "invalid" => (sizeof($missing_user_ids) ||
2726 sizeof($invalid_peer_ids) ||
2727 sizeof($invalid_giver_ids)),
2728 "missing_user_ids" => $missing_user_ids,
2729 "not_returned_ids" => $not_returned_ids,
2730 "invalid_peer_ids" => $invalid_peer_ids,
2731 "invalid_giver_ids" => $invalid_giver_ids,
2732 "reviews" => $all_reviews);
2733 }
2734 }
2735
2736 public function getPeerReviewsByGiver($a_user_id)
2737 {
2738 global $ilDB;
2739
2740 $res = array();
2741
2742 if($this->initPeerReviews())
2743 {
2744 $set = $ilDB->query("SELECT *".
2745 " FROM exc_assignment_peer".
2746 " WHERE giver_id = ".$ilDB->quote($a_user_id, "integer").
2747 " AND ass_id = ".$ilDB->quote($this->getId(), "integer").
2748 " ORDER BY peer_id");
2749 while($row = $ilDB->fetchAssoc($set))
2750 {
2751 $res[] = $row;
2752 }
2753 }
2754
2755 return $res;
2756 }
2757
2758 protected static function validatePeerReview(array $a_data, $a_rating = null)
2759 {
2760 $valid = false;
2761
2762 // comment
2763 if(trim($a_data["pcomment"]))
2764 {
2765 $valid = true;
2766 }
2767
2768 // rating
2769 if(!$valid)
2770 {
2771 if($a_rating === null)
2772 {
2773 include_once './Services/Rating/classes/class.ilRating.php';
2774 $valid = (bool)round(ilRating::getRatingForUserAndObject($a_data["ass_id"],
2775 "ass", $a_data["peer_id"], "peer", $a_data["giver_id"]));
2776 }
2777 else if($a_rating)
2778 {
2779 $valid = true;
2780 }
2781 }
2782
2783 // file(s)
2784 if(!$valid)
2785 {
2786 $ass = new self($a_data["ass_id"]);
2787 $valid = (bool)sizeof($ass->getPeerUploadFiles($a_data["peer_id"], $a_data["giver_id"]));
2788 }
2789
2790 return $valid;
2791 }
2792
2793 public function getPeerReviewsByPeerId($a_user_id, $a_only_valid = false)
2794 {
2795 global $ilDB;
2796
2797 $res = array();
2798
2799 $set = $ilDB->query("SELECT *".
2800 " FROM exc_assignment_peer".
2801 " WHERE peer_id = ".$ilDB->quote($a_user_id, "integer").
2802 " AND ass_id = ".$ilDB->quote($this->getId(), "integer").
2803 " ORDER BY peer_id");
2804 while($row = $ilDB->fetchAssoc($set))
2805 {
2806 if(!$a_only_valid ||
2807 self::validatePeerReview($row))
2808 {
2809 $res[] = $row;
2810 }
2811 }
2812
2813 return $res;
2814 }
2815
2816 public function getAllPeerReviews($a_validate = true)
2817 {
2818 global $ilDB;
2819
2820 $res = array();
2821
2822 include_once './Services/Rating/classes/class.ilRating.php';
2823
2824 $set = $ilDB->query("SELECT *".
2825 " FROM exc_assignment_peer".
2826 " WHERE ass_id = ".$ilDB->quote($this->getId(), "integer").
2827 " ORDER BY peer_id");
2828 while($row = $ilDB->fetchAssoc($set))
2829 {
2830 $rating = round(ilRating::getRatingForUserAndObject($this->getId(),
2831 "ass", $row["peer_id"], "peer", $row["giver_id"]));
2832
2833 if(!$a_validate ||
2834 self::validatePeerReview($row, $rating))
2835 {
2836 $res[$row["peer_id"]][$row["giver_id"]] = array($row["pcomment"], $rating);
2837 }
2838 }
2839
2840 return $res;
2841 }
2842
2843 public function hasPeerReviewAccess($a_peer_id)
2844 {
2845 global $ilDB, $ilUser;
2846
2847 $set = $ilDB->query("SELECT ass_id".
2848 " FROM exc_assignment_peer".
2849 " WHERE giver_id = ".$ilDB->quote($ilUser->getId(), "integer").
2850 " AND peer_id = ".$ilDB->quote($a_peer_id, "integer").
2851 " AND ass_id = ".$ilDB->quote($this->getId(), "integer"));
2852 $row = $ilDB->fetchAssoc($set);
2853 return (bool)$row["ass_id"];
2854 }
2855
2856 public function updatePeerReviewTimestamp($a_peer_id)
2857 {
2858 global $ilDB, $ilUser;
2859
2860 $ilDB->manipulate("UPDATE exc_assignment_peer".
2861 " SET tstamp = ".$ilDB->quote(ilUtil::now(), "timestamp").
2862 " WHERE giver_id = ".$ilDB->quote($ilUser->getId(), "integer").
2863 " AND peer_id = ".$ilDB->quote($a_peer_id, "integer").
2864 " AND ass_id = ".$ilDB->quote($this->getId(), "integer"));
2865 }
2866
2867 public function getPeerUploadFiles($a_peer_id, $a_giver_id)
2868 {
2869 if(!$this->hasPeerReviewFileUpload())
2870 {
2871 return array();
2872 }
2873 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
2874 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
2875 $path = $storage->getPeerReviewUploadPath($a_peer_id, $a_giver_id);
2876 return glob($path."/*.*");
2877 }
2878
2879 public function updatePeerReviewComment($a_peer_id, $a_comment)
2880 {
2881 global $ilDB, $ilUser;
2882
2883 $sql = "UPDATE exc_assignment_peer".
2884 " SET tstamp = ".$ilDB->quote(ilUtil::now(), "timestamp").
2885 ",pcomment = ".$ilDB->quote(trim($a_comment), "text").
2886 " WHERE giver_id = ".$ilDB->quote($ilUser->getId(), "integer").
2887 " AND peer_id = ".$ilDB->quote($a_peer_id, "integer").
2888 " AND ass_id = ".$ilDB->quote($this->getId(), "integer");
2889
2890 $ilDB->manipulate($sql);
2891 }
2892
2893 public static function countGivenFeedback($a_ass_id)
2894 {
2895 global $ilDB, $ilUser;
2896
2897 $cnt = 0;
2898
2899 include_once './Services/Rating/classes/class.ilRating.php';
2900
2901 $set = $ilDB->query("SELECT *".
2902 " FROM exc_assignment_peer".
2903 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer").
2904 " AND giver_id = ".$ilDB->quote($ilUser->getId(), "integer"));
2905 while($row = $ilDB->fetchAssoc($set))
2906 {
2907 if(self::validatePeerReview($row))
2908 {
2909 $cnt++;
2910 }
2911 }
2912
2913 return $cnt;
2914 }
2915
2916 public static function getNumberOfMissingFeedbacks($a_ass_id, $a_min)
2917 {
2918 global $ilDB;
2919
2920 // check if number of returned assignments is lower than assignment peer min
2921 $set = $ilDB->query("SELECT COUNT(DISTINCT(user_id)) cnt".
2922 " FROM exc_returned".
2923 " WHERE ass_id = ".$ilDB->quote($a_ass_id, "integer"));
2924 $cnt = $ilDB->fetchAssoc($set);
2925 $cnt = (int)$cnt["cnt"];
2926
2927 // forever alone
2928 if($cnt < 2)
2929 {
2930 return;
2931 }
2932
2933 $a_min = min($cnt-1, $a_min);
2934
2935 return max(0, $a_min-self::countGivenFeedback($a_ass_id));
2936 }
2937
2938 public static function getPendingFeedbackNotifications()
2939 {
2940 global $ilDB;
2941
2942 $res = array();
2943
2944 $set = $ilDB->query("SELECT id,fb_file FROM exc_assignment".
2945 " WHERE fb_cron = ".$ilDB->quote(1, "integer").
2946 " AND fb_date = ".$ilDB->quote(self::FEEDBACK_DATE_DEADLINE, "integer").
2947 " AND time_stamp IS NOT NULL".
2948 " AND time_stamp > ".$ilDB->quote(0, "integer").
2949 " AND time_stamp < ".$ilDB->quote(time(), "integer").
2950 " AND fb_cron_done = ".$ilDB->quote(0, "integer"));
2951 while($row = $ilDB->fetchAssoc($set))
2952 {
2953 if(trim($row["fb_file"]))
2954 {
2955 $res[] = $row["id"];
2956 }
2957 }
2958
2959 return $res;
2960 }
2961
2962 public function sendFeedbackNotifications($a_ass_id, $a_user_id = null)
2963 {
2964 global $ilDB;
2965
2966 $ass = new self($a_ass_id);
2967
2968 // valid assignment?
2969 if(!$ass->hasFeedbackCron() || !$ass->getFeedbackFile())
2970 {
2971 return false;
2972 }
2973
2974 if(!$a_user_id)
2975 {
2976 // already done?
2977 $set = $ilDB->query("SELECT fb_cron_done".
2978 " FROM exc_assignment".
2979 " WHERE id = ".$ilDB->quote($a_ass_id, "integer"));
2980 $row = $ilDB->fetchAssoc($set);
2981 if($row["fb_cron_done"])
2982 {
2983 return false;
2984 }
2985 }
2986
2987 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
2988 $ntf = new ilSystemNotification();
2989 $ntf->setLangModules(array("exc"));
2990 $ntf->setObjId($ass->getExerciseId());
2991 $ntf->setSubjectLangId("exc_feedback_notification_subject");
2992 $ntf->setIntroductionLangId("exc_feedback_notification_body");
2993 $ntf->addAdditionalInfo("exc_assignment", $ass->getTitle());
2994 $ntf->setGotoLangId("exc_feedback_notification_link");
2995 $ntf->setReasonLangId("exc_feedback_notification_reason");
2996
2997 if(!$a_user_id)
2998 {
2999 include_once "./Modules/Exercise/classes/class.ilExerciseMembers.php";
3000 $ntf->sendMail(ilExerciseMembers::_getMembers($ass->getExerciseId()));
3001
3002 $ilDB->manipulate("UPDATE exc_assignment".
3003 " SET fb_cron_done = ".$ilDB->quote(1, "integer").
3004 " WHERE id = ".$ilDB->quote($a_ass_id, "integer"));
3005 }
3006 else
3007 {
3008 $ntf->sendMail(array($a_user_id));
3009 }
3010
3011 return true;
3012 }
3013
3017
3022 {
3023 global $ilDB;
3024
3025
3026 // send and delete the zip file
3027 $deliverFilename = trim(str_replace(" ", "_", $this->getTitle()."_".$this->getId()));
3028 $deliverFilename = ilUtil::getASCIIFilename($deliverFilename);
3029 $deliverFilename = "multi_feedback_".$deliverFilename;
3030
3031 $exc = new ilObjExercise($this->getExerciseId(), false);
3032
3033 $cdir = getcwd();
3034
3035 // create temporary directoy
3036 $tmpdir = ilUtil::ilTempnam();
3037 ilUtil::makeDir($tmpdir);
3038 $mfdir = $tmpdir."/".$deliverFilename;
3039 ilUtil::makeDir($mfdir);
3040
3041 // create subfolders <lastname>_<firstname>_<id> for each participant
3042 include_once("./Modules/Exercise/classes/class.ilExerciseMembers.php");
3043 $exmem = new ilExerciseMembers($exc);
3044 $mems = $exmem->getMembers();
3045
3046 foreach ($mems as $mem)
3047 {
3048 $name = ilObjUser::_lookupName($mem);
3049 $subdir = $name["lastname"]."_".$name["firstname"]."_".$name["login"]."_".$name["user_id"];
3050 $subdir = ilUtil::getASCIIFilename($subdir);
3051 ilUtil::makeDir($mfdir."/".$subdir);
3052 }
3053
3054 // create the zip file
3055 chdir($tmpdir);
3056 $tmpzipfile = $tmpdir."/multi_feedback.zip";
3057 ilUtil::zip($tmpdir, $tmpzipfile, true);
3058 chdir($cdir);
3059
3060
3061 ilUtil::deliverFile($tmpzipfile, $deliverFilename.".zip", "", false, true);
3062 }
3063
3070 function uploadMultiFeedbackFile($a_file)
3071 {
3072 global $lng, $ilUser;
3073
3074 include_once("./Modules/Exercise/exceptions/class.ilExerciseException.php");
3075 if (!is_file($a_file["tmp_name"]))
3076 {
3077 throw new ilExerciseException($lng->txt("exc_feedback_file_could_not_be_uploaded"));
3078 }
3079
3080 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
3081 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
3082 $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
3083 ilUtil::delDir($mfu, true);
3084 ilUtil::moveUploadedFile($a_file["tmp_name"], "multi_feedback.zip", $mfu."/"."multi_feedback.zip");
3085 ilUtil::unzip($mfu."/multi_feedback.zip", true);
3086 $subdirs = ilUtil::getDir($mfu);
3087 $subdir = "notfound";
3088 foreach ($subdirs as $s => $j)
3089 {
3090 if ($j["type"] == "dir" && substr($s, 0, 14) == "multi_feedback")
3091 {
3092 $subdir = $s;
3093 }
3094 }
3095
3096 if (!is_dir($mfu."/".$subdir))
3097 {
3098 throw new ilExerciseException($lng->txt("exc_no_feedback_dir_found_in_zip"));
3099 }
3100
3101 return true;
3102 }
3103
3110 function getMultiFeedbackFiles($a_user_id = 0)
3111 {
3112 global $ilUser;
3113
3114 if ($a_user_id == 0)
3115 {
3116 $a_user_id = $ilUser->getId();
3117 }
3118
3119 $mf_files = array();
3120
3121 // get members
3122 $exc = new ilObjExercise($this->getExerciseId(), false);
3123 include_once("./Modules/Exercise/classes/class.ilExerciseMembers.php");
3124 $exmem = new ilExerciseMembers($exc);
3125 $mems = $exmem->getMembers();
3126
3127 // read mf directory
3128 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
3129 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
3130 $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
3131
3132 // get subdir that starts with multi_feedback
3133 $subdirs = ilUtil::getDir($mfu);
3134 $subdir = "notfound";
3135 foreach ($subdirs as $s => $j)
3136 {
3137 if ($j["type"] == "dir" && substr($s, 0, 14) == "multi_feedback")
3138 {
3139 $subdir = $s;
3140 }
3141 }
3142
3143 $items = ilUtil::getDir($mfu."/".$subdir);
3144 foreach ($items as $k => $i)
3145 {
3146 // check directory
3147 if ($i["type"] == "dir" && !in_array($k, array(".", "..")))
3148 {
3149 // check if valid member id is given
3150 $parts = explode("_", $i["entry"]);
3151 $user_id = (int) $parts[count($parts) - 1];
3152 if (in_array($user_id, $mems))
3153 {
3154 // read dir of user
3155 $name = ilObjUser::_lookupName($user_id);
3156 $files = ilUtil::getDir($mfu."/".$subdir."/".$k);
3157 foreach ($files as $k2 => $f)
3158 {
3159 // append files to array
3160 if ($f["type"] == "file" && substr($k2, 0, 1) != ".")
3161 {
3162 $mf_files[] = array(
3163 "lastname" => $name["lastname"],
3164 "firstname" => $name["firstname"],
3165 "login" => $name["login"],
3166 "user_id" => $name["user_id"],
3167 "full_path" => $mfu."/".$subdir."/".$k."/".$k2,
3168 "file" => $k2);
3169 }
3170 }
3171 }
3172 }
3173 }
3174 return $mf_files;
3175 }
3176
3184 {
3185 global $lng, $ilUser;
3186
3187 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
3188 $storage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
3189 $mfu = $storage->getMultiFeedbackUploadPath($ilUser->getId());
3190 ilUtil::delDir($mfu);
3191 }
3192
3199 function saveMultiFeedbackFiles($a_files, ilObjExercise $a_exc)
3200 {
3201 if($this->getExerciseId() != $a_exc->getId())
3202 {
3203 return;
3204 }
3205
3206 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
3207 $fstorage = new ilFSStorageExercise($this->getExerciseId(), $this->getId());
3208 $fstorage->create();
3209
3210 $team_map = array();
3211
3212 $mf_files = $this->getMultiFeedbackFiles();
3213 foreach ($mf_files as $f)
3214 {
3215 $user_id = $f["user_id"];
3216 $file_path = $f["full_path"];
3217 $file_name = $f["file"];
3218
3219 // if checked in confirmation gui
3220 if ($a_files[$user_id][md5($file_name)] != "")
3221 {
3222 // #14294 - team assignment
3224 {
3225 // just once for each user
3226 if (!array_key_exists($user_id, $team_map))
3227 {
3228 $team_id = $this->getTeamId($user_id);
3229 $team_map[$user_id]["team_id"] = "t".$team_id;
3230
3231 $team_map[$user_id]["noti_rec_ids"] = array();
3232 foreach ($this->getTeamMembers($team_id) as $team_user_id)
3233 {
3234 $team_map[$user_id]["noti_rec_ids"][] = $team_user_id;
3235 }
3236 }
3237
3238 $feedback_id = $team_map[$user_id]["team_id"];
3239 $noti_rec_ids = $team_map[$user_id]["noti_rec_ids"];
3240 }
3241 else
3242 {
3243 $feedback_id = $user_id;
3244 $noti_rec_ids = array($user_id);
3245 }
3246
3247 if ($feedback_id)
3248 {
3249 $fb_path = $fstorage->getFeedbackPath($feedback_id);
3250 $target = $fb_path."/".$file_name;
3251 if (is_file($target))
3252 {
3253 unlink($target);
3254 }
3255 // rename file
3256 rename($file_path, $target);
3257
3258 if ($noti_rec_ids)
3259 {
3260 $a_exc->sendFeedbackFileNotification($file_name, $noti_rec_ids,
3261 (int) $this->getId());
3262 }
3263 }
3264 }
3265 }
3266
3268 }
3269
3275 protected function handleCalendarEntries($a_event)
3276 {
3277 global $ilAppEventHandler;
3278
3279 $dl_id = $this->getId()."0";
3280 $fbdl_id = $this->getId()."1";
3281
3282 $context_ids = array($dl_id, $fbdl_id);
3283 $apps = array();
3284
3285 if($a_event != "delete")
3286 {
3287 include_once "Services/Calendar/classes/class.ilCalendarAppointmentTemplate.php";
3288
3289 if($this->getDeadline())
3290 {
3291 $app = new ilCalendarAppointmentTemplate($dl_id);
3292 $app->setTranslationType(IL_CAL_TRANSLATION_SYSTEM);
3293 $app->setSubtitle("cal_exc_deadline");
3294 $app->setTitle($this->getTitle());
3295 $app->setFullday(false);
3296 $app->setStart(new ilDateTime($this->getDeadline(), IL_CAL_UNIX));
3297
3298 $apps[] = $app;
3299 }
3300
3301 if($this->getPeerReview() &&
3302 $this->getPeerReviewDeadline())
3303 {
3304 $app = new ilCalendarAppointmentTemplate($fbdl_id);
3305 $app->setTranslationType(IL_CAL_TRANSLATION_SYSTEM);
3306 $app->setSubtitle("cal_exc_peer_review_deadline");
3307 $app->setTitle($this->getTitle());
3308 $app->setFullday(false);
3309 $app->setStart(new ilDateTime($this->getPeerReviewDeadline(), IL_CAL_UNIX));
3310
3311 $apps[] = $app;
3312 }
3313
3314 }
3315
3316 include_once "Modules/Exercise/classes/class.ilObjExercise.php";
3317 $exc = new ilObjExercise($this->getExerciseId(), false);
3318
3319 $ilAppEventHandler->raise('Modules/Exercise',
3320 $a_event.'Assignment',
3321 array(
3322 'object' => $exc,
3323 'obj_id' => $exc->getId(),
3324 'context_ids' => $context_ids,
3325 'appointments' => $apps));
3326 }
3327
3328 public static function getAdoptableTeamAssignments($a_exercise_id, $a_exclude_ass_id = null, $a_user_id = null)
3329 {
3330 $res = array();
3331
3333 foreach($data as $row)
3334 {
3335 if($a_exclude_ass_id && $row["id"] == $a_exclude_ass_id)
3336 {
3337 continue;
3338 }
3339
3341 {
3343
3344 if($a_user_id && !array_key_exists($a_user_id, $map))
3345 {
3346 continue;
3347 }
3348
3349 if(sizeof($map))
3350 {
3351 $user_team = null;
3352 if($a_user_id)
3353 {
3354 $user_team_id = $map[$a_user_id];
3355 $user_team = array();
3356 foreach($map as $user_id => $team_id)
3357 {
3358 if($user_id != $a_user_id &&
3359 $user_team_id == $team_id)
3360 {
3361 $user_team[] = $user_id;
3362 }
3363 }
3364 }
3365
3366 if(!$a_user_id ||
3367 sizeof($user_team))
3368 {
3369 $res[$row["id"]] = array(
3370 "title" => $row["title"],
3371 "teams" => sizeof(array_flip($map)),
3372 );
3373
3374 if($a_user_id)
3375 {
3376 $res[$row["id"]]["user_team"] = $user_team;
3377 }
3378 }
3379 }
3380 }
3381 }
3382
3383 return ilUtil::sortArray($res, "title", "asc", false, true);
3384 }
3385
3386 public function adoptTeams($a_source_ass_id, $a_user_id = null, $a_exc_ref_id = null)
3387 {
3388 $teams = array();
3389
3390 $old_team = null;
3391 foreach(self::getAssignmentTeamMap($a_source_ass_id) as $user_id => $team_id)
3392 {
3393 $teams[$team_id][] = $user_id;
3394
3395 if($a_user_id && $user_id == $a_user_id)
3396 {
3397 $old_team = $team_id;
3398 }
3399 }
3400
3401 if($a_user_id)
3402 {
3403 // no existing team (in source) or user already in team (in current)
3404 if(!$old_team || $this->getTeamId($a_user_id))
3405 {
3406 return;
3407 }
3408 }
3409
3410 $current_map = self::getAssignmentTeamMap($this->getId());
3411
3412 foreach($teams as $team_id => $user_ids)
3413 {
3414 if(!$old_team || $team_id == $old_team)
3415 {
3416 // only not assigned users
3417 $missing = array();
3418 foreach($user_ids as $user_id)
3419 {
3420 if(!array_key_exists($user_id, $current_map))
3421 {
3422 $missing[] = $user_id;
3423 }
3424 }
3425
3426 if(sizeof($missing))
3427 {
3428 // create new team
3429 $first = array_shift($missing);
3430 $team_id = $this->getTeamId($first, true);
3431
3432 if($a_exc_ref_id)
3433 {
3434 // getTeamId() does NOT send notification
3435 $this->sendNotification($a_exc_ref_id, $first, "add");
3436 }
3437
3438 foreach($missing as $user_id)
3439 {
3440 $this->addTeamMember($team_id, $user_id, $a_exc_ref_id);
3441 }
3442 }
3443 }
3444 }
3445 }
3446}
3447
3448?>
$result
print $file
$filename
Definition: buildRTE.php:89
const IL_CAL_TRANSLATION_SYSTEM
const IL_CAL_UNIX
const IL_CAL_DATETIME
Apointment templates are used for automatic generated apointments.
static formatDate(ilDateTime $date)
Format a date @access public.
@classDescription Date and time handling
Exercise assignment.
downloadAllDeliveredFiles($a_exc_id, $a_ass_id, $members)
Download all submitted files of an assignment (all user)
removeTeamMember($a_team_id, $a_user_id, $a_exc_ref_id)
Remove member from team.
getPeerUploadFiles($a_peer_id, $a_giver_id)
lookupStatusFeedbackOfUser($a_ass_id, $a_user_id)
was: getStatusFeedbackByMember($a_member_id)
getPeerReviewsByGiver($a_user_id)
handleFeedbackFileUpload(array $a_file)
orderAssByDeadline($a_ex_id)
Order assignments by deadline date.
hasPeerReviewPersonalized()
Get peer review personalized status.
setDeadline($a_val)
Set deadline (timestamp)
countMandatory($a_ex_id)
Order assignments by deadline date.
static lookupMaxOrderNrForEx($a_exc_id)
Select the maximum order nr for an exercise.
setOrderNr($a_val)
Set order nr.
clearMultiFeedbackDirectory()
Clear multi feedback directory.
static getFiles($a_exc_id, $a_ass_id)
Get files.
lookupStatusReturnedOfUser($a_ass_id, $a_user_id)
was: getStatusReturnedByMember($a_member_id)
static getTeamIdByAssignment($a_ass_id, $a_user_id)
Find team by assignment.
static lookupNewFiles($ass_id, $member_id)
Check how much files have been uploaded by the learner after the last download of the tutor.
setPeerReview($a_value)
Toggle peer review.
getFeedbackDate()
Get (global) feedback file availability date.
lookupMarkOfUser($a_ass_id, $a_user_id)
Lookup user mark.
getAllPeerReviews($a_validate=true)
getMultiFeedbackFiles($a_user_id=0)
Get multi feedback files (of uploader)
getExerciseId()
Get exercise id.
updateTutorDownloadTime($a_exc_id, $a_ass_id, $a_user_id)
was: updateTutorDownloadTime($member_id)
lookupAssMemberField($a_ass_id, $a_user_id, $a_field)
Lookup a field value of ass/member table.
static lookup($a_id, $a_field)
Private lookup.
getMembersOfAllTeams()
Get members for all teams of assignment.
setFeedbackCron($a_value)
Toggle (global) feedback file cron.
setTitle($a_val)
Set title.
uploadMultiFeedbackFile($a_file)
Upload multi feedback file.
updateStatusSentForUser($a_ass_id, $a_user_id, $a_status)
was: setStatusSentForMember($a_member_id,$a_status)
getPeerReviewsByPeerId($a_user_id, $a_only_valid=false)
handleCalendarEntries($a_event)
Handle calendar entries for deadline(s)
static getAdoptableTeamAssignments($a_exercise_id, $a_exclude_ass_id=null, $a_user_id=null)
downloadMultipleFiles($a_exc_id, $a_ass_id, $array_filenames, $a_user_id, $a_multi_user=false)
was: downloadMultipleFiles($array_filenames, $pathname, $a_member_id = 0)
getId()
Get assignment id.
static getLastSubmission($a_ass_id, $a_user_id)
Get the date of the last submission of a user for the assignment.
getInstruction()
Get instruction.
getMemberListData($a_exc_id, $a_ass_id)
get member list data
static lookupUpdatedSubmission($ass_id, $member_id)
Check whether student has upload new files after tutor has set the exercise to another than notgraded...
static getTeamMembersByAssignmentId($a_ass_id, $a_user_id)
Find team members by assignment and team member.
updateAssMemberField($a_ass_id, $a_user_id, $a_field, $a_value, $a_type)
Update a field value of ass/member table.
getPeerReviewMin()
Get peer review minimum.
static lookupSentTimeOfUser($a_ass_id, $a_user_id)
Get time when exercise has been sent per e-mail to user.
updatePeerReviewComment($a_peer_id, $a_comment)
setPeerReviewPersonalized($a_val)
Set peer review personalized.
static lookupAnyExerciseSent($a_exc_id, $a_ass_id)
Check whether exercise has been sent to any student per mail.
updateNoticeForUser($a_ass_id, $a_user_id, $a_notice)
was: setNoticeForMember($a_member_id,$a_notice)
static writeTeamLog($a_team_id, $a_action, $a_details=null)
Add entry to team log.
isValidType($a_value)
Is given type valid?
static getNumberOfMissingFeedbacks($a_ass_id, $a_min)
static lookupFeedbackTimeOfUser($a_ass_id, $a_user_id)
Get time when feedback mail has been sent.
saveMultiFeedbackFiles($a_files, ilObjExercise $a_exc)
Save multi feedback files.
lookupStatusSentOfUser($a_ass_id, $a_user_id)
was: getStatusSentByMember($a_member_id)
updateStatusOfUser($a_ass_id, $a_user_id, $a_status)
was: setStatusForMember($a_member_id,$a_status)
lookupCommentForUser($a_ass_id, $a_user_id)
Lookup comment for the user.
addTeamMember($a_team_id, $a_user_id, $a_exc_ref_id=null)
Add new member to team.
lookupStatusOfUser($a_ass_id, $a_user_id)
was: getStatusByMember
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 getAssignmentTeamMap($a_ass_id)
Get team structure for assignment.
sendNotification($a_exc_ref_id, $a_user_id, $a_action)
Send notification about team status.
static getPendingFeedbackNotifications()
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 getDownloadedFilesInfoForTableGUIS($a_parent_obj, $a_exercise_id, $a_ass_type, $a_ass_id, $a_user_id, $a_parent_cmd=null)
lookupNoticeOfUser($a_ass_id, $a_user_id)
was: getNoticeByMember($a_member_id)
getTeamId($a_user_id, $a_create_on_demand=false)
Get team id for member id.
static getAssignmentDataOfExercise($a_exc_id)
Get assignments data of an exercise in an array.
sendFeedbackNotifications($a_ass_id, $a_user_id=null)
getAllDeliveredFiles($a_exc_id, $a_ass_id)
was: getAllDeliveredFiles()
adoptTeams($a_source_ass_id, $a_user_id=null, $a_exc_ref_id=null)
setId($a_val)
Set assignment id.
hasFeedbackCron()
Get (global) feedback file cron status.
getStartTime()
Get start time (timestamp)
setStartTime($a_val)
Set start time (timestamp)
getDeliveredFiles($a_exc_id, $a_ass_id, $a_user_id, $a_filter_empty_filename=false)
was: getDeliveredFiles($a_member_id)
static validatePeerReview(array $a_data, $a_rating=null)
sendMultiFeedbackStructureFile()
Create member status record for a new assignment for all participants.
updateMarkOfUser($a_ass_id, $a_user_id, $a_value)
Update mark.
updateStatusFeedbackForUser($a_ass_id, $a_user_id, $a_status)
was: setStatusFeedbackForMember($a_member_id,$a_status)
cloneAssignmentsOfExercise($a_old_exc_id, $a_new_exc_id)
Clone assignments of exercise.
getPeerReviewDeadline()
Get peer review deadline (timestamp)
downloadSelectedFiles($a_exc_id, $a_ass_id, $a_user_id, $array_file_id)
was: downloadSelectedFiles($array_file_id,$a_user_id)?
updateStatusTimeOfUser($a_ass_id, $a_user_id)
was: updateStatusTimeForMember($a_user_id)
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.
updateCommentForUser($a_ass_id, $a_user_id, $a_value)
Update comment.
hasPeerReviewAccess($a_peer_id)
setPeerReviewFileUpload($a_val)
Set peer review file upload.
deleteDeliveredFiles($a_exc_id, $a_ass_id, $file_id_array, $a_user_id)
was: deleteDeliveredFiles($file_id_array, $a_member_id)
saveAssOrderOfExercise($a_ex_id, $a_order)
Save ordering of all assignments of an exercise.
static createNewUserRecords($a_user_id, $a_exc_id)
Create member status record for a new participant for all assignments.
setType($a_value)
Set type.
hasReturned($a_ass_id, $a_user_id)
was: hasReturned($a_member_id)
static lookupAssignmentOnline($a_ass_id)
Check if assignment is online.
getTeamMembers($a_team_id)
Get members of assignment team.
updatePeerReviewTimestamp($a_peer_id)
save()
Save assignment.
updateStatusReturnedForUser($a_ass_id, $a_user_id, $a_status)
was: setStatusReturnedForMember($a_member_id,$a_status)
getDeadline()
Get deadline (timestamp)
downloadSingleFile($a_exc_id, $a_ass_id, $a_user_id, $filename, $filetitle)
was: downloadSingleFile($filename, $filetitle)
setExerciseId($a_val)
Set exercise id.
static lookupType($a_id)
Lookup type.
setFeedbackFile($a_value)
Set (global) feedback file.
setMandatory($a_val)
Set mandatory.
static countGivenFeedback($a_ass_id)
getMandatory()
Get mandatory.
static lookupStatusTimeOfUser($a_ass_id, $a_user_id)
Get status time.
deliverReturnedFiles($a_exc_id, $a_ass_id, $a_user_id, $a_only_new=false, $a_peer_review_mask_filename=false)
was: deliverReturnedFiles($a_member_id, $a_only_new = false)
static deleteAllDeliveredFilesOfUser($a_exc_id, $a_user_id)
Delete all delivered files of user.
static getTeamLog($a_team_id)
Get all log entries for team.
_getReturned($a_ass_id)
was: _getReturned($a_obj_id)
Class to report exception.
Class ilExerciseMembers.
Class ilObjExercise.
sendFeedbackFileNotification($a_feedback_file, $a_user_id, $a_ass_id, $a_is_text_feedback=false)
Send feedback file notification to user.
_lookupFullname($a_user_id)
Lookup Full Name.
static _lookupName($a_user_id)
lookup user name
static _lookupTitle($a_id)
lookup object title
getId()
get object id @access public
static getRatingForUserAndObject($a_obj_id, $a_obj_type, $a_sub_obj_id, $a_sub_obj_type, $a_user_id, $a_category_id=null)
Get rating for a user and an object.
static resetRatingForUserAndObject($a_obj_id, $a_obj_type, $a_sub_obj_id, $a_sub_obj_type, $a_user_id)
Reset rating for a user and an object.
Wrapper classes for system notifications.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getMySQLTimestamp($a_ts)
Get MySQL timestamp in 4.1.x or higher format (yyyy-mm-dd hh:mm:ss) This function converts a timestam...
static sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static escapeShellArg($a_arg)
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)
static getDir($a_dir, $a_rec=false, $a_sub_dir="")
get directory
static now()
Return current timestamp in Y-m-d H:i:s format.
static ilTempnam()
Create a temporary file in an ILIAS writable directory.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
static deliverFile($a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static dirsize($directory)
get size of a directory or a file.
$valid
global $ilCtrl
Definition: ilias.php:18
exit
Definition: login.php:54
global $lng
Definition: privfeed.php:40
$path
Definition: index.php:22
global $ilDB
global $ilUser
Definition: imgupload.php:15