62 protected \ILIAS\Exercise\InternalGUIService
$gui;
63 protected \ILIAS\Exercise\InternalDomainService
$domain;
72 protected int $id = 0;
119 $this->domain =
$DIC->exercise()->internal()->domain();
120 $this->db =
$DIC->database();
121 $this->
lng = $DIC->language();
122 $this->
user = $DIC->user();
123 $this->app_event_handler =
$DIC[
"ilAppEventHandler"];
125 $this->
access = $DIC->access();
126 $this->domain =
$DIC->exercise()->internal()->domain();
127 $this->gui =
$DIC->exercise()->internal()->gui();
129 $this->
setType(self::TYPE_UPLOAD);
138 $this->string_transform =
$DIC->refinery()
153 $set =
$ilDB->query(
"SELECT * FROM exc_assignment " .
154 " WHERE exc_id = " .
$ilDB->quote($a_exc_id,
"integer") .
155 " ORDER BY order_nr");
159 while ($rec =
$ilDB->fetchAssoc($set)) {
161 $rec[
"order_val"] = $order_val;
164 $ass->initFromDB($rec);
189 FROM exc_ass_file_order
190 WHERE assignment_id = {$db->quote($a_ass_id, 'integer')}
191 AND filename = {$db->quote($a_file_data['entry'], 'text')}
197 $order_val = (
int) $row[
'order_nr'];
198 $order_id = (
int) $row[
'id'];
200 return array($order_val, $order_id);
205 return $this->ass_type->usesTeams();
208 public function setId(
int $a_val): void
220 $this->exc_id = $a_val;
225 return $this->exc_id;
230 $this->start_time = $a_val;
235 return $this->start_time;
240 $this->deadline = $a_val;
245 return $this->deadline;
254 $this->deadline_mode = $a_val;
259 return $this->deadline_mode;
264 $this->relative_deadline = $a_val;
269 return $this->relative_deadline;
274 $this->rel_deadline_last_subm = $a_val;
279 return $this->rel_deadline_last_subm;
289 if ($this->ass_type->usesTeams()) {
293 return $this->getDeadline();
295 $a_user_id = $team_id;
299 $set =
$ilDB->query(
"SELECT tstamp FROM exc_idl" .
300 " WHERE ass_id = " .
$ilDB->quote($this->getId(),
"integer") .
301 " AND member_id = " .
$ilDB->quote($a_user_id,
"integer") .
302 " AND is_team = " .
$ilDB->quote($is_team,
"integer"));
303 $row =
$ilDB->fetchAssoc($set);
306 return max(($row[
"tstamp"] ?? 0), $this->getDeadline());
314 $set =
$ilDB->query(
"SELECT MAX(tstamp) FROM exc_idl" .
315 " WHERE ass_id = " .
$ilDB->quote($this->getId(),
"integer"));
316 $row =
$ilDB->fetchAssoc($set);
317 return $row[
"tstamp"] ?? 0;
323 $this->deadline2 = $a_val;
328 return $this->deadline2;
333 $this->instruction = $a_val;
338 return $this->instruction;
343 $inst = $this->getInstruction();
345 $is_html = (strlen($inst) != strlen(strip_tags($inst)));
348 $this->string_transform->makeClickable()->transform($inst)
352 $inst = $this->gui->html()->escapeCurly($inst);
358 $this->title = $a_val;
368 $this->mandatory = $a_val;
373 return $this->mandatory;
378 $this->order_nr = $a_val;
383 return $this->order_nr;
393 if ($this->isValidType($a_value)) {
394 $this->type = $a_value;
396 $this->ass_type = $this->types->getById($a_value);
398 if ($this->ass_type->usesTeams()) {
399 $this->setPeerReview(
false);
406 return $this->ass_type;
421 return $this->types->isValidId($a_value);
426 $this->peer = $a_value;
436 $this->peer_min = $a_value;
441 return $this->peer_min;
446 $this->peer_unlock = $a_value;
451 return $this->peer_unlock;
459 $this->peer_dl = $a_val;
464 return $this->peer_dl;
474 $this->peer_valid = $a_value;
479 return $this->peer_valid;
484 $this->peer_rating = $a_val;
489 return $this->peer_rating;
494 $this->peer_text = $a_val;
499 return $this->peer_text;
504 $this->peer_file = $a_val;
509 return $this->peer_file;
514 $this->peer_personal = $a_val;
519 return $this->peer_personal;
524 $a_value = (is_numeric($a_value) && (
int) $a_value > 0)
527 $this->peer_char = $a_value;
532 return $this->peer_char;
537 $this->crit_cat = $a_value;
542 return $this->crit_cat;
545 public function getPeerReviewCriteriaCatalogueItems(): array
547 if ($this->crit_cat) {
552 if ($this->peer_rating) {
556 if ($this->peer_text) {
559 if ($this->peer_char) {
560 $crit->setMinChars($this->peer_char);
565 if ($this->peer_file) {
575 $this->feedback_file = $a_value;
580 return $this->feedback_file;
588 $this->feedback_cron = $a_value;
593 return $this->feedback_cron;
599 $this->feedback_date = $a_value;
604 return $this->feedback_date;
613 $this->feedback_date_custom = $a_value;
618 return $this->feedback_date_custom;
624 $this->team_tutor = $a_value;
629 return $this->team_tutor;
635 $this->max_file = $a_value;
640 return $this->max_file;
646 $this->portfolio_template = $a_val;
651 return $this->portfolio_template;
662 "SELECT * FROM exc_assignment " .
663 " WHERE id = " .
$ilDB->quote($this->getId(),
"integer")
665 $rec =
$ilDB->fetchAssoc($set);
668 if (is_array($rec)) {
669 $this->initFromDB($rec);
680 $this->setId((
int) $a_set[
"id"]);
681 $this->setExerciseId((
int) $a_set[
"exc_id"]);
682 $this->setDeadline((
int) $a_set[
"time_stamp"]);
683 $this->setExtendedDeadline((
int) $a_set[
"deadline2"]);
684 $this->setInstruction((
string) $a_set[
"instruction"]);
685 $this->setTitle((
string) $a_set[
"title"]);
686 $this->setStartTime((
int) $a_set[
"start_time"]);
687 $this->setOrderNr((
int) $a_set[
"order_nr"]);
688 $this->setMandatory((
bool) $a_set[
"mandatory"]);
689 $this->setType((
int) $a_set[
"type"]);
690 $this->setPeerReview((
bool) $a_set[
"peer"]);
691 $this->setPeerReviewMin((
int) $a_set[
"peer_min"]);
692 $this->setPeerReviewSimpleUnlock((
int) $a_set[
"peer_unlock"]);
693 $this->setPeerReviewDeadline((
int) $a_set[
"peer_dl"]);
694 $this->setPeerReviewValid((
int) $a_set[
"peer_valid"]);
695 $this->setPeerReviewFileUpload((
bool) $a_set[
"peer_file"]);
696 $this->setPeerReviewPersonalized((
bool) $a_set[
"peer_prsl"]);
697 $this->setPeerReviewChars((
int) $a_set[
"peer_char"]);
698 $this->setPeerReviewText((
bool) $a_set[
"peer_text"]);
699 $this->setPeerReviewRating((
bool) $a_set[
"peer_rating"]);
700 $this->setPeerReviewCriteriaCatalogue((
int) $a_set[
"peer_crit_cat"]);
701 $this->setFeedbackFile((
string) $a_set[
"fb_file"]);
702 $this->setFeedbackDate((
int) $a_set[
"fb_date"]);
703 $this->setFeedbackDateCustom((
int) $a_set[
"fb_date_custom"]);
704 $this->setFeedbackCron((
bool) $a_set[
"fb_cron"]);
705 $this->setTeamTutor((
bool) $a_set[
"team_tutor"]);
706 $this->setMaxFile((
int) $a_set[
"max_file"]);
707 $this->setPortfolioTemplateId((
int) $a_set[
"portfolio_template"]);
708 $this->setMinCharLimit((
int) $a_set[
"min_char_limit"]);
709 $this->setMaxCharLimit((
int) $a_set[
"max_char_limit"]);
710 $this->setDeadlineMode((
int) $a_set[
"deadline_mode"]);
711 $this->setRelativeDeadline((
int) $a_set[
"relative_deadline"]);
712 $this->setRelDeadlineLastSubmission((
int) $a_set[
"rel_deadline_last_subm"]);
722 if ($this->getOrderNr() == 0) {
724 self::lookupMaxOrderNrForEx($this->getExerciseId())
729 $next_id =
$ilDB->nextId(
"exc_assignment");
730 $ilDB->insert(
"exc_assignment", array(
731 "id" => array(
"integer", $next_id),
732 "exc_id" => array(
"integer", $this->getExerciseId()),
733 "time_stamp" => array(
"integer", $this->getDeadline()),
734 "deadline2" => array(
"integer", $this->getExtendedDeadline()),
735 "instruction" => array(
"clob", $this->getInstruction()),
736 "title" => array(
"text", $this->
getTitle()),
737 "start_time" => array(
"integer", $this->getStartTime()),
738 "order_nr" => array(
"integer", $this->getOrderNr()),
739 "mandatory" => array(
"integer", $this->getMandatory()),
740 "type" => array(
"integer", $this->getType()),
741 "peer" => array(
"integer", $this->getPeerReview()),
742 "peer_min" => array(
"integer", $this->getPeerReviewMin()),
743 "peer_unlock" => array(
"integer", $this->getPeerReviewSimpleUnlock()),
744 "peer_dl" => array(
"integer", $this->getPeerReviewDeadline()),
745 "peer_valid" => array(
"integer", $this->getPeerReviewValid()),
746 "peer_file" => array(
"integer", $this->hasPeerReviewFileUpload()),
747 "peer_prsl" => array(
"integer", $this->hasPeerReviewPersonalized()),
748 "peer_char" => array(
"integer", $this->getPeerReviewChars()),
749 "peer_text" => array(
"integer", (
int) $this->hasPeerReviewText()),
750 "peer_rating" => array(
"integer", (
int) $this->hasPeerReviewRating()),
751 "peer_crit_cat" => array(
"integer", $this->getPeerReviewCriteriaCatalogue()),
752 "fb_file" => array(
"text", $this->getFeedbackFile()),
753 "fb_date" => array(
"integer", $this->getFeedbackDate()),
754 "fb_date_custom" => array(
"integer", $this->getFeedbackDateCustom()),
755 "fb_cron" => array(
"integer", $this->hasFeedbackCron()),
756 "team_tutor" => array(
"integer", $this->getTeamTutor()),
757 "max_file" => array(
"integer", $this->getMaxFile()),
758 "portfolio_template" => array(
"integer", $this->getPortfolioTemplateId()),
759 "min_char_limit" => array(
"integer", $this->getMinCharLimit()),
760 "max_char_limit" => array(
"integer", $this->getMaxCharLimit()),
761 "relative_deadline" => array(
"integer", $this->getRelativeDeadline()),
762 "rel_deadline_last_subm" => array(
"integer", $this->getRelDeadlineLastSubmission()),
763 "deadline_mode" => array(
"integer", $this->getDeadlineMode()),
764 "solution_rid" => array(
"text",
''),
766 $this->setId($next_id);
768 $exc->updateAllUsersStatus();
770 $this->domain->assignment()->instructionFiles($next_id)->createCollection();
772 self::createNewAssignmentRecords($next_id, $exc);
774 $this->handleCalendarEntries(
"create", $exc);
787 "exc_id" => array(
"integer", $this->getExerciseId()),
788 "time_stamp" => array(
"integer", $this->getDeadline()),
789 "deadline2" => array(
"integer", $this->getExtendedDeadline()),
790 "instruction" => array(
"clob", $this->getInstruction()),
791 "title" => array(
"text", $this->
getTitle()),
792 "start_time" => array(
"integer", $this->getStartTime()),
793 "order_nr" => array(
"integer", $this->getOrderNr()),
794 "mandatory" => array(
"integer", $this->getMandatory()),
795 "type" => array(
"integer", $this->getType()),
796 "peer" => array(
"integer", $this->getPeerReview()),
797 "peer_min" => array(
"integer", $this->getPeerReviewMin()),
798 "peer_unlock" => array(
"integer", $this->getPeerReviewSimpleUnlock()),
799 "peer_dl" => array(
"integer", $this->getPeerReviewDeadline()),
800 "peer_valid" => array(
"integer", $this->getPeerReviewValid()),
801 "peer_file" => array(
"integer", $this->hasPeerReviewFileUpload()),
802 "peer_prsl" => array(
"integer", $this->hasPeerReviewPersonalized()),
803 "peer_char" => array(
"integer", $this->getPeerReviewChars()),
804 "peer_text" => array(
"integer", (
int) $this->hasPeerReviewText()),
805 "peer_rating" => array(
"integer", (
int) $this->hasPeerReviewRating()),
806 "peer_crit_cat" => array(
"integer", $this->getPeerReviewCriteriaCatalogue()),
807 "fb_file" => array(
"text", $this->getFeedbackFile()),
808 "fb_date" => array(
"integer", $this->getFeedbackDate()),
809 "fb_date_custom" => array(
"integer", $this->getFeedbackDateCustom()),
810 "fb_cron" => array(
"integer", $this->hasFeedbackCron()),
811 "team_tutor" => array(
"integer", $this->getTeamTutor()),
812 "max_file" => array(
"integer", $this->getMaxFile()),
813 "portfolio_template" => array(
"integer", $this->getPortfolioTemplateId()),
814 "min_char_limit" => array(
"integer", $this->getMinCharLimit()),
815 "max_char_limit" => array(
"integer", $this->getMaxCharLimit()),
816 "deadline_mode" => array(
"integer", $this->getDeadlineMode()),
817 "relative_deadline" => array(
"integer", $this->getRelativeDeadline()),
818 "rel_deadline_last_subm" => array(
"integer", $this->getRelDeadlineLastSubmission())
821 "id" => array(
"integer", $this->
getId()),
825 $exc->updateAllUsersStatus();
827 $this->handleCalendarEntries(
"update", $exc);
833 public function delete(
835 bool $update_user_status =
true
841 foreach ($exc_members->getMembers() as $mem) {
843 $submission->deleteAllFiles();
847 "DELETE FROM exc_usr_tutor " .
850 array($this->
getId())
854 if ($this->getPeerReview()) {
856 $peer_review->resetPeerReviews();
860 "DELETE FROM exc_ass_file_order" .
861 " WHERE assignment_id = " .
$ilDB->quote($this->getId(),
'integer')
865 "DELETE FROM exc_mem_ass_status" .
866 " WHERE ass_id = " .
$ilDB->quote($this->getId(),
'integer')
870 "DELETE FROM exc_assignment WHERE " .
871 " id = " .
$ilDB->quote($this->getId(),
"integer")
874 if ($update_user_status) {
878 $this->handleCalendarEntries(
"delete", $exc);
883 $reminder->deleteReminders($this->
getId());
886 $this->domain->team()->deleteTeamsOfAssignment($this->
getId());
889 $this->domain->assignment()->instructionFiles($this->
getId())
890 ->deleteCollection();
903 $set =
$ilDB->query(
"SELECT * FROM exc_assignment " .
904 " WHERE exc_id = " .
$ilDB->quote($a_exc_id,
"integer") .
905 " ORDER BY order_nr");
909 while ($rec =
$ilDB->fetchAssoc($set)) {
911 "id" => (
int) $rec[
"id"],
912 "exc_id" => (
int) $rec[
"exc_id"],
913 "deadline" => (
int) $rec[
"time_stamp"],
914 "deadline2" => (
int) $rec[
"deadline2"],
915 "instruction" => (
string) $rec[
"instruction"],
916 "title" => (
string) $rec[
"title"],
917 "start_time" => (
int) $rec[
"start_time"],
918 "order_val" => $order_val,
919 "mandatory" => (
bool) $rec[
"mandatory"],
920 "type" => (
int) $rec[
"type"],
921 "peer" => (
bool) $rec[
"peer"],
922 "peer_min" => (
int) $rec[
"peer_min"],
923 "peer_dl" => (
int) $rec[
"peer_dl"],
924 "peer_file" => (
bool) $rec[
"peer_file"],
925 "peer_prsl" => (
bool) $rec[
"peer_prsl"],
926 "fb_file" => (
string) $rec[
"fb_file"],
927 "fb_date" => (
int) $rec[
"fb_date"],
928 "fb_cron" => (
bool) $rec[
"fb_cron"],
929 "deadline_mode" => (
int) $rec[
"deadline_mode"],
930 "relative_deadline" => (
int) $rec[
"relative_deadline"],
931 "rel_deadline_last_subm" => (
int) $rec[
"rel_deadline_last_subm"]
948 array $a_crit_cat_map
952 $ass_domain =
$DIC->exercise()->internal()->domain()->assignment();
953 $ass_data = self::getInstancesByExercise($a_old_exc_id);
954 foreach ($ass_data as
$d) {
957 $new_ass->setExerciseId($a_new_exc_id);
958 $new_ass->setTitle(
$d->getTitle());
959 $new_ass->setDeadline(
$d->getDeadline());
960 $new_ass->setExtendedDeadline(
$d->getExtendedDeadline());
961 $new_ass->setInstruction(
$d->getInstruction());
962 $new_ass->setMandatory(
$d->getMandatory());
963 $new_ass->setOrderNr(
$d->getOrderNr());
964 $new_ass->setStartTime(
$d->getStartTime());
965 $new_ass->setType(
$d->getType());
966 $new_ass->setPeerReview(
$d->getPeerReview());
967 $new_ass->setPeerReviewMin(
$d->getPeerReviewMin());
968 $new_ass->setPeerReviewDeadline(
$d->getPeerReviewDeadline());
969 $new_ass->setPeerReviewFileUpload(
$d->hasPeerReviewFileUpload());
970 $new_ass->setPeerReviewPersonalized(
$d->hasPeerReviewPersonalized());
971 $new_ass->setPeerReviewValid(
$d->getPeerReviewValid());
972 $new_ass->setPeerReviewChars(
$d->getPeerReviewChars());
973 $new_ass->setPeerReviewText(
$d->hasPeerReviewText());
974 $new_ass->setPeerReviewRating(
$d->hasPeerReviewRating());
975 $new_ass->setPeerReviewCriteriaCatalogue(
$d->getPeerReviewCriteriaCatalogue());
976 $new_ass->setPeerReviewSimpleUnlock(
$d->getPeerReviewSimpleUnlock());
977 $new_ass->setFeedbackFile(
$d->getFeedbackFile());
978 $new_ass->setFeedbackDate(
$d->getFeedbackDate());
979 $new_ass->setFeedbackDateCustom(
$d->getFeedbackDateCustom());
980 $new_ass->setFeedbackCron(
$d->hasFeedbackCron());
981 $new_ass->setTeamTutor(
$d->getTeamTutor());
982 $new_ass->setMaxFile(
$d->getMaxFile());
983 $new_ass->setMinCharLimit(
$d->getMinCharLimit());
984 $new_ass->setMaxCharLimit(
$d->getMaxCharLimit());
985 $new_ass->setPortfolioTemplateId(
$d->getPortfolioTemplateId());
986 $new_ass->setDeadlineMode(
$d->getDeadlineMode());
987 $new_ass->setRelativeDeadline(
$d->getRelativeDeadline());
988 $new_ass->setRelDeadlineLastSubmission(
$d->getRelDeadlineLastSubmission());
991 if (
$d->getPeerReviewCriteriaCatalogue() &&
992 array_key_exists(
$d->getPeerReviewCriteriaCatalogue(), $a_crit_cat_map)) {
993 $new_ass->setPeerReviewCriteriaCatalogue($a_crit_cat_map[
$d->getPeerReviewCriteriaCatalogue()]);
999 $ass_domain->instructionFiles(
$d->getId())->cloneTo($new_ass->getId());
1002 $ass_domain->sampleSolution(
$d->getId())->cloneTo($new_ass->getId());
1009 if ($rmd_sub->getReminderStatus()) {
1011 $new_rmd_sub->setReminderStatus($rmd_sub->getReminderStatus());
1012 $new_rmd_sub->setReminderStart($rmd_sub->getReminderStart());
1013 $new_rmd_sub->setReminderEnd($rmd_sub->getReminderEnd());
1014 $new_rmd_sub->setReminderFrequency($rmd_sub->getReminderFrequency());
1015 $new_rmd_sub->setReminderMailTemplate($rmd_sub->getReminderMailTemplate());
1016 $new_rmd_sub->save();
1022 $ass_type =
$d->getAssignmentType();
1029 return $this->domain->assignment()->instructionFiles($this->
getId())->getFiles();
1038 $set =
$ilDB->query(
1039 "SELECT filename, order_nr, id FROM exc_ass_file_order " .
1040 " WHERE assignment_id = " .
$ilDB->quote($this->getId(),
"integer")
1044 while ($rec =
$ilDB->fetchAssoc($set)) {
1045 $data[$rec[
'filename']] = $rec;
1060 $set =
$ilDB->query(
1061 "SELECT MAX(order_nr) mnr FROM exc_assignment " .
1062 " WHERE exc_id = " .
$ilDB->quote($a_exc_id,
"integer")
1064 if ($rec =
$ilDB->fetchAssoc($set)) {
1065 return (
int) $rec[
"mnr"];
1076 $query =
"SELECT id FROM exc_assignment " .
1077 "WHERE start_time <= " .
$ilDB->quote(time(),
'integer') .
' ' .
1078 "AND time_stamp >= " .
$ilDB->quote(time(),
'integer') .
' ' .
1079 "AND id = " .
$ilDB->quote($a_ass_id,
'integer');
1082 return (
bool)
$res->numRows();
1090 $query =
"SELECT exc_id FROM exc_assignment " .
1091 "WHERE id = " .
$ilDB->quote($a_ass_id,
'integer');
1094 return (
int) (
$res[
"exc_id"] ?? 0);
1097 private static function lookup(
int $a_id,
string $a_field): string
1103 $set =
$ilDB->query(
1104 "SELECT " . $a_field .
" FROM exc_assignment " .
1105 " WHERE id = " .
$ilDB->quote($a_id,
"integer")
1108 $rec =
$ilDB->fetchAssoc($set);
1110 return $rec[$a_field] ??
"";
1115 return self::lookup($a_id,
"title");
1120 return (
int) self::lookup($a_id,
"type");
1132 foreach ($a_order as $k => $v) {
1135 "UPDATE exc_assignment SET " .
1136 " order_nr = " .
$ilDB->quote($nr,
"integer") .
1137 " WHERE id = " .
$ilDB->quote((
int) $k,
"integer") .
1138 " AND exc_id = " .
$ilDB->quote($a_ex_id,
"integer")
1150 $set =
$ilDB->query(
1151 "SELECT id FROM exc_assignment " .
1152 " WHERE exc_id = " .
$ilDB->quote($a_ex_id,
"integer") .
1153 " ORDER BY time_stamp"
1156 while ($rec =
$ilDB->fetchAssoc($set)) {
1158 "UPDATE exc_assignment SET " .
1159 " order_nr = " .
$ilDB->quote($nr,
"integer") .
1160 " WHERE id = " .
$ilDB->quote($rec[
"id"],
"integer")
1173 $set =
$ilDB->query(
1174 "SELECT count(*) cntm FROM exc_assignment " .
1175 " WHERE exc_id = " .
$ilDB->quote($a_ex_id,
"integer") .
1176 " AND mandatory = " .
$ilDB->quote(1,
"integer")
1178 $rec =
$ilDB->fetchAssoc($set);
1179 return (
int) $rec[
"cntm"];
1189 $set =
$ilDB->query(
1190 "SELECT count(*) cntm FROM exc_assignment " .
1191 " WHERE exc_id = " .
$ilDB->quote($a_ex_id,
"integer")
1193 $rec =
$ilDB->fetchAssoc($set);
1194 return $rec[
"cntm"];
1204 $set =
$ilDB->query(
1205 "SELECT * FROM exc_assignment " .
1206 " WHERE exc_id = " .
$ilDB->quote($a_ex_id,
"integer") .
1207 " AND id = " .
$ilDB->quote($a_ass_id,
"integer")
1209 if (
$ilDB->fetchAssoc($set)) {
1222 $set =
$ilDB->query(
"SELECT ud.usr_id, ud.lastname, ud.firstname, ud.login" .
1223 " FROM exc_members excm" .
1224 " JOIN usr_data ud ON (ud.usr_id = excm.usr_id)" .
1225 " WHERE excm.obj_id = " .
$ilDB->quote($this->getExerciseId(),
"integer"));
1226 while ($rec =
$ilDB->fetchAssoc($set)) {
1227 $mem[$rec[
"usr_id"]] =
1229 "name" => $rec[
"lastname"] .
", " . $rec[
"firstname"],
1230 "login" => $rec[
"login"],
1231 "usr_id" => $rec[
"usr_id"],
1232 "lastname" => $rec[
"lastname"],
1233 "firstname" => $rec[
"firstname"]
1239 $idl = $this->getIndividualDeadlines();
1240 if (!$this->ass_type->usesTeams()) {
1247 "name" => $name[
"lastname"] .
", " . $name[
"firstname"],
1248 "login" => $name[
"login"],
1250 "lastname" => $name[
"lastname"],
1251 "firstname" => $name[
"firstname"]
1258 $q =
"SELECT * FROM exc_mem_ass_status " .
1259 "WHERE ass_id = " .
$ilDB->quote($this->
getId(),
"integer");
1261 while ($rec =
$ilDB->fetchAssoc($set)) {
1262 if (isset($mem[$rec[
"usr_id"]])) {
1265 $mem[$rec[
"usr_id"]][
"sent_time"] = $rec[
"sent_time"];
1266 $mem[$rec[
"usr_id"]][
"submission"] = $sub->getLastSubmission();
1267 $mem[$rec[
"usr_id"]][
"status_time"] = $rec[
"status_time"];
1268 $mem[$rec[
"usr_id"]][
"feedback_time"] = $rec[
"feedback_time"];
1269 $mem[$rec[
"usr_id"]][
"notice"] = $rec[
"notice"];
1270 $mem[$rec[
"usr_id"]][
"status"] = $rec[
"status"];
1271 $mem[$rec[
"usr_id"]][
"mark"] = $rec[
"mark"];
1272 $mem[$rec[
"usr_id"]][
"comment"] = $rec[
"u_comment"];
1284 string $a_grade =
""
1290 if (in_array($a_grade, array(
"notgraded",
"passed",
"failed"))) {
1291 $and_grade =
" AND status = " .
$ilDB->quote($a_grade,
"text");
1294 $q =
"SELECT * FROM exc_mem_ass_status " .
1295 "WHERE ass_id = " .
$ilDB->quote($this->
getId(),
"integer") .
1296 " AND usr_id = " .
$ilDB->quote($a_user_id,
"integer") .
1302 while ($rec =
$ilDB->fetchAssoc($set)) {
1305 $data[
"sent_time"] = $rec[
"sent_time"];
1306 $data[
"submission"] = $sub->getLastSubmission();
1307 $data[
"status_time"] = $rec[
"status_time"];
1308 $data[
"feedback_time"] = $rec[
"feedback_time"];
1309 $data[
"notice"] = $rec[
"notice"];
1310 $data[
"status"] = $rec[
"status"];
1311 $data[
"mark"] = $rec[
"mark"];
1312 $data[
"comment"] = $rec[
"u_comment"];
1325 $ass_domain =
$DIC->exercise()->internal()->domain()->assignment();
1327 $ass_data = self::getAssignmentDataOfExercise($a_exc_id);
1328 foreach ($ass_data as $ass) {
1330 $ilDB->replace(
"exc_mem_ass_status", array(
1331 "ass_id" => array(
"integer", $ass[
"id"]),
1332 "usr_id" => array(
"integer", $a_user_id)
1334 "status" => array(
"text",
"notgraded")
1336 if (!$ass_domain->tutorFeedbackFile((
int) $ass[
"id"])->hasCollection($a_user_id)) {
1337 $ass_domain->tutorFeedbackFile((
int) $ass[
"id"])->createCollection($a_user_id);
1350 $ass_domain =
$DIC->exercise()->internal()->domain()->assignment();
1353 $mems = $exmem->getMembers();
1355 foreach ($mems as $mem) {
1356 $ilDB->replace(
"exc_mem_ass_status", array(
1357 "ass_id" => array(
"integer", $a_ass_id),
1358 "usr_id" => array(
"integer", $mem)
1360 "status" => array(
"text",
"notgraded")
1362 if (!$ass_domain->tutorFeedbackFile($a_ass_id)->hasCollection($mem)) {
1363 $ass_domain->tutorFeedbackFile($a_ass_id)->createCollection($mem);
1377 $ilAppEventHandler = $this->app_event_handler;
1379 $dl_id = $this->
getId() .
"0";
1380 $fbdl_id = $this->
getId() .
"1";
1382 $context_ids = array($dl_id, $fbdl_id);
1385 if ($a_event !=
"delete") {
1390 $app->setSubtitle(
"cal_exc_deadline");
1392 $app->setFullday(
false);
1400 if ($this->getPeerReview() &&
1401 $this->getPeerReviewDeadline()) {
1404 $app->setSubtitle(
"cal_exc_peer_review_deadline");
1406 $app->setFullday(
false);
1413 $ilAppEventHandler->raise(
1414 'components/ILIAS/Exercise',
1415 $a_event .
'Assignment',
1418 'obj_id' => $exc->
getId(),
1419 'context_ids' => $context_ids,
1420 'appointments' => $apps)
1429 $log->debug(
"Get feedback notifications.");
1435 $set =
$ilDB->query(
"SELECT id,fb_file,time_stamp,deadline2,fb_date FROM exc_assignment" .
1436 " WHERE fb_cron = " .
$ilDB->quote(1,
"integer") .
1437 " AND (fb_date = " .
$ilDB->quote(self::FEEDBACK_DATE_DEADLINE,
"integer") .
1438 " AND time_stamp IS NOT NULL" .
1439 " AND time_stamp > " .
$ilDB->quote(0,
"integer") .
1440 " AND time_stamp < " .
$ilDB->quote(time(),
"integer") .
1441 " AND fb_cron_done = " .
$ilDB->quote(0,
"integer") .
1442 ") OR (fb_date = " .
$ilDB->quote(self::FEEDBACK_DATE_CUSTOM,
"integer") .
1443 " AND fb_date_custom IS NOT NULL" .
1444 " AND fb_date_custom > " .
$ilDB->quote(0,
"integer") .
1445 " AND fb_date_custom < " .
$ilDB->quote(time(),
"integer") .
1446 " AND fb_cron_done = " .
$ilDB->quote(0,
"integer") .
")");
1450 while ($row =
$ilDB->fetchAssoc($set)) {
1451 $log->debug(
"check assignment " . $row[
'id'] .
", fb_file " . $row[
"fb_file"]);
1452 if ($row[
'fb_date'] == self::FEEDBACK_DATE_DEADLINE) {
1453 $max = max($row[
'time_stamp'], $row[
'deadline2']);
1454 if (trim((
string) $row[
"fb_file"]) && $max <= time()) {
1455 $log->debug(
"...adding(1)");
1456 $res[] = $row[
"id"];
1458 } elseif ($row[
'fb_date'] == self::FEEDBACK_DATE_CUSTOM) {
1459 if (trim($row[
"fb_file"] ??
"") && ($row[
'fb_date_custom'] ?? 0) <= time()) {
1460 $log->debug(
"...adding(2)");
1461 $res[] = $row[
"id"];
1474 ?
int $a_user_id =
null
1479 $gui =
$DIC->exercise()->internal()->gui();
1480 $domain =
$DIC->exercise()->internal()->domain();
1483 $ass =
new self($a_ass_id);
1486 if (!$ass->hasFeedbackCron() || !$ass->getFeedbackFile()) {
1487 $log->debug(
"return(1)");
1493 $set =
$ilDB->query(
"SELECT fb_cron_done" .
1494 " FROM exc_assignment" .
1495 " WHERE id = " .
$ilDB->quote($a_ass_id,
"integer"));
1496 $row =
$ilDB->fetchAssoc($set);
1497 if ($row[
"fb_cron_done"]) {
1498 $log->debug(
"return(2)");
1504 $ntf->setLangModules(array(
"exc"));
1505 $ntf->setObjId($ass->getExerciseId());
1506 $ntf->setSubjectLangId(
"exc_feedback_notification_subject");
1507 $ntf->setIntroductionLangId(
"exc_feedback_notification_body");
1508 $ntf->addAdditionalInfo(
"exc_assignment", $ass->getTitle());
1511 $ref_id = $domain->permission()->getFirstRefIdWithPermission(
1513 $ass->getExerciseId(),
1518 if (count($ref_ids) === 1) {
1523 $perm_link = $gui->permanentLink()->getPermanentLink(
$ref_id, $ass->getId());
1524 $ntf->addAdditionalInfo(
"exc_link_to_assignment", $perm_link);
1527 $ntf->setGotoLangId(
"exc_feedback_notification_link");
1528 $ntf->setReasonLangId(
"exc_feedback_notification_reason");
1534 $ilDB->manipulate(
"UPDATE exc_assignment" .
1535 " SET fb_cron_done = " .
$ilDB->quote(1,
"integer") .
1536 " WHERE id = " .
$ilDB->quote($a_ass_id,
"integer"));
1538 $log->debug(
"send to user: " . $a_user_id);
1539 $ntf->sendMailAndReturnRecipients(array($a_user_id));
1551 $ilUser = $this->user;
1554 $idl = $this->getPersonalDeadline($ilUser->getId());
1557 $deadline = max($this->deadline, $this->deadline2, $idl);
1558 return ($deadline - time() <= 0);
1566 $idl = $a_include_personal
1567 ? $this->getLastPersonalDeadline()
1571 $deadline = max($this->deadline, $this->deadline2, $idl);
1575 if ($idl && $deadline == $idl) {
1576 return ($deadline - time() <= 0);
1580 return ($deadline > 0 &&
1581 $this->afterDeadline());
1589 $date_custom = $this->getFeedbackDateCustom();
1594 return ($date_custom - time() <= 0);
1601 return !$this->afterDeadlineStrict();
1606 return (time() - $this->start_time <= 0);
1619 $rcid = $this->domain->assignment()->sampleSolution(
$ass_id)->importFromLegacyUpload($a_file);
1620 $this->setFeedbackFile($a_file[
"name"]);
1621 return ($rcid !==
"");
1627 $ilUser = $this->user;
1630 $a_user_id = $ilUser->getId();
1632 if (!array_key_exists($a_user_id, $this->member_status)) {
1635 return $this->member_status[$a_user_id];
1647 if (!is_numeric(
$id)) {
1663 $set =
$ilDB->query(
"SELECT * FROM exc_idl" .
1664 " WHERE ass_id = " .
$ilDB->quote($this->getId(),
"integer"));
1665 while ($row =
$ilDB->fetchAssoc($set)) {
1666 if ($row[
"is_team"]) {
1667 $row[
"member_id"] =
"t" . $row[
"member_id"];
1670 $res[$row[
"member_id"]] = $row[
"tstamp"];
1682 $set =
$ilDB->query(
"SELECT * FROM exc_idl" .
1683 " WHERE ass_id = " .
$ilDB->quote($this->getId(),
"integer") .
1684 " AND requested = " .
$ilDB->quote(1,
"integer"));
1685 while ($row =
$ilDB->fetchAssoc($set)) {
1686 if ($row[
"is_team"]) {
1687 $row[
"member_id"] =
"t" . $row[
"member_id"];
1690 $res[$row[
"member_id"]] = $row[
"requested"];
1698 return (
bool) ($this->getDeadline() || $this->getDeadlineMode() === self::DEADLINE_ABSOLUTE_INDIVIDUAL);
1703 if (!$this->ass_type->usesTeams() &&
1704 $this->getPeerReview()) {
1707 if ($peer_review->hasPeerReviewGroups()) {
1721 $db =
$DIC->database();
1723 asort($a_order, SORT_NUMERIC);
1726 foreach (array_keys($a_order) as $k) {
1729 "UPDATE exc_ass_file_order SET " .
1730 " order_nr = " . $db->
quote($nr,
"integer") .
1731 " WHERE id = " . $db->
quote((
int) $k,
"integer") .
1732 " AND assignment_id = " . $db->
quote($a_ass_id,
"integer")
1744 $db =
$DIC->database();
1745 $id = $db->
nextId(
"exc_ass_file_order");
1747 "exc_ass_file_order",
1749 "id" => [
"integer",
$id],
1750 "order_nr" => [
"integer", $a_order_nr],
1751 "assignment_id" => [
"integer", $a_ass_id],
1752 "filename" => [
"text", $a_filename]
1765 $db =
$DIC->database();
1771 if (self::instructionFileExistsInDb(
$filename, $a_ass_id) == 0) {
1772 if ($a_order_nr == 0) {
1773 $order_val = self::instructionFileOrderGetMax($a_ass_id);
1774 $order = $order_val + 10;
1776 $order = $a_order_nr;
1779 $id = $db->nextID(
'exc_ass_file_order');
1780 $db->
manipulate(
"INSERT INTO exc_ass_file_order " .
1781 "(id, assignment_id, filename, order_nr) VALUES (" .
1783 $db->
quote($a_ass_id,
"integer") .
"," .
1785 $db->
quote($order,
"integer") .
1800 $db =
$DIC->database();
1803 foreach ($a_file as $v) {
1805 "DELETE FROM exc_ass_file_order " .
1806 "WHERE filename = " . $db->
quote($v,
'text') .
1807 " AND assignment_id = " . $db->
quote($a_ass_id,
'integer')
1819 $db =
$DIC->database();
1823 "DELETE FROM exc_ass_file_order" .
1824 " WHERE assignment_id = " . $db->
quote($a_ass_id,
'integer') .
1825 " AND filename = " . $db->
quote($a_new_name,
'text')
1829 "UPDATE exc_ass_file_order SET" .
1830 " filename = " . $db->
quote($a_new_name,
'text') .
1831 " WHERE assignment_id = " . $db->
quote($a_ass_id,
'integer') .
1832 " AND filename = " . $db->
quote($a_old_name,
'text')
1843 $db =
$DIC->database();
1846 $result = $db->
query(
1847 "SELECT id FROM exc_ass_file_order" .
1848 " WHERE assignment_id = " . $db->
quote($a_ass_id,
'integer') .
1849 " AND filename = " . $db->
quote($a_filename,
'text')
1862 $files = array_map(
function ($v) {
1864 }, $this->getFiles());
1866 $set = $db->
query(
"SELECT * FROM exc_ass_file_order " .
1867 " WHERE assignment_id = " . $db->
quote($this->getId(),
"integer") .
1868 " ORDER BY order_nr");
1870 $numbered_files = array();
1873 if (in_array($rec[
"filename"], $files)) {
1875 "UPDATE exc_ass_file_order SET " .
1876 " order_nr = " . $db->
quote($order_nr,
"integer") .
1877 " WHERE assignment_id = " . $db->
quote($this->getId(),
"integer") .
1878 " AND id = " . $db->
quote($rec[
"id"],
"integer")
1881 $numbered_files[] = $rec[
"filename"];
1884 "DELETE FROM exc_ass_file_order " .
1885 " WHERE assignment_id = " . $db->
quote($this->getId(),
"integer") .
1886 " AND id = " . $db->
quote($rec[
"id"],
"integer")
1890 foreach ($files as
$f) {
1891 if (!in_array(
$f, $numbered_files)) {
1892 self::instructionFileInsertOrder(
$f, $this->
getId());
1898 array $a_entries = array()
1900 $this->fixInstructionFileOrdering();
1902 $order = $this->getInstructionFilesOrder();
1903 foreach ($a_entries as $k =>
$e) {
1904 $a_entries[$k][
"order_val"] = $order[
$e[
"file"]][
"order_nr"] ?? 0;
1905 $a_entries[$k][
"order_id"] = $order[
$e[
"file"]][
"id"] ??
"";
1915 $db =
$DIC->database();
1919 "SELECT max(order_nr) as max_order FROM exc_ass_file_order WHERE assignment_id = %s",
1921 array($db->
quote($a_ass_id,
'integer'))
1926 $order_val = (
int) $row[
'max_order'];
1935 $this->min_char_limit = $a_val;
1940 return $this->min_char_limit;
1946 $this->max_char_limit = $a_val;
1951 return $this->max_char_limit;
1964 $calculated_deadlines = array(
1969 if ($this->getRelativeDeadline() && $this->getDeadlineMode() == self::DEADLINE_RELATIVE) {
1971 $type = $ts[
"is_team"]
1975 $calculated_deadlines[$type][$ts[
"member_id"]] = array(
1976 "calculated_deadline" => $ts[
"starting_ts"] + ($this->getRelativeDeadline() * 24 * 60 * 60)
1980 return $calculated_deadlines;
1986 if ($this->hasTeam()) {
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Indicates that the directory is missing or not found.
Indicates that a file is missing or not found.
Indicates general problems with the input or output operations.
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Class ResourceCollectionIdentification.
Class ResourceIdentification.
This exception indicates that an UI component was accepted by the JF but is not backed by a real impl...
Apointment templates are used for automatic generated apointments.
@classDescription Date and time handling
get(int $a_format, string $a_format_str='', string $a_tz='')
get formatted date
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getTeamId(int $a_assignment_id, int $a_user_id, bool $a_create_on_demand=false)
ILIAS Refinery String Group $string_transform
static getAssignmentDataOfExercise(int $a_exc_id)
static lookupExerciseId(int $a_ass_id)
ilAppEventHandler $app_event_handler
setTeamTutor(bool $a_value)
static lookupMaxOrderNrForEx(int $a_exc_id)
ilExAssignmentTypes $types
hasPeerReviewPersonalized()
static saveInstructionFilesOrderOfAssignment(int $a_ass_id, array $a_order)
static lookup(int $a_id, string $a_field)
getLastPersonalDeadline()
static saveAssOrderOfExercise(int $a_ex_id, array $a_order)
setPeerReviewSimpleUnlock(int $a_value)
setRelativeDeadline(int $a_val)
setPeerReviewMin(int $a_value)
ilExAssignmentTypeInterface $ass_type
static instructionFileOrderGetMax(int $a_ass_id)
fixInstructionFileOrdering()
static instructionFileGetFileOrderData(array $a_file_data, int $a_ass_id)
static count(int $a_ex_id)
static lookupType(int $a_id)
const TEAMS_FORMED_BY_TUTOR
setExtendedDeadline(?int $a_val)
static cloneAssignmentsOfExercise(int $a_old_exc_id, int $a_new_exc_id, array $a_crit_cat_map)
Clone assignments of exercise.
setPeerReviewText(bool $a_val)
setPeerReviewCriteriaCatalogue(?int $a_value)
static countMandatory(int $a_ex_id)
setPeerReview(bool $a_value)
isValidType(int $a_value)
getInstructionFilesOrder()
const PEER_REVIEW_VALID_NONE
static instructionFileDeleteOrder(int $a_ass_id, array $a_file)
getType()
Get type this will most probably become an non public function in the future (or become obsolete)
const TEAMS_FORMED_BY_PARTICIPANTS
static isInExercise(int $a_ass_id, int $a_ex_id)
handleCalendarEntries(string $a_event, ilObjExercise $exc)
Handle calendar entries for deadline(s)
getInstructionPresentation()
const PEER_REVIEW_VALID_ALL
setMinCharLimit(int $a_val)
static insertFileOrderNr(int $a_ass_id, string $a_filename, int $a_order_nr)
setStartTime(?int $a_val)
setDeadlineMode(int $a_val)
Set deadline mode.
setFeedbackCron(bool $a_value)
Toggle (global) feedback file cron.
getCalculatedDeadlines()
Get calculated deadlines for user/team members.
static renameInstructionFile(string $a_old_name, string $a_new_name, int $a_ass_id)
setPeerReviewValid(int $a_value)
Set peer review validation.
static instructionFileInsertOrder(string $a_filename, int $a_ass_id, int $a_order_nr=0)
getRelDeadlineLastSubmission()
static getInstancesByExercise(int $a_exc_id)
setPeerReviewPersonalized(bool $a_val)
static createNewUserRecords(int $a_user_id, int $a_exc_id)
int $feedback_date_custom
const TEAMS_FORMED_BY_RANDOM
getExerciseMemberAssignmentData(int $a_user_id, string $a_grade="")
Get submission data for an specific user,exercise and assignment.
static getPendingFeedbackNotifications()
initFromDB(array $a_set)
Import DB record.
__construct($a_id=0)
Constructor.
hasPeerReviewFileUpload()
int $rel_deadline_last_subm
setInstruction(string $a_val)
setPortfolioTemplateId(int $a_val)
static sendFeedbackNotifications(int $a_ass_id, ?int $a_user_id=null)
getPeerReviewSimpleUnlock()
const TYPE_UPLOAD
direct checks against const should be avoided, use type objects instead
const FEEDBACK_DATE_CUSTOM
static createNewAssignmentRecords(int $a_ass_id, ilObjExercise $a_exc)
const TEAMS_FORMED_BY_ASSIGNMENT
getPersonalDeadline(int $a_user_id)
const FEEDBACK_DATE_DEADLINE
handleGlobalFeedbackFileUpload(int $ass_id, array $a_file)
setRelDeadlineLastSubmission(int $a_val)
ILIAS Exercise InternalDomainService $domain
getMemberStatus(?int $a_user_id=null)
setFeedbackFile(?string $a_value)
const PEER_REVIEW_VALID_ONE
ILIAS Exercise InternalGUIService $gui
setPeerReviewChars(?int $a_value)
setPeerReviewRating(bool $a_val)
getPeerReviewCriteriaCatalogue()
setType(int $a_value)
Set type this will most probably become an non public function in the future (or become obsolete)
static orderAssByDeadline(int $a_ex_id)
setPeerReviewDeadline(int $a_val)
const FEEDBACK_DATE_SUBMISSION
fileAddOrder(array $a_entries=array())
setFeedbackDateCustom(int $a_value)
Set (global) feedback file availability using a custom date.
setFeedbackDate(int $a_value)
setIndividualDeadline(string $id, ilDateTime $date)
canParticipantReceiveFeedback(int $part_id)
setMaxFile(?int $a_value)
static lookupAssignmentOnline(int $a_ass_id)
setMandatory(bool $a_val)
setMaxCharLimit(int $a_val)
setPeerReviewFileUpload(bool $a_val)
static instructionFileExistsInDb(string $a_filename, int $a_ass_id)
const DEADLINE_ABSOLUTE_INDIVIDUAL
static lookupTitle(int $a_id)
setExerciseId(int $a_val)
afterDeadlineStrict(bool $a_include_personal=true)
Exercise submission //TODO: This class has many static methods related to delivered "files".
static getInstancesByParentId(int $a_parent_id)
static getInstanceByType(string $a_type)
static getStartingTimestamps(int $a_ass_id)
Get starting timestamp data for an assignment.
static deleteForAssignment(int $ass_id)
static getInstance(int $a_ass_id, int $a_participant_id, bool $a_is_team=false)
static _getMembers(int $a_obj_id)
static getSafeFilename(string $a_initial_filename)
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
updateAllUsersStatus()
Update status of all users.
static _lookupName(int $a_user_id)
static raiseContentChanged(int $obj_id)
static _getAllReferences(int $id)
get all reference ids for object ID
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface ResourceStakeholder.
Interface ilAccessHandler This interface combines all available interfaces which can be called via gl...
insert(string $table_name, array $values)
nextId(string $table_name)
setLimit(int $limit, int $offset=0)
numRows(ilDBStatement $statement)
quote($value, string $type)
manipulate(string $query)
Run a (write) Query on the database.
query(string $query)
Run a (read-only) Query on the database.
fetchAssoc(ilDBStatement $statement)
queryF(string $query, array $types, array $values)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
cloneSpecificProperties(ilExAssignment $source, ilExAssignment $target)