ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilExSubmission.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_FILE = "File";
14 const TYPE_OBJECT = "Object"; // Blogs in WSP/Portfolio
15 const TYPE_TEXT = "Text";
16 const TYPE_REPO_OBJECT = "RepoObject"; // Wikis
17
21 protected $user;
22
26 protected $db;
27
31 protected $lng;
32
36 protected $ctrl;
37
38 protected $assignment; // [ilExAssignment]
39 protected $user_id; // [int]
40 protected $team; // [ilExAssignmentTeam]
41 protected $peer_review; // [ilExPeerReview]
42 protected $is_tutor; // [bool]
43 protected $public_submissions; // [bool]
44
48 protected $ass_type;
49
53 protected $ass_types;
54
55 public function __construct(ilExAssignment $a_ass, $a_user_id, ilExAssignmentTeam $a_team = null, $a_is_tutor = false, $a_public_submissions = false)
56 {
57 global $DIC;
58
59 $this->user = $DIC->user();
60 $this->db = $DIC->database();
61 $this->lng = $DIC->language();
62 $this->ctrl = $DIC->ctrl();
63 $ilUser = $DIC->user();
64
65 $this->assignment = $a_ass;
66 $this->ass_type = $this->assignment->getAssignmentType();
67 $this->ass_types = ilExAssignmentTypes::getInstance();
68
69 $this->user_id = $a_user_id;
70 $this->is_tutor = (bool) $a_is_tutor;
71 $this->public_submissions = (bool) $a_public_submissions;
72
73 include_once("./Modules/Exercise/classes/class.ilExcAssMemberState.php");
74 $this->state = ilExcAssMemberState::getInstanceByIds($a_ass->getId(), $a_user_id);
75
76 if ($a_ass->hasTeam()) {
77 if (!$a_team) {
78 include_once "Modules/Exercise/classes/class.ilExAssignmentTeam.php";
79 $this->team = ilExAssignmentTeam::getInstanceByUserId($this->assignment->getId(), $this->user_id);
80 } else {
81 $this->team = $a_team;
82 }
83 }
84
85 if ($this->assignment->getPeerReview()) {
86 include_once "Modules/Exercise/classes/class.ilExPeerReview.php";
87 $this->peer_review = new ilExPeerReview($this->assignment);
88 }
89 }
90
91 public function getSubmissionType()
92 {
93 return $this->assignment->getAssignmentType()->getSubmissionType();
94 /*switch($this->assignment->getType())
95 {
96 case ilExAssignment::TYPE_UPLOAD_TEAM:
97 case ilExAssignment::TYPE_UPLOAD:
98 return "File";
99
100 case ilExAssignment::TYPE_BLOG:
101 case ilExAssignment::TYPE_PORTFOLIO:
102 return "Object";
103
104 case ilExAssignment::TYPE_TEXT:
105 return "Text";
106 };*/
107 }
108
109
113 public function getAssignment()
114 {
115 return $this->assignment;
116 }
117
121 public function getTeam()
122 {
123 return $this->team;
124 }
125
129 public function getPeerReview()
130 {
131 return $this->peer_review;
132 }
133
134 public function validatePeerReviews()
135 {
136 $res = array();
137 foreach ($this->getUserIds() as $user_id) {
138 $valid = true;
139
140 // no peer review == valid
141 if ($this->peer_review) {
142 $valid = $this->peer_review->isFeedbackValidForPassed($user_id);
143 }
144
146 }
147 return $res;
148 }
149
150 public function getUserId()
151 {
152 return $this->user_id;
153 }
154
155 public function getUserIds()
156 {
157 if ($this->team &&
158 !$this->hasNoTeamYet()) {
159 return $this->team->getMembers();
160 }
161
162 // if has no team currently there still might be uploads attached
163 return array($this->user_id);
164 }
165
166 public function getFeedbackId()
167 {
168 if ($this->team) {
169 return "t" . $this->team->getId();
170 } else {
171 return $this->getUserId();
172 }
173 }
174
175 public function hasSubmitted()
176 {
177 return (bool) sizeof($this->getFiles(null, true));
178 }
179
180 public function getSelectedObject()
181 {
182 $files = $this->getFiles();
183 if (sizeof($files)) {
184 return array_pop($files);
185 }
186 }
187
188 public function canSubmit()
189 {
190 return ($this->isOwner() &&
191 $this->state->isSubmissionAllowed());
192 }
193
194 public function canView()
195 {
197
198 if ($this->canSubmit() ||
199 $this->isTutor() ||
200 $this->isInTeam() ||
201 $this->public_submissions) {
202 return true;
203 }
204
205 // #16115
206 if ($this->peer_review) {
207 // peer review givers may view peer submissions
208 foreach ($this->peer_review->getPeerReviewsByPeerId($this->getUserId()) as $giver) {
209 if ($giver["giver_id"] == $ilUser->getId()) {
210 return true;
211 }
212 }
213 }
214
215 return false;
216 }
217
218 public function isTutor()
219 {
220 return $this->is_tutor;
221 }
222
223 public function hasNoTeamYet()
224 {
225 if ($this->assignment->hasTeam() &&
226 !$this->team->getId()) {
227 return true;
228 }
229 return false;
230 }
231
232 public function isInTeam($a_user_id = null)
233 {
235
236 if (!$a_user_id) {
237 $a_user_id = $ilUser->getId();
238 }
239 return in_array($a_user_id, $this->getUserIds());
240 }
241
242 public function isOwner()
243 {
245
246 return ($ilUser->getId() == $this->getUserId());
247 }
248
249 public function hasPeerReviewAccess()
250 {
251 return ($this->peer_review &&
252 $this->peer_review->hasPeerReviewAccess($this->user_id));
253 }
254
255 public function canAddFile()
256 {
257 if (!$this->canSubmit()) {
258 return false;
259 }
260
261 $max = $this->getAssignment()->getMaxFile();
262 if ($max &&
263 $max <= sizeof($this->getFiles())) {
264 return false;
265 }
266
267 return true;
268 }
269
270
271 //
272 // FILES
273 //
274
275 protected function isLate()
276 {
277 $dl = $this->state->getOfficialDeadline();
278 //$dl = $this->assignment->getPersonalDeadline($this->getUserId());
279 return ($dl && $dl < time());
280 }
281
282 protected function initStorage()
283 {
284 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
285 return new ilFSStorageExercise($this->assignment->getExerciseId(), $this->assignment->getId());
286 }
287
293 protected function getStorageId()
294 {
295 if ($this->ass_type->isSubmissionAssignedToTeam()) {
296 $storage_id = $this->getTeam()->getId();
297 } else {
298 $storage_id = $this->getUserId();
299 }
300 return $storage_id;
301 }
302
303
307 public function uploadFile($a_http_post_files, $unzip = false)
308 {
310
311 if (!$this->canAddFile()) {
312 return false;
313 }
314
315 if ($this->ass_type->isSubmissionAssignedToTeam()) {
316 $team_id = $this->getTeam()->getId();
317 $user_id = 0;
318 if ($team_id == 0) {
319 return false;
320 }
321 } else {
322 $team_id = 0;
323 $user_id = $this->getUserId();
324 }
325 $storage_id = $this->getStorageId();
326
327 $deliver_result = $this->initStorage()->uploadFile($a_http_post_files, $storage_id, $unzip);
328
329 if ($deliver_result) {
330 $next_id = $ilDB->nextId("exc_returned");
331 $query = sprintf(
332 "INSERT INTO exc_returned " .
333 "(returned_id, obj_id, user_id, filename, filetitle, mimetype, ts, ass_id, late, team_id) " .
334 "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
335 $ilDB->quote($next_id, "integer"),
336 $ilDB->quote($this->assignment->getExerciseId(), "integer"),
337 $ilDB->quote($user_id, "integer"),
338 $ilDB->quote($deliver_result["fullname"], "text"),
339 $ilDB->quote(ilFileUtils::getValidFilename($a_http_post_files["name"]), "text"),
340 $ilDB->quote($deliver_result["mimetype"], "text"),
341 $ilDB->quote(ilUtil::now(), "timestamp"),
342 $ilDB->quote($this->assignment->getId(), "integer"),
343 $ilDB->quote($this->isLate(), "integer"),
344 $ilDB->quote($team_id, "integer")
345 );
346 $ilDB->manipulate($query);
347
348 if ($this->team) {
349 $this->team->writeLog(
351 $a_http_post_files["name"]
352 );
353 }
354
355 return true;
356 }
357 return false;
358 }
359
364 public function processUploadedZipFile($fileTmp)
365 {
367
368 // Create unzip-directory
369 $newDir = ilUtil::ilTempnam();
370 ilUtil::makeDir($newDir);
371
372 include_once("Services/Utilities/classes/class.ilFileUtils.php");
373
374 $success = true;
375
376 try {
377 ilFileUtils::processZipFile($newDir, $fileTmp, false);
378 ilFileUtils::recursive_dirscan($newDir, $filearray);
379
380 // #18441 - check number of files in zip
381 $max_num = $this->assignment->getMaxFile();
382 if ($max_num) {
383 $current_num = sizeof($this->getFiles());
384 $zip_num = sizeof($filearray["file"]);
385 if ($current_num + $zip_num > $max_num) {
386 $success = false;
387 ilUtil::sendFailure($lng->txt("exc_upload_error") . " [Zip1]", true);
388 }
389 }
390
391 if ($success) {
392 foreach ($filearray["file"] as $key => $filename) {
393 $a_http_post_files["name"] = ilFileUtils::utf8_encode($filename);
394 $a_http_post_files["type"] = "other";
395 $a_http_post_files["tmp_name"] = $filearray["path"][$key] . "/" . $filename;
396 $a_http_post_files["error"] = 0;
397 $a_http_post_files["size"] = filesize($filearray["path"][$key] . "/" . $filename);
398
399 if (!$this->uploadFile($a_http_post_files, true)) {
400 $success = false;
401 ilUtil::sendFailure($lng->txt("exc_upload_error") . " [Zip2]", true);
402 }
403 }
404 }
405 } catch (ilFileUtilsException $e) {
406 $success = false;
407 ilUtil::sendFailure($e->getMessage());
408 }
409
410 ilUtil::delDir($newDir);
411 return $success;
412 }
413
414 public static function hasAnySubmissions($a_ass_id)
415 {
416 global $DIC;
417
418 $ilDB = $DIC->database();
419
420 $query = "SELECT * FROM exc_returned" .
421 " WHERE ass_id = " . $ilDB->quote($a_ass_id, "integer") .
422 " AND (filename IS NOT NULL OR atext IS NOT NULL)" .
423 " AND ts IS NOT NULL";
424 $res = $ilDB->query($query);
425 return $res->numRows($res);
426 }
427
428 public static function getAllAssignmentFiles($a_exc_id, $a_ass_id)
429 {
430 global $DIC;
431
432 $ilDB = $DIC->database();
433
434 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
435 $storage = new ilFSStorageExercise($a_exc_id, $a_ass_id);
436 $path = $storage->getAbsoluteSubmissionPath();
437
438 include_once("./Modules/Exercise/AssignmentTypes/classes/class.ilExAssignmentTypes.php");
440
441 $query = "SELECT * FROM exc_returned WHERE ass_id = " .
442 $ilDB->quote($a_ass_id, "integer");
443
444 $res = $ilDB->query($query);
445 while ($row = $ilDB->fetchAssoc($res)) {
446 if ($ass_type->isSubmissionAssignedToTeam()) {
447 $storage_id = $row["team_id"];
448 } else {
449 $storage_id = $row["user_id"];
450 }
451
452 $row["timestamp"] = $row["ts"];
453 $row["filename"] = $path . "/" . $storage_id . "/" . basename($row["filename"]);
454 $delivered[] = $row;
455 }
456
457 return $delivered ? $delivered : array();
458 }
459
460 public static function getAssignmentFilesByUsers(int $a_exc_id, int $a_ass_id, array $a_users) : array
461 {
462 global $DIC;
463
464 $ilDB = $DIC->database();
465
466 $storage = new ilFSStorageExercise($a_exc_id, $a_ass_id);
467 $path = $storage->getAbsoluteSubmissionPath();
468
470
471 $query = "SELECT * FROM exc_returned WHERE ass_id = " .
472 $ilDB->quote($a_ass_id, "integer") .
473 " AND user_id IN (" . implode(',', $a_users) . ")";
474
475 $res = $ilDB->query($query);
476 while ($row = $ilDB->fetchAssoc($res)) {
477 if ($ass_type->isSubmissionAssignedToTeam()) {
478 $storage_id = $row["team_id"];
479 } else {
480 $storage_id = $row["user_id"];
481 }
482
483 $row["timestamp"] = $row["ts"];
484 $row["filename"] = $path . "/" . $storage_id . "/" . basename($row["filename"]);
485 $delivered[] = $row;
486 }
487
488 return $delivered ? $delivered : array();
489 }
490
499 public function getFiles(array $a_file_ids = null, $a_only_valid = false, $a_min_timestamp = null)
500 {
502
503 $sql = "SELECT * FROM exc_returned" .
504 " WHERE ass_id = " . $ilDB->quote($this->getAssignment()->getId(), "integer");
505
506 $sql .= " AND " . $this->getTableUserWhere(true);
507
508
509 if ($a_file_ids) {
510 $sql .= " AND " . $ilDB->in("returned_id", $a_file_ids, false, "integer");
511 }
512
513 if ($a_min_timestamp) {
514 $sql .= " AND ts > " . $ilDB->quote($a_min_timestamp, "timestamp");
515 }
516
517 $result = $ilDB->query($sql);
518
519 $delivered_files = array();
520 if ($ilDB->numRows($result)) {
521 $path = $this->initStorage()->getAbsoluteSubmissionPath();
522
523 while ($row = $ilDB->fetchAssoc($result)) {
524 // blog/portfolio/text submissions
525 if ($a_only_valid &&
526 !$row["filename"] &&
527 !(trim($row["atext"]))) {
528 continue;
529 }
530
531 $row["owner_id"] = $row["user_id"];
532 $row["timestamp"] = $row["ts"];
533 $row["timestamp14"] = substr($row["ts"], 0, 4) .
534 substr($row["ts"], 5, 2) . substr($row["ts"], 8, 2) .
535 substr($row["ts"], 11, 2) . substr($row["ts"], 14, 2) .
536 substr($row["ts"], 17, 2);
537
538 if ($this->getAssignment()->getAssignmentType()->isSubmissionAssignedToTeam()) {
539 $storage_id = $row["team_id"];
540 } else {
541 $storage_id = $row["user_id"];
542 }
543
544
545 $row["filename"] = $path .
546 "/" . $storage_id . "/" . basename($row["filename"]);
547
548 // see 22301, 22719
549 if (is_file($row["filename"]) || (!$this->assignment->getAssignmentType()->usesFileUpload())) {
550 array_push($delivered_files, $row);
551 }
552 }
553 }
554
555 return $delivered_files;
556 }
557
564 public function lookupNewFiles($a_tutor = null)
565 {
568
569 $tutor = ($a_tutor)
570 ? $a_tutor
571 : $ilUser->getId();
572
573 $where = " AND " . $this->getTableUserWhere(true);
574
575 $q = "SELECT exc_returned.returned_id AS id " .
576 "FROM exc_usr_tutor, exc_returned " .
577 "WHERE exc_returned.ass_id = exc_usr_tutor.ass_id " .
578 " AND exc_returned.user_id = exc_usr_tutor.usr_id " .
579 " AND exc_returned.ass_id = " . $ilDB->quote($this->getAssignment()->getId(), "integer") .
580 $where .
581 " AND exc_usr_tutor.tutor_id = " . $ilDB->quote($tutor, "integer") .
582 " AND exc_usr_tutor.download_time < exc_returned.ts ";
583
584 $new_up_set = $ilDB->query($q);
585
586 $new_up = array();
587 while ($new_up_rec = $ilDB->fetchAssoc($new_up_set)) {
588 $new_up[] = $new_up_rec["id"];
589 }
590
591 return $new_up;
592 }
593
600 public static function lookupExerciseIdForReturnedId($a_returned_id)
601 {
602 global $DIC;
603
604 $ilDB = $DIC->database();
605
606 $set = $ilDB->query("SELECT obj_id" .
607 " FROM exc_returned" .
608 " WHERE returned_id = " . $ilDB->quote($a_returned_id, "integer"));
609 $row = $ilDB->fetchAssoc($set);
610 return (int) $row["obj_id"];
611 }
612
621 public static function findUserFiles($a_user_id, $a_filetitle)
622 {
623 global $DIC;
624
625 $ilDB = $DIC->database();
626
627 $set = $ilDB->query("SELECT obj_id, ass_id" .
628 " FROM exc_returned" .
629 " WHERE user_id = " . $ilDB->quote($a_user_id, "integer") .
630 " AND filetitle = " . $ilDB->quote($a_filetitle, "text"));
631 $res = array();
632 while ($row = $ilDB->fetchAssoc($set)) {
633 $res[$row["ass_id"]] = $row;
634 }
635 return $res;
636 }
637
638 public function deleteAllFiles()
639 {
640 $files = array();
641 foreach ($this->getFiles() as $item) {
642 $files[] = $item["returned_id"];
643 }
644 if (sizeof($files)) {
646 }
647 }
648
655 public function deleteSelectedFiles(array $file_id_array)
656 {
658
659
660 $where = " AND " . $this->getTableUserWhere(true);
661
662
663 if (!sizeof($file_id_array)) {
664 return;
665 }
666
667 if (count($file_id_array)) {
668 $result = $ilDB->query("SELECT * FROM exc_returned" .
669 " WHERE " . $ilDB->in("returned_id", $file_id_array, false, "integer") .
670 $where);
671
672 if ($ilDB->numRows($result)) {
673 $result_array = array();
674 while ($row = $ilDB->fetchAssoc($result)) {
675 $row["timestamp"] = $row["ts"];
676 array_push($result_array, $row);
677 }
678
679 // delete the entries in the database
680 $ilDB->manipulate("DELETE FROM exc_returned" .
681 " WHERE " . $ilDB->in("returned_id", $file_id_array, false, "integer") .
682 $where);
683
684 // delete the files
685 $path = $this->initStorage()->getAbsoluteSubmissionPath();
686 foreach ($result_array as $key => $value) {
687 if ($value["filename"]) {
688 if ($this->team) {
689 $this->team->writeLog(
691 $value["filetitle"]
692 );
693 }
694
695 if ($this->getAssignment()->getAssignmentType()->isSubmissionAssignedToTeam()) {
696 $storage_id = $value["team_id"];
697 } else {
698 $storage_id = $value["user_id"];
699 }
700
701 $filename = $path . "/" . $storage_id . "/" . basename($value["filename"]);
702 unlink($filename);
703 }
704 }
705 }
706 }
707 }
708
715 public static function deleteUser($a_exc_id, $a_user_id)
716 {
717 include_once("./Modules/Exercise/classes/class.ilExAssignment.php");
718
719 foreach (ilExAssignment::getInstancesByExercise($a_exc_id) as $ass) {
720 $submission = new self($ass, $a_user_id);
721 $submission->deleteAllFiles();
722
723 // remove from any team
724 $team = $submission->getTeam();
725 if ($team) {
726 $team->removeTeamMember($a_user_id);
727 }
728
729 // #14900
730 $member_status = $ass->getMemberStatus($a_user_id);
731 $member_status->setStatus("notgraded");
732 $member_status->update();
733 }
734 }
735
736 protected function getLastDownloadTime(array $a_user_ids)
737 {
740
741 $q = "SELECT download_time FROM exc_usr_tutor WHERE " .
742 " ass_id = " . $ilDB->quote($this->getAssignment()->getId(), "integer") . " AND " .
743 $ilDB->in("usr_id", $a_user_ids, "", "integer") . " AND " .
744 " tutor_id = " . $ilDB->quote($ilUser->getId(), "integer");
745 $lu_set = $ilDB->query($q);
746 $lu_rec = $ilDB->fetchAssoc($lu_set);
747 return $lu_rec["download_time"];
748 }
749
750 public function downloadFiles(array $a_file_ids = null, $a_only_new = false, $a_peer_review_mask_filename = false)
751 {
754
755 $user_ids = $this->getUserIds();
756 $is_team = $this->assignment->hasTeam();
757
758 // get last download time
759 $download_time = null;
760 if ($a_only_new) {
761 $download_time = $this->getLastDownloadTime($user_ids);
762 }
763
764 if ($this->is_tutor) {
766 }
767
768 if ($a_peer_review_mask_filename) {
769 // process peer review sequence id
770 $peer_id = null;
771 foreach ($this->peer_review->getPeerReviewsByGiver($ilUser->getId()) as $idx => $item) {
772 if ($item["peer_id"] == $this->getUserId()) {
773 $peer_id = $idx + 1;
774 break;
775 }
776 }
777
778 // this will remove personal info from zip-filename
779 $is_team = true;
780 }
781
782 $files = $this->getFiles($a_file_ids, false, $download_time);
783 if ($files) {
784 if (sizeof($files) == 1) {
785 $file = array_pop($files);
786
787 switch ($this->assignment->getType()) {
790 $file["filetitle"] = ilObjUser::_lookupName($file["user_id"]);
791 $file["filetitle"] = ilObject::_lookupTitle($this->assignment->getExerciseId()) . " - " .
792 $this->assignment->getTitle() . " - " .
793 $file["filetitle"]["firstname"] . " " .
794 $file["filetitle"]["lastname"] . " (" .
795 $file["filetitle"]["login"] . ").zip";
796 break;
797
798 // @todo: generalize
800 $file["filetitle"] = ilObject::_lookupTitle($this->assignment->getExerciseId()) . " - " .
801 $this->assignment->getTitle() . " (Team " . $this->getTeam()->getId() . ").zip";
802 break;
803
804 default:
805 break;
806 }
807
808 if ($a_peer_review_mask_filename) {
809 $suffix = array_pop(explode(".", $file["filetitle"]));
810 $file["filetitle"] = $this->assignment->getTitle() . "_peer" . $peer_id . "." . $suffix;
811 } elseif ($file["late"]) {
812 $file["filetitle"] = $lng->txt("exc_late_submission") . " - " .
813 $file["filetitle"];
814 }
815
816 $this->downloadSingleFile($file["user_id"], $file["filename"], $file["filetitle"], $file["team_id"]);
817 } else {
818 $array_files = array();
819 foreach ($files as $seq => $file) {
820 if ($this->assignment->getAssignmentType()->isSubmissionAssignedToTeam()) {
821 $storage_id = $file["team_id"];
822 } else {
823 $storage_id = $file["user_id"];
824 }
825
826 $src = basename($file["filename"]);
827 if ($a_peer_review_mask_filename) {
828 $suffix = array_pop(explode(".", $src));
829 $tgt = $this->assignment->getTitle() . "_peer" . $peer_id .
830 "_" . (++$seq) . "." . $suffix;
831
832 $array_files[$storage_id][] = array(
833 "src" => $src,
834 "tgt" => $tgt
835 );
836 } else {
837 $array_files[$storage_id][] = array(
838 "src" => $src,
839 "late" => $file["late"]
840 );
841 }
842 }
843
845 $array_files,
846 ($is_team ? null : $this->getUserId()),
847 $is_team
848 );
849 }
850 } else {
851 return false;
852 }
853
854 return true;
855 }
856
857 // Update the timestamp of the last download of current user (=tutor)
858 public function updateTutorDownloadTime()
859 {
862
863 $exc_id = $this->assignment->getExerciseId();
864 $ass_id = $this->assignment->getId();
865
866 foreach ($this->getUserIds() as $user_id) {
867 $ilDB->manipulateF(
868 "DELETE FROM exc_usr_tutor " .
869 "WHERE ass_id = %s AND usr_id = %s AND tutor_id = %s",
870 array("integer", "integer", "integer"),
871 array($ass_id, $user_id, $ilUser->getId())
872 );
873
874 $ilDB->manipulateF(
875 "INSERT INTO exc_usr_tutor (ass_id, obj_id, usr_id, tutor_id, download_time) VALUES " .
876 "(%s, %s, %s, %s, %s)",
877 array("integer", "integer", "integer", "integer", "timestamp"),
878 array($ass_id, $exc_id, $user_id, $ilUser->getId(), ilUtil::now())
879 );
880 }
881 }
882
883 protected function downloadSingleFile($a_user_id, $filename, $filetitle, $a_team_id)
884 {
885 if ($this->ass_type->isSubmissionAssignedToTeam()) {
886 $storage_id = $a_team_id;
887 } else {
888 $storage_id = $a_user_id;
889 }
890
891 $filename = $this->initStorage()->getAbsoluteSubmissionPath() .
892 "/" . $storage_id . "/" . basename($filename);
893
894 ilUtil::deliverFile($filename, $filetitle);
895 }
896
897 protected function downloadMultipleFiles($a_filenames, $a_user_id, $a_multi_user = false)
898 {
900
901 $path = $this->initStorage()->getAbsoluteSubmissionPath();
902
903 $cdir = getcwd();
904
905 $zip = PATH_TO_ZIP;
906 $tmpdir = ilUtil::ilTempnam();
907 $tmpfile = ilUtil::ilTempnam();
908 $tmpzipfile = $tmpfile . ".zip";
909
910 ilUtil::makeDir($tmpdir);
911 chdir($tmpdir);
912
913 $assTitle = ilExAssignment::lookupTitle($this->assignment->getId());
914 $deliverFilename = str_replace(" ", "_", $assTitle);
915 if ($a_user_id > 0 && !$a_multi_user) {
916 $userName = ilObjUser::_lookupName($a_user_id);
917 $deliverFilename .= "_" . $userName["lastname"] . "_" . $userName["firstname"];
918 } else {
919 $deliverFilename .= "_files";
920 }
921 $orgDeliverFilename = trim($deliverFilename);
922 $deliverFilename = ilUtil::getASCIIFilename($orgDeliverFilename);
923 ilUtil::makeDir($tmpdir . "/" . $deliverFilename);
924 chdir($tmpdir . "/" . $deliverFilename);
925
926 //copy all files to a temporary directory and remove them afterwards
927 $parsed_files = $duplicates = array();
928 foreach ($a_filenames as $storage_id => $files) {
929 $pathname = $path . "/" . $storage_id;
930
931 foreach ($files as $filename) {
932 // peer review masked filenames, see deliverReturnedFiles()
933 if (isset($filename["tgt"])) {
934 $newFilename = $filename["tgt"];
935 $filename = $filename["src"];
936 } else {
937 $late = $filename["late"];
938 $filename = $filename["src"];
939
940 // remove timestamp
941 $newFilename = trim($filename);
942 $pos = strpos($newFilename, "_");
943 if ($pos !== false) {
944 $newFilename = substr($newFilename, $pos + 1);
945 }
946 // #11070
947 $chkName = strtolower($newFilename);
948 if (array_key_exists($chkName, $duplicates)) {
949 $suffix = strrpos($newFilename, ".");
950 $newFilename = substr($newFilename, 0, $suffix) .
951 " (" . (++$duplicates[$chkName]) . ")" .
952 substr($newFilename, $suffix);
953 } else {
954 $duplicates[$chkName] = 1;
955 }
956
957 if ($late) {
958 $newFilename = $lng->txt("exc_late_submission") . " - " .
959 $newFilename;
960 }
961 }
962
963 $newFilename = ilUtil::getASCIIFilename($newFilename);
964 $newFilename = $tmpdir . DIRECTORY_SEPARATOR . $deliverFilename . DIRECTORY_SEPARATOR . $newFilename;
965 // copy to temporal directory
966 $oldFilename = $pathname . DIRECTORY_SEPARATOR . $filename;
967 if (!copy($oldFilename, $newFilename)) {
968 echo 'Could not copy ' . $oldFilename . ' to ' . $newFilename;
969 }
970 touch($newFilename, filectime($oldFilename));
971 $parsed_files[] = ilUtil::escapeShellArg($deliverFilename . DIRECTORY_SEPARATOR . basename($newFilename));
972 }
973 }
974
975 chdir($tmpdir);
976 $zipcmd = $zip . " " . ilUtil::escapeShellArg($tmpzipfile) . " " . join(" ", $parsed_files);
977
978 exec($zipcmd);
979 ilUtil::delDir($tmpdir);
980
981 chdir($cdir);
982 ilUtil::deliverFile($tmpzipfile, $orgDeliverFilename . ".zip", "", false, true);
983 exit;
984 }
985
994 public static function downloadAllAssignmentFiles(ilExAssignment $a_ass, array $members, $to_path)
995 {
996 global $DIC;
997
998 $lng = $DIC->language();
999
1000 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php");
1001
1002 $storage = new ilFSStorageExercise($a_ass->getExerciseId(), $a_ass->getId());
1003 $storage->create();
1004
1005 ksort($members);
1006 //$savepath = $this->getExercisePath() . "/" . $this->obj_id . "/";
1007 $savepath = $storage->getAbsoluteSubmissionPath();
1008 $cdir = getcwd();
1009
1010
1011 // important check: if the directory does not exist
1012 // ILIAS stays in the current directory (echoing only a warning)
1013 // and the zip command below archives the whole ILIAS directory
1014 // (including the data directory) and sends a mega file to the user :-o
1015 if (!is_dir($savepath)) {
1016 return;
1017 }
1018 // Safe mode fix
1019 // chdir($this->getExercisePath());
1020
1021 $tmpdir = $storage->getTempPath();
1022 chdir($tmpdir);
1023 $zip = PATH_TO_ZIP;
1024
1025 // check free diskspace
1026 $dirsize = 0;
1027 foreach (array_keys($members) as $id) {
1028 $directory = $savepath . DIRECTORY_SEPARATOR . $id;
1029 $dirsize += ilUtil::dirsize($directory);
1030 }
1031 if ($dirsize > disk_free_space($tmpdir)) {
1032 return -1;
1033 }
1034
1035 $ass_type = $a_ass->getType();
1036
1037 // copy all member directories to the temporary folder
1038 // switch from id to member name and append the login if the member name is double
1039 // ensure that no illegal filenames will be created
1040 // remove timestamp from filename
1041 if ($a_ass->hasTeam()) {
1042 $team_dirs = array();
1043 $team_map = ilExAssignmentTeam::getAssignmentTeamMap($a_ass->getId());
1044 }
1045 foreach ($members as $id => $item) {
1046 $user = $item["name"];
1047 $user_files = $item["files"];
1048 $sourcedir = $savepath . DIRECTORY_SEPARATOR . $id;
1049 if (!is_dir($sourcedir)) {
1050 continue;
1051 }
1052
1053 // group by teams
1054 $team_dir = "";
1055 if (is_array($team_map) &&
1056 array_key_exists($id, $team_map)) {
1057 $team_id = $team_map[$id];
1058 if (!array_key_exists($team_id, $team_dirs)) {
1059 $team_dir = $lng->txt("exc_team") . " " . $team_id;
1060 ilUtil::makeDir($team_dir);
1061 $team_dirs[$team_id] = $team_dir;
1062 }
1063 $team_dir = $team_dirs[$team_id] . DIRECTORY_SEPARATOR;
1064 }
1065
1066 if ($a_ass->getAssignmentType()->isSubmissionAssignedToTeam()) {
1067 $targetdir = $team_dir . ilUtil::getASCIIFilename(
1068 $item["name"]
1069 );
1070 if ($targetdir == "") {
1071 continue;
1072 }
1073 } else {
1075 if ($a_ass->getAssignmentType()->usesTeams()) {
1076 $targetdir = $team_dir . $targetdir;
1077 }
1078 }
1079 ilUtil::makeDir($targetdir);
1080
1081 $sourcefiles = scandir($sourcedir);
1082 $duplicates = array();
1083 foreach ($sourcefiles as $sourcefile) {
1084 if ($sourcefile == "." || $sourcefile == "..") {
1085 continue;
1086 }
1087
1088 $targetfile = trim(basename($sourcefile));
1089 $pos = strpos($targetfile, "_");
1090 if ($pos !== false) {
1091 $targetfile = substr($targetfile, $pos + 1);
1092 }
1093
1094 if ($a_ass->getAssignmentType()->getSubmissionType() == self::TYPE_REPO_OBJECT) {
1095 $obj_id = ilObject::_lookupObjId($targetfile);
1096 $obj_type = ilObject::_lookupType($obj_id);
1097 $targetfile = $obj_type . "_" . $obj_id . ".zip";
1098 }
1099
1100
1101 // #14536
1102 if (array_key_exists($targetfile, $duplicates)) {
1103 $suffix = strrpos($targetfile, ".");
1104 $targetfile = substr($targetfile, 0, $suffix) .
1105 " (" . (++$duplicates[$targetfile]) . ")" .
1106 substr($targetfile, $suffix);
1107 } else {
1108 $duplicates[$targetfile] = 1;
1109 }
1110
1111 // late submission?
1112 if (is_array($user_files)) { // see #23900
1113 foreach ($user_files as $file) {
1114 if (basename($file["filename"]) == $sourcefile) {
1115 if ($file["late"]) {
1116 $targetfile = $lng->txt("exc_late_submission") . " - " .
1117 $targetfile;
1118 }
1119 break;
1120 }
1121 }
1122 }
1123
1124 $targetfile = ilUtil::getASCIIFilename($targetfile);
1125 $targetfile = $targetdir . DIRECTORY_SEPARATOR . $targetfile;
1126 $sourcefile = $sourcedir . DIRECTORY_SEPARATOR . $sourcefile;
1127
1128 if (!copy($sourcefile, $targetfile)) {
1129 include_once "Modules/Exercise/exceptions/class.ilExerciseException.php";
1130 throw new ilExerciseException("Could not copy " . basename($sourcefile) . " to '" . $targetfile . "'.");
1131 } else {
1132 // preserve time stamp
1133 touch($targetfile, filectime($sourcefile));
1134
1135 // blogs and portfolios are stored as zip and have to be unzipped
1138 ilUtil::unzip($targetfile);
1139 unlink($targetfile);
1140 }
1141 }
1142 }
1143 }
1144 $tmpzipfile = ilUtil::getASCIIFilename($lng->txt("exc_ass_submission_zip")) . ".zip";
1145 // Safe mode fix
1146 $zipcmd = $zip . " -r " . ilUtil::escapeShellArg($tmpzipfile) . " .";
1147 exec($zipcmd);
1148 //$path_final_zip_file = $to_path.DIRECTORY_SEPARATOR."Submissions/".$tmpzipfile;
1149 $path_final_zip_file = $to_path . DIRECTORY_SEPARATOR . $tmpzipfile;
1150
1151 if (file_exists($tmpdir . DIRECTORY_SEPARATOR . $tmpzipfile)) {
1152 copy($tmpzipfile, $path_final_zip_file);
1153 ilUtil::delDir($tmpdir);
1154
1155 //unzip the submissions zip file.(decided to unzip to allow the excel link the files more obvious when blog/portfolio)
1156 chdir($to_path);
1157 //TODO Bug in ilUtil -> if flat unzip fails. We can get rid of creating Submissions directory
1158 //ilUtil::unzip($path_final_zip_file,FALSE, TRUE);
1159 ilUtil::unzip($path_final_zip_file);
1160 unlink($path_final_zip_file);
1161 }
1162
1163 chdir($cdir);
1164 }
1165
1166
1173 protected function getTableUserWhere($a_team_mode = false)
1174 {
1175 $ilDB = $this->db;
1176
1177 if ($this->getAssignment()->getAssignmentType()->isSubmissionAssignedToTeam()) {
1178 $team_id = $this->getTeam()->getId();
1179 $where = " team_id = " . $ilDB->quote($team_id, "integer") . " ";
1180 } else {
1181 if ($a_team_mode) {
1182 $where = " " . $ilDB->in("user_id", $this->getUserIds(), "", "integer") . " ";
1183 } else {
1184 $where = " user_id = " . $ilDB->quote($this->getUserId(), "integer");
1185 }
1186 }
1187 return $where;
1188 }
1189
1190
1196 public function getLastSubmission()
1197 {
1198 $ilDB = $this->db;
1199
1200 $ilDB->setLimit(1);
1201
1202 $q = "SELECT obj_id,user_id,ts FROM exc_returned" .
1203 " WHERE ass_id = " . $ilDB->quote($this->assignment->getId(), "integer") .
1204 " AND " . $this->getTableUserWhere(true) .
1205 " AND (filename IS NOT NULL OR atext IS NOT NULL)" .
1206 " AND ts IS NOT NULL" .
1207 " ORDER BY ts DESC";
1208 $usr_set = $ilDB->query($q);
1209 $array = $ilDB->fetchAssoc($usr_set);
1210 return ilUtil::getMySQLTimestamp($array["ts"]);
1211 }
1212
1213
1214 //
1215 // OBJECTS
1216 //
1217
1226 public function addResourceObject($a_wsp_id, $a_text = null)
1227 {
1228 $ilDB = $this->db;
1229
1230 if ($this->getAssignment()->getAssignmentType()->isSubmissionAssignedToTeam()) {
1231 $user_id = 0;
1232 $team_id = $this->getTeam()->getId();
1233 } else {
1234 $user_id = $this->getUserId();
1235 $team_id = 0;
1236 }
1237
1238 // repository objects must be unique in submissions
1239 // the same repo object cannot be used in different submissions or even different assignment/exercises
1240 // why? -> the access handling would fail, since the access depends e.g. on teams or even phase of the
1241 // assignment
1242 if ($this->getAssignment()->getAssignmentType()->getSubmissionType() == ilExSubmission::TYPE_REPO_OBJECT) {
1243 $repos_ass_type_ids = $this->ass_types->getIdsForSubmissionType(ilExSubmission::TYPE_REPO_OBJECT);
1244 $subs = $this->getSubmissionsForFilename($a_wsp_id, $repos_ass_type_ids);
1245 if (count($subs) > 0) {
1246 throw new ilExerciseException("Repository object $a_wsp_id is already assigned to another assignment.");
1247 }
1248 }
1249
1250 $next_id = $ilDB->nextId("exc_returned");
1251 $query = sprintf(
1252 "INSERT INTO exc_returned " .
1253 "(returned_id, obj_id, user_id, filetitle, ass_id, ts, atext, late, team_id) " .
1254 "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)",
1255 $ilDB->quote($next_id, "integer"),
1256 $ilDB->quote($this->assignment->getExerciseId(), "integer"),
1257 $ilDB->quote($user_id, "integer"),
1258 $ilDB->quote($a_wsp_id, "text"),
1259 $ilDB->quote($this->assignment->getId(), "integer"),
1260 $ilDB->quote(ilUtil::now(), "timestamp"),
1261 $ilDB->quote($a_text, "text"),
1262 $ilDB->quote($this->isLate(), "integer"),
1263 $ilDB->quote($team_id, "integer")
1264 );
1265 $ilDB->manipulate($query);
1266
1267 return $next_id;
1268 }
1269
1275 public function deleteResourceObject($a_returned_id)
1276 {
1277 $ilDB = $this->db;
1278
1279 $ilDB->manipulate("DELETE FROM exc_returned" .
1280 " WHERE obj_id = " . $ilDB->quote($this->assignment->getExerciseId(), "integer") .
1281 " AND " . $this->getTableUserWhere(false) .
1282 " AND ass_id = " . $ilDB->quote($this->assignment->getId(), "integer") .
1283 " AND returned_id = " . $ilDB->quote($a_returned_id, "integer"));
1284 }
1285
1292 public function updateTextSubmission($a_text)
1293 {
1294 $ilDB = $this->db;
1295
1296 $files = $this->getFiles();
1297
1298 // no text = remove submission
1299 if (!trim($a_text)) {
1300 $this->deleteAllFiles();
1301 return;
1302 }
1303
1304 if (!$files) {
1305 return $this->addResourceObject("TEXT", $a_text);
1306 } else {
1307 $files = array_shift($files);
1308 $id = $files["returned_id"];
1309 if ($id) {
1310 $ilDB->manipulate("UPDATE exc_returned" .
1311 " SET atext = " . $ilDB->quote($a_text, "text") .
1312 ", ts = " . $ilDB->quote(ilUtil::now(), "timestamp") .
1313 ", late = " . $ilDB->quote($this->isLate(), "integer") .
1314 " WHERE returned_id = " . $ilDB->quote($id, "integer"));
1315 return $id;
1316 }
1317 }
1318 }
1319
1320
1321 //
1322 // GUI helper
1323 //
1324
1325 // :TODO:
1326
1327 public function getDownloadedFilesInfoForTableGUIS($a_parent_obj, $a_parent_cmd = null)
1328 {
1329 $lng = $this->lng;
1331
1332 $result = array();
1333 $result["files"]["count"] = "---";
1334
1335 // submission:
1336 // see if files have been resubmmited after solved
1337 $last_sub = $this->getLastSubmission();
1338 if ($last_sub) {
1339 $last_sub = ilDatePresentation::formatDate(new ilDateTime($last_sub, IL_CAL_DATETIME));
1340 } else {
1341 $last_sub = "---";
1342 }
1343 /* #13741 - status_time has been reduced to grading (mark/status)
1344 if (self::lookupUpdatedSubmission($a_ass_id, $a_user_id) == 1)
1345 {
1346 $last_sub = "<b>".$last_sub."</b>";
1347 }
1348 */
1349 $result["last_submission"]["txt"] = $lng->txt("exc_last_submission");
1350 $result["last_submission"]["value"] = $last_sub;
1351
1352 // #16994
1353 $ilCtrl->setParameterByClass("ilexsubmissionfilegui", "member_id", $this->getUserId());
1354
1355 // assignment type specific
1356 switch ($this->assignment->getType()) {
1358 // data is merged by team - see above
1359 // fallthrough
1360
1362 $all_files = $this->getFiles();
1363 $late_files = 0;
1364 foreach ($all_files as $file) {
1365 if ($file["late"]) {
1366 $late_files++;
1367 }
1368 }
1369
1370 // nr of submitted files
1371 $result["files"]["txt"] = $lng->txt("exc_files_returned");
1372 if ($late_files) {
1373 $result["files"]["txt"] .= ' - <span class="warning">' . $lng->txt("exc_late_submission") . " (" . $late_files . ")</span>";
1374 }
1375 $sub_cnt = count($all_files);
1376 $new = $this->lookupNewFiles();
1377 if (count($new) > 0) {
1378 $sub_cnt .= " " . sprintf($lng->txt("cnt_new"), count($new));
1379 }
1380
1381 $result["files"]["count"] = $sub_cnt;
1382
1383 // download command
1384 if ($sub_cnt > 0) {
1385 $result["files"]["download_url"] =
1386 $ilCtrl->getLinkTargetByClass("ilexsubmissionfilegui", "downloadReturned");
1387
1388 if (count($new) <= 0) {
1389 $result["files"]["download_txt"] = $lng->txt("exc_tbl_action_download_files");
1390 } else {
1391 $result["files"]["download_txt"] = $lng->txt("exc_tbl_action_download_all_files");
1392 }
1393
1394 // download new files only
1395 if (count($new) > 0) {
1396 $result["files"]["download_new_url"] =
1397 $ilCtrl->getLinkTargetByClass("ilexsubmissionfilegui", "downloadNewReturned");
1398
1399 $result["files"]["download_new_txt"] = $lng->txt("exc_tbl_action_download_new_files");
1400 }
1401 }
1402 break;
1403
1405 $result["files"]["txt"] = $lng->txt("exc_blog_returned");
1406 $blogs = $this->getFiles();
1407 if ($blogs) {
1408 $blogs = array_pop($blogs);
1409 if ($blogs && substr($blogs["filename"], -1) != "/") {
1410 if ($blogs["late"]) {
1411 $result["files"]["txt"] .= ' - <span class="warning">' . $lng->txt("exc_late_submission") . "</span>";
1412 }
1413
1414 $result["files"]["count"] = 1;
1415
1416 $result["files"]["download_url"] =
1417 $ilCtrl->getLinkTargetByClass("ilexsubmissionfilegui", "downloadReturned");
1418
1419 $result["files"]["download_txt"] = $lng->txt("exc_tbl_action_download_files");
1420 }
1421 }
1422 break;
1423
1425 $result["files"]["txt"] = $lng->txt("exc_portfolio_returned");
1426 $portfolios = $this->getFiles();
1427 if ($portfolios) {
1428 $portfolios = array_pop($portfolios);
1429 if ($portfolios && substr($portfolios["filename"], -1) != "/") {
1430 if ($portfolios["late"]) {
1431 $result["files"]["txt"] .= ' - <span class="warning">' . $lng->txt("exc_late_submission") . "</span>";
1432 }
1433
1434 $result["files"]["count"] = 1;
1435
1436 $result["files"]["download_url"] =
1437 $ilCtrl->getLinkTargetByClass("ilexsubmissionfilegui", "downloadReturned");
1438
1439 $result["files"]["download_txt"] = $lng->txt("exc_tbl_action_download_files");
1440 }
1441 }
1442 break;
1443
1445 $result["files"]["txt"] = $lng->txt("exc_files_returned_text");
1446 $files = $this->getFiles();
1447 if ($files) {
1448 $result["files"]["count"] = 1;
1449
1450 $files = array_shift($files);
1451 if (trim($files["atext"])) {
1452 if ($files["late"]) {
1453 $result["files"]["txt"] .= ' - <span class="warning">' . $lng->txt("exc_late_submission") . "</span>";
1454 }
1455
1456 $result["files"]["download_url"] =
1457 $ilCtrl->getLinkTargetByClass("ilexsubmissiontextgui", "showAssignmentText");
1458
1459 $result["files"]["download_txt"] = $lng->txt("exc_tbl_action_text_assignment_show");
1460 }
1461 }
1462 break;
1463
1465 $result["files"]["txt"] = $lng->txt("exc_wiki_returned");
1466 $objs = $this->getFiles();
1467 if ($objs) {
1468 $objs = array_pop($objs);
1469 if ($objs && substr($objs["filename"], -1) != "/") {
1470 if ($objs["late"]) {
1471 $result["files"]["txt"] .= ' - <span class="warning">' . $lng->txt("exc_late_submission") . "</span>";
1472 }
1473
1474 $result["files"]["count"] = 1;
1475
1476 $result["files"]["download_url"] =
1477 $ilCtrl->getLinkTargetByClass("ilexsubmissionfilegui", "downloadReturned");
1478
1479 $result["files"]["download_txt"] = $lng->txt("exc_tbl_action_download_files");
1480 }
1481 }
1482 break;
1483 }
1484
1485 $ilCtrl->setParameterByClass("ilexsubmissionfilegui", "member_id", "");
1486
1487 return $result;
1488 }
1489
1497 public static function getSubmissionsForFilename($a_filename, $a_assignment_types = array())
1498 {
1499 global $DIC;
1500
1501 $db = $DIC->database();
1502
1503 $query = "SELECT * FROM exc_returned r LEFT JOIN exc_assignment a" .
1504 " ON (r.ass_id = a.id) " .
1505 " WHERE r.filetitle = " . $db->quote($a_filename, "string");
1506
1507 if (is_array($a_assignment_types) && count($a_assignment_types) > 0) {
1508 $query .= " AND " . $db->in("a.type", $a_assignment_types, false, "integer");
1509 }
1510
1511 $set = $db->query($query);
1512 $rets = array();
1513 while ($rec = $db->fetchAssoc($set)) {
1514 $rets[] = $rec;
1515 }
1516
1517
1518 return $rets;
1519 }
1520
1521 /*
1522 * @param $a_user_id
1523 * @return string
1524 */
1525 public static function getDirectoryNameFromUserData($a_user_id)
1526 {
1527 $userName = ilObjUser::_lookupName($a_user_id);
1528 $targetdir = ilUtil::getASCIIFilename(
1529 trim($userName["lastname"]) . "_" .
1530 trim($userName["firstname"]) . "_" .
1531 trim($userName["login"]) . "_" .
1532 $userName["user_id"]
1533 );
1534
1535 return $targetdir;
1536 }
1537
1543 public static function getAssignmentParticipants(int $a_exercise_id, int $a_ass_id) : array
1544 {
1545 global $DIC;
1546
1547 $ilDB = $DIC->database();
1548
1549 $participants = array();
1550 $query = "SELECT user_id FROM exc_returned WHERE ass_id = " .
1551 $ilDB->quote($a_ass_id, "integer") .
1552 " AND obj_id = " .
1553 $ilDB->quote($a_exercise_id, "integer");
1554
1555 $res = $ilDB->query($query);
1556
1557 while ($row = $ilDB->fetchAssoc($res)) {
1558 $participants[] = $row['user_id'];
1559 }
1560
1561 return $participants;
1562 }
1563}
$result
user()
Definition: user.php:4
$success
Definition: Utf8Test.php:86
$path
Definition: aliased.php:25
exit
Definition: backend.php:16
$filename
Definition: buildRTE.php:89
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_DATETIME
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date @access public.
@classDescription Date and time handling
Exercise assignment team.
static getAssignmentTeamMap($a_ass_id)
Get team structure for assignment.
static getInstanceByUserId($a_assignment_id, $a_user_id, $a_create_on_demand=false)
static getInstance()
Get instance.
Exercise assignment.
getExerciseId()
Get exercise id.
getId()
Get assignment id.
static getInstancesByExercise($a_exc_id)
getAssignmentType()
Get assignment type.
static lookupTitle($a_id)
Lookup title.
static lookupType($a_id)
Lookup type.
Exercise peer review.
Exercise submission //TODO: This class has to much static methods related to delivered "files".
static downloadAllAssignmentFiles(ilExAssignment $a_ass, array $members, $to_path)
Download all submitted files of an assignment (all user)
downloadSingleFile($a_user_id, $filename, $filetitle, $a_team_id)
static deleteUser($a_exc_id, $a_user_id)
Delete all delivered files of user.
static getAllAssignmentFiles($a_exc_id, $a_ass_id)
processUploadedZipFile($fileTmp)
processes errorhandling etc for uploaded archive
addResourceObject($a_wsp_id, $a_text=null)
Add personal resource or repository object (ref_id) to assigment.
downloadMultipleFiles($a_filenames, $a_user_id, $a_multi_user=false)
isInTeam($a_user_id=null)
getTableUserWhere($a_team_mode=false)
Get user/team where clause.
static getDirectoryNameFromUserData($a_user_id)
getStorageId()
Get storage id.
static lookupExerciseIdForReturnedId($a_returned_id)
Get exercise from submission id (used in ilObjMediaObject)
static hasAnySubmissions($a_ass_id)
static getAssignmentFilesByUsers(int $a_exc_id, int $a_ass_id, array $a_users)
deleteSelectedFiles(array $file_id_array)
Deletes already delivered files.
lookupNewFiles($a_tutor=null)
Check how much files have been uploaded by the learner after the last download of the tutor.
__construct(ilExAssignment $a_ass, $a_user_id, ilExAssignmentTeam $a_team=null, $a_is_tutor=false, $a_public_submissions=false)
static getAssignmentParticipants(int $a_exercise_id, int $a_ass_id)
downloadFiles(array $a_file_ids=null, $a_only_new=false, $a_peer_review_mask_filename=false)
deleteResourceObject($a_returned_id)
Remove personal resource to assigment.
updateTextSubmission($a_text)
Handle text assignment submissions.
uploadFile($a_http_post_files, $unzip=false)
Save submitted file of user.
static findUserFiles($a_user_id, $a_filetitle)
Check if given file was assigned.
getDownloadedFilesInfoForTableGUIS($a_parent_obj, $a_parent_cmd=null)
getFiles(array $a_file_ids=null, $a_only_valid=false, $a_min_timestamp=null)
Get submission items (not only files)
getLastSubmission()
Get the date of the last submission of a user for the assignment.
static getSubmissionsForFilename($a_filename, $a_assignment_types=array())
Get assignment return entries for a filename.
getLastDownloadTime(array $a_user_ids)
static getInstanceByIds($a_ass_id, $a_user_id=0)
Get instance by IDs (recommended for consumer code)
Exercise exceptions class.
Class to report exception.
static getValidFilename($a_filename)
Get valid filename.
static processZipFile($a_directory, $a_file, $structure, $ref_id=null, $containerType=null, $tree=null, $access_handler=null)
unzips in given directory and processes uploaded zip for use as single files
static utf8_encode($string)
utf8-encodes string if it is not a valid utf8-string.
static recursive_dirscan($dir, &$arr)
Recursively scans a given directory and writes path and filename into referenced array.
static _lookupName($a_user_id)
lookup user name
static _lookupObjId($a_id)
static _lookupTitle($a_id)
lookup object title
static _lookupType($a_id, $a_reference=false)
lookup object type
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 escapeShellArg($a_arg)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static now()
Return current timestamp in Y-m-d H:i:s format.
static ilTempnam($a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static deliverFile( $a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static dirsize($directory)
get size of a directory or a file.
$key
Definition: croninfo.php:18
$valid
if(!array_key_exists('StateId', $_REQUEST)) $id
global $ilCtrl
Definition: ilias.php:18
$files
Definition: metarefresh.php:49
$row
$query
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB
$ilUser
Definition: imgupload.php:18