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())
765 $this->setId($next_id);
767 $exc->updateAllUsersStatus();
769 $this->domain->assignment()->instructionFiles($next_id)->createCollection();
771 self::createNewAssignmentRecords($next_id, $exc);
773 $this->handleCalendarEntries(
"create", $exc);
786 "exc_id" => array(
"integer", $this->getExerciseId()),
787 "time_stamp" => array(
"integer", $this->getDeadline()),
788 "deadline2" => array(
"integer", $this->getExtendedDeadline()),
789 "instruction" => array(
"clob", $this->getInstruction()),
790 "title" => array(
"text", $this->
getTitle()),
791 "start_time" => array(
"integer", $this->getStartTime()),
792 "order_nr" => array(
"integer", $this->getOrderNr()),
793 "mandatory" => array(
"integer", $this->getMandatory()),
794 "type" => array(
"integer", $this->getType()),
795 "peer" => array(
"integer", $this->getPeerReview()),
796 "peer_min" => array(
"integer", $this->getPeerReviewMin()),
797 "peer_unlock" => array(
"integer", $this->getPeerReviewSimpleUnlock()),
798 "peer_dl" => array(
"integer", $this->getPeerReviewDeadline()),
799 "peer_valid" => array(
"integer", $this->getPeerReviewValid()),
800 "peer_file" => array(
"integer", $this->hasPeerReviewFileUpload()),
801 "peer_prsl" => array(
"integer", $this->hasPeerReviewPersonalized()),
802 "peer_char" => array(
"integer", $this->getPeerReviewChars()),
803 "peer_text" => array(
"integer", (
int) $this->hasPeerReviewText()),
804 "peer_rating" => array(
"integer", (
int) $this->hasPeerReviewRating()),
805 "peer_crit_cat" => array(
"integer", $this->getPeerReviewCriteriaCatalogue()),
806 "fb_file" => array(
"text", $this->getFeedbackFile()),
807 "fb_date" => array(
"integer", $this->getFeedbackDate()),
808 "fb_date_custom" => array(
"integer", $this->getFeedbackDateCustom()),
809 "fb_cron" => array(
"integer", $this->hasFeedbackCron()),
810 "team_tutor" => array(
"integer", $this->getTeamTutor()),
811 "max_file" => array(
"integer", $this->getMaxFile()),
812 "portfolio_template" => array(
"integer", $this->getPortfolioTemplateId()),
813 "min_char_limit" => array(
"integer", $this->getMinCharLimit()),
814 "max_char_limit" => array(
"integer", $this->getMaxCharLimit()),
815 "deadline_mode" => array(
"integer", $this->getDeadlineMode()),
816 "relative_deadline" => array(
"integer", $this->getRelativeDeadline()),
817 "rel_deadline_last_subm" => array(
"integer", $this->getRelDeadlineLastSubmission())
820 "id" => array(
"integer", $this->
getId()),
824 $exc->updateAllUsersStatus();
826 $this->handleCalendarEntries(
"update", $exc);
832 public function delete(
834 bool $update_user_status =
true
840 foreach ($exc_members->getMembers() as $mem) {
842 $submission->deleteAllFiles();
846 "DELETE FROM exc_usr_tutor " .
849 array($this->
getId())
853 if ($this->getPeerReview()) {
855 $peer_review->resetPeerReviews();
859 "DELETE FROM exc_ass_file_order" .
860 " WHERE assignment_id = " .
$ilDB->quote($this->getId(),
'integer')
864 "DELETE FROM exc_mem_ass_status" .
865 " WHERE ass_id = " .
$ilDB->quote($this->getId(),
'integer')
869 "DELETE FROM exc_assignment WHERE " .
870 " id = " .
$ilDB->quote($this->getId(),
"integer")
873 if ($update_user_status) {
877 $this->handleCalendarEntries(
"delete", $exc);
882 $reminder->deleteReminders($this->
getId());
885 $this->domain->team()->deleteTeamsOfAssignment($this->
getId());
888 $this->domain->assignment()->instructionFiles($this->
getId())
889 ->deleteCollection();
902 $set =
$ilDB->query(
"SELECT * FROM exc_assignment " .
903 " WHERE exc_id = " .
$ilDB->quote($a_exc_id,
"integer") .
904 " ORDER BY order_nr");
908 while ($rec =
$ilDB->fetchAssoc($set)) {
910 "id" => (
int) $rec[
"id"],
911 "exc_id" => (
int) $rec[
"exc_id"],
912 "deadline" => (
int) $rec[
"time_stamp"],
913 "deadline2" => (
int) $rec[
"deadline2"],
914 "instruction" => (
string) $rec[
"instruction"],
915 "title" => (
string) $rec[
"title"],
916 "start_time" => (
int) $rec[
"start_time"],
917 "order_val" => $order_val,
918 "mandatory" => (
bool) $rec[
"mandatory"],
919 "type" => (
int) $rec[
"type"],
920 "peer" => (
bool) $rec[
"peer"],
921 "peer_min" => (
int) $rec[
"peer_min"],
922 "peer_dl" => (
int) $rec[
"peer_dl"],
923 "peer_file" => (
bool) $rec[
"peer_file"],
924 "peer_prsl" => (
bool) $rec[
"peer_prsl"],
925 "fb_file" => (
string) $rec[
"fb_file"],
926 "fb_date" => (
int) $rec[
"fb_date"],
927 "fb_cron" => (
bool) $rec[
"fb_cron"],
928 "deadline_mode" => (
int) $rec[
"deadline_mode"],
929 "relative_deadline" => (
int) $rec[
"relative_deadline"],
930 "rel_deadline_last_subm" => (
int) $rec[
"rel_deadline_last_subm"]
947 array $a_crit_cat_map
951 $ass_domain =
$DIC->exercise()->internal()->domain()->assignment();
952 $ass_data = self::getInstancesByExercise($a_old_exc_id);
953 foreach ($ass_data as
$d) {
956 $new_ass->setExerciseId($a_new_exc_id);
957 $new_ass->setTitle(
$d->getTitle());
958 $new_ass->setDeadline(
$d->getDeadline());
959 $new_ass->setExtendedDeadline(
$d->getExtendedDeadline());
960 $new_ass->setInstruction(
$d->getInstruction());
961 $new_ass->setMandatory(
$d->getMandatory());
962 $new_ass->setOrderNr(
$d->getOrderNr());
963 $new_ass->setStartTime(
$d->getStartTime());
964 $new_ass->setType(
$d->getType());
965 $new_ass->setPeerReview(
$d->getPeerReview());
966 $new_ass->setPeerReviewMin(
$d->getPeerReviewMin());
967 $new_ass->setPeerReviewDeadline(
$d->getPeerReviewDeadline());
968 $new_ass->setPeerReviewFileUpload(
$d->hasPeerReviewFileUpload());
969 $new_ass->setPeerReviewPersonalized(
$d->hasPeerReviewPersonalized());
970 $new_ass->setPeerReviewValid(
$d->getPeerReviewValid());
971 $new_ass->setPeerReviewChars(
$d->getPeerReviewChars());
972 $new_ass->setPeerReviewText(
$d->hasPeerReviewText());
973 $new_ass->setPeerReviewRating(
$d->hasPeerReviewRating());
974 $new_ass->setPeerReviewCriteriaCatalogue(
$d->getPeerReviewCriteriaCatalogue());
975 $new_ass->setPeerReviewSimpleUnlock(
$d->getPeerReviewSimpleUnlock());
976 $new_ass->setFeedbackFile(
$d->getFeedbackFile());
977 $new_ass->setFeedbackDate(
$d->getFeedbackDate());
978 $new_ass->setFeedbackDateCustom(
$d->getFeedbackDateCustom());
979 $new_ass->setFeedbackCron(
$d->hasFeedbackCron());
980 $new_ass->setTeamTutor(
$d->getTeamTutor());
981 $new_ass->setMaxFile(
$d->getMaxFile());
982 $new_ass->setMinCharLimit(
$d->getMinCharLimit());
983 $new_ass->setMaxCharLimit(
$d->getMaxCharLimit());
984 $new_ass->setPortfolioTemplateId(
$d->getPortfolioTemplateId());
985 $new_ass->setDeadlineMode(
$d->getDeadlineMode());
986 $new_ass->setRelativeDeadline(
$d->getRelativeDeadline());
987 $new_ass->setRelDeadlineLastSubmission(
$d->getRelDeadlineLastSubmission());
990 if (
$d->getPeerReviewCriteriaCatalogue() &&
991 array_key_exists(
$d->getPeerReviewCriteriaCatalogue(), $a_crit_cat_map)) {
992 $new_ass->setPeerReviewCriteriaCatalogue($a_crit_cat_map[
$d->getPeerReviewCriteriaCatalogue()]);
998 $ass_domain->instructionFiles(
$d->getId())->cloneTo($new_ass->getId());
1001 $ass_domain->sampleSolution(
$d->getId())->cloneTo($new_ass->getId());
1008 if ($rmd_sub->getReminderStatus()) {
1010 $new_rmd_sub->setReminderStatus($rmd_sub->getReminderStatus());
1011 $new_rmd_sub->setReminderStart($rmd_sub->getReminderStart());
1012 $new_rmd_sub->setReminderEnd($rmd_sub->getReminderEnd());
1013 $new_rmd_sub->setReminderFrequency($rmd_sub->getReminderFrequency());
1014 $new_rmd_sub->setReminderMailTemplate($rmd_sub->getReminderMailTemplate());
1015 $new_rmd_sub->save();
1021 $ass_type =
$d->getAssignmentType();
1028 return $this->domain->assignment()->instructionFiles($this->
getId())->getFiles();
1037 $set =
$ilDB->query(
1038 "SELECT filename, order_nr, id FROM exc_ass_file_order " .
1039 " WHERE assignment_id = " .
$ilDB->quote($this->getId(),
"integer")
1043 while ($rec =
$ilDB->fetchAssoc($set)) {
1044 $data[$rec[
'filename']] = $rec;
1059 $set =
$ilDB->query(
1060 "SELECT MAX(order_nr) mnr FROM exc_assignment " .
1061 " WHERE exc_id = " .
$ilDB->quote($a_exc_id,
"integer")
1063 if ($rec =
$ilDB->fetchAssoc($set)) {
1064 return (
int) $rec[
"mnr"];
1075 $query =
"SELECT id FROM exc_assignment " .
1076 "WHERE start_time <= " .
$ilDB->quote(time(),
'integer') .
' ' .
1077 "AND time_stamp >= " .
$ilDB->quote(time(),
'integer') .
' ' .
1078 "AND id = " .
$ilDB->quote($a_ass_id,
'integer');
1081 return (
bool)
$res->numRows();
1089 $query =
"SELECT exc_id FROM exc_assignment " .
1090 "WHERE id = " .
$ilDB->quote($a_ass_id,
'integer');
1093 return (
int) (
$res[
"exc_id"] ?? 0);
1096 private static function lookup(
int $a_id,
string $a_field): string
1102 $set =
$ilDB->query(
1103 "SELECT " . $a_field .
" FROM exc_assignment " .
1104 " WHERE id = " .
$ilDB->quote($a_id,
"integer")
1107 $rec =
$ilDB->fetchAssoc($set);
1109 return $rec[$a_field] ??
"";
1114 return self::lookup($a_id,
"title");
1119 return (
int) self::lookup($a_id,
"type");
1131 foreach ($a_order as $k => $v) {
1134 "UPDATE exc_assignment SET " .
1135 " order_nr = " .
$ilDB->quote($nr,
"integer") .
1136 " WHERE id = " .
$ilDB->quote((
int) $k,
"integer") .
1137 " AND exc_id = " .
$ilDB->quote($a_ex_id,
"integer")
1149 $set =
$ilDB->query(
1150 "SELECT id FROM exc_assignment " .
1151 " WHERE exc_id = " .
$ilDB->quote($a_ex_id,
"integer") .
1152 " ORDER BY time_stamp"
1155 while ($rec =
$ilDB->fetchAssoc($set)) {
1157 "UPDATE exc_assignment SET " .
1158 " order_nr = " .
$ilDB->quote($nr,
"integer") .
1159 " WHERE id = " .
$ilDB->quote($rec[
"id"],
"integer")
1172 $set =
$ilDB->query(
1173 "SELECT count(*) cntm FROM exc_assignment " .
1174 " WHERE exc_id = " .
$ilDB->quote($a_ex_id,
"integer") .
1175 " AND mandatory = " .
$ilDB->quote(1,
"integer")
1177 $rec =
$ilDB->fetchAssoc($set);
1178 return (
int) $rec[
"cntm"];
1188 $set =
$ilDB->query(
1189 "SELECT count(*) cntm FROM exc_assignment " .
1190 " WHERE exc_id = " .
$ilDB->quote($a_ex_id,
"integer")
1192 $rec =
$ilDB->fetchAssoc($set);
1193 return $rec[
"cntm"];
1203 $set =
$ilDB->query(
1204 "SELECT * FROM exc_assignment " .
1205 " WHERE exc_id = " .
$ilDB->quote($a_ex_id,
"integer") .
1206 " AND id = " .
$ilDB->quote($a_ass_id,
"integer")
1208 if (
$ilDB->fetchAssoc($set)) {
1221 $set =
$ilDB->query(
"SELECT ud.usr_id, ud.lastname, ud.firstname, ud.login" .
1222 " FROM exc_members excm" .
1223 " JOIN usr_data ud ON (ud.usr_id = excm.usr_id)" .
1224 " WHERE excm.obj_id = " .
$ilDB->quote($this->getExerciseId(),
"integer"));
1225 while ($rec =
$ilDB->fetchAssoc($set)) {
1226 $mem[$rec[
"usr_id"]] =
1228 "name" => $rec[
"lastname"] .
", " . $rec[
"firstname"],
1229 "login" => $rec[
"login"],
1230 "usr_id" => $rec[
"usr_id"],
1231 "lastname" => $rec[
"lastname"],
1232 "firstname" => $rec[
"firstname"]
1238 $idl = $this->getIndividualDeadlines();
1239 if (!$this->ass_type->usesTeams()) {
1246 "name" => $name[
"lastname"] .
", " . $name[
"firstname"],
1247 "login" => $name[
"login"],
1249 "lastname" => $name[
"lastname"],
1250 "firstname" => $name[
"firstname"]
1257 $q =
"SELECT * FROM exc_mem_ass_status " .
1258 "WHERE ass_id = " .
$ilDB->quote($this->
getId(),
"integer");
1260 while ($rec =
$ilDB->fetchAssoc($set)) {
1261 if (isset($mem[$rec[
"usr_id"]])) {
1264 $mem[$rec[
"usr_id"]][
"sent_time"] = $rec[
"sent_time"];
1265 $mem[$rec[
"usr_id"]][
"submission"] = $sub->getLastSubmission();
1266 $mem[$rec[
"usr_id"]][
"status_time"] = $rec[
"status_time"];
1267 $mem[$rec[
"usr_id"]][
"feedback_time"] = $rec[
"feedback_time"];
1268 $mem[$rec[
"usr_id"]][
"notice"] = $rec[
"notice"];
1269 $mem[$rec[
"usr_id"]][
"status"] = $rec[
"status"];
1270 $mem[$rec[
"usr_id"]][
"mark"] = $rec[
"mark"];
1271 $mem[$rec[
"usr_id"]][
"comment"] = $rec[
"u_comment"];
1283 string $a_grade =
""
1289 if (in_array($a_grade, array(
"notgraded",
"passed",
"failed"))) {
1290 $and_grade =
" AND status = " .
$ilDB->quote($a_grade,
"text");
1293 $q =
"SELECT * FROM exc_mem_ass_status " .
1294 "WHERE ass_id = " .
$ilDB->quote($this->
getId(),
"integer") .
1295 " AND usr_id = " .
$ilDB->quote($a_user_id,
"integer") .
1301 while ($rec =
$ilDB->fetchAssoc($set)) {
1304 $data[
"sent_time"] = $rec[
"sent_time"];
1305 $data[
"submission"] = $sub->getLastSubmission();
1306 $data[
"status_time"] = $rec[
"status_time"];
1307 $data[
"feedback_time"] = $rec[
"feedback_time"];
1308 $data[
"notice"] = $rec[
"notice"];
1309 $data[
"status"] = $rec[
"status"];
1310 $data[
"mark"] = $rec[
"mark"];
1311 $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($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
1481 $ass =
new self($a_ass_id);
1484 if (!$ass->hasFeedbackCron() || !$ass->getFeedbackFile()) {
1485 $log->debug(
"return(1)");
1491 $set =
$ilDB->query(
"SELECT fb_cron_done" .
1492 " FROM exc_assignment" .
1493 " WHERE id = " .
$ilDB->quote($a_ass_id,
"integer"));
1494 $row =
$ilDB->fetchAssoc($set);
1495 if ($row[
"fb_cron_done"]) {
1496 $log->debug(
"return(2)");
1502 $ntf->setLangModules(array(
"exc"));
1503 $ntf->setObjId($ass->getExerciseId());
1504 $ntf->setSubjectLangId(
"exc_feedback_notification_subject");
1505 $ntf->setIntroductionLangId(
"exc_feedback_notification_body");
1506 $ntf->addAdditionalInfo(
"exc_assignment", $ass->getTitle());
1507 $ntf->setGotoLangId(
"exc_feedback_notification_link");
1508 $ntf->setReasonLangId(
"exc_feedback_notification_reason");
1514 $ilDB->manipulate(
"UPDATE exc_assignment" .
1515 " SET fb_cron_done = " .
$ilDB->quote(1,
"integer") .
1516 " WHERE id = " .
$ilDB->quote($a_ass_id,
"integer"));
1518 $log->debug(
"send to user: " . $a_user_id);
1519 $ntf->sendMailAndReturnRecipients(array($a_user_id));
1531 $ilUser = $this->user;
1534 $idl = $this->getPersonalDeadline($ilUser->getId());
1537 $deadline = max($this->deadline, $this->deadline2, $idl);
1538 return ($deadline - time() <= 0);
1546 $idl = $a_include_personal
1547 ? $this->getLastPersonalDeadline()
1551 $deadline = max($this->deadline, $this->deadline2, $idl);
1555 if ($idl && $deadline == $idl) {
1556 return ($deadline - time() <= 0);
1560 return ($deadline > 0 &&
1561 $this->afterDeadline());
1569 $date_custom = $this->getFeedbackDateCustom();
1574 return ($date_custom - time() <= 0);
1581 return !$this->afterDeadlineStrict();
1586 return (time() - $this->start_time <= 0);
1599 $rcid = $this->domain->assignment()->sampleSolution(
$ass_id)->importFromLegacyUpload($a_file);
1600 $this->setFeedbackFile($a_file[
"name"]);
1601 return ($rcid !==
"");
1607 $ilUser = $this->user;
1610 $a_user_id = $ilUser->getId();
1612 if (!array_key_exists($a_user_id, $this->member_status)) {
1615 return $this->member_status[$a_user_id];
1627 if (!is_numeric(
$id)) {
1643 $set =
$ilDB->query(
"SELECT * FROM exc_idl" .
1644 " WHERE ass_id = " .
$ilDB->quote($this->getId(),
"integer"));
1645 while ($row =
$ilDB->fetchAssoc($set)) {
1646 if ($row[
"is_team"]) {
1647 $row[
"member_id"] =
"t" . $row[
"member_id"];
1650 $res[$row[
"member_id"]] = $row[
"tstamp"];
1662 $set =
$ilDB->query(
"SELECT * FROM exc_idl" .
1663 " WHERE ass_id = " .
$ilDB->quote($this->getId(),
"integer") .
1664 " AND requested = " .
$ilDB->quote(1,
"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[
"requested"];
1678 return (
bool) ($this->getDeadline() || $this->getDeadlineMode() === self::DEADLINE_ABSOLUTE_INDIVIDUAL);
1683 if (!$this->ass_type->usesTeams() &&
1684 $this->getPeerReview()) {
1687 if ($peer_review->hasPeerReviewGroups()) {
1701 $db =
$DIC->database();
1703 asort($a_order, SORT_NUMERIC);
1706 foreach (array_keys($a_order) as $k) {
1709 "UPDATE exc_ass_file_order SET " .
1710 " order_nr = " . $db->
quote($nr,
"integer") .
1711 " WHERE id = " . $db->
quote((
int) $k,
"integer") .
1712 " AND assignment_id = " . $db->
quote($a_ass_id,
"integer")
1724 $db =
$DIC->database();
1725 $id = $db->
nextId(
"exc_ass_file_order");
1727 "exc_ass_file_order",
1729 "id" => [
"integer",
$id],
1730 "order_nr" => [
"integer", $a_order_nr],
1731 "assignment_id" => [
"integer", $a_ass_id],
1732 "filename" => [
"text", $a_filename]
1745 $db =
$DIC->database();
1751 if (self::instructionFileExistsInDb(
$filename, $a_ass_id) == 0) {
1752 if ($a_order_nr == 0) {
1753 $order_val = self::instructionFileOrderGetMax($a_ass_id);
1754 $order = $order_val + 10;
1756 $order = $a_order_nr;
1759 $id = $db->nextID(
'exc_ass_file_order');
1760 $db->
manipulate(
"INSERT INTO exc_ass_file_order " .
1761 "(id, assignment_id, filename, order_nr) VALUES (" .
1763 $db->
quote($a_ass_id,
"integer") .
"," .
1765 $db->
quote($order,
"integer") .
1780 $db =
$DIC->database();
1783 foreach ($a_file as $v) {
1785 "DELETE FROM exc_ass_file_order " .
1786 "WHERE filename = " . $db->
quote($v,
'text') .
1787 " AND assignment_id = " . $db->
quote($a_ass_id,
'integer')
1799 $db =
$DIC->database();
1803 "DELETE FROM exc_ass_file_order" .
1804 " WHERE assignment_id = " . $db->
quote($a_ass_id,
'integer') .
1805 " AND filename = " . $db->
quote($a_new_name,
'text')
1809 "UPDATE exc_ass_file_order SET" .
1810 " filename = " . $db->
quote($a_new_name,
'text') .
1811 " WHERE assignment_id = " . $db->
quote($a_ass_id,
'integer') .
1812 " AND filename = " . $db->
quote($a_old_name,
'text')
1823 $db =
$DIC->database();
1826 $result = $db->
query(
1827 "SELECT id FROM exc_ass_file_order" .
1828 " WHERE assignment_id = " . $db->
quote($a_ass_id,
'integer') .
1829 " AND filename = " . $db->
quote($a_filename,
'text')
1842 $files = array_map(
function ($v) {
1844 }, $this->getFiles());
1846 $set = $db->
query(
"SELECT * FROM exc_ass_file_order " .
1847 " WHERE assignment_id = " . $db->
quote($this->getId(),
"integer") .
1848 " ORDER BY order_nr");
1850 $numbered_files = array();
1853 if (in_array($rec[
"filename"], $files)) {
1855 "UPDATE exc_ass_file_order SET " .
1856 " order_nr = " . $db->
quote($order_nr,
"integer") .
1857 " WHERE assignment_id = " . $db->
quote($this->getId(),
"integer") .
1858 " AND id = " . $db->
quote($rec[
"id"],
"integer")
1861 $numbered_files[] = $rec[
"filename"];
1864 "DELETE FROM exc_ass_file_order " .
1865 " WHERE assignment_id = " . $db->
quote($this->getId(),
"integer") .
1866 " AND id = " . $db->
quote($rec[
"id"],
"integer")
1870 foreach ($files as
$f) {
1871 if (!in_array(
$f, $numbered_files)) {
1872 self::instructionFileInsertOrder(
$f, $this->
getId());
1878 array $a_entries = array()
1880 $this->fixInstructionFileOrdering();
1882 $order = $this->getInstructionFilesOrder();
1883 foreach ($a_entries as $k =>
$e) {
1884 $a_entries[$k][
"order_val"] = $order[
$e[
"file"]][
"order_nr"] ?? 0;
1885 $a_entries[$k][
"order_id"] = $order[
$e[
"file"]][
"id"] ??
"";
1895 $db =
$DIC->database();
1899 "SELECT max(order_nr) as max_order FROM exc_ass_file_order WHERE assignment_id = %s",
1901 array($db->
quote($a_ass_id,
'integer'))
1906 $order_val = (
int) $row[
'max_order'];
1915 $this->min_char_limit = $a_val;
1920 return $this->min_char_limit;
1926 $this->max_char_limit = $a_val;
1931 return $this->max_char_limit;
1944 $calculated_deadlines = array(
1949 if ($this->getRelativeDeadline() && $this->getDeadlineMode() == self::DEADLINE_RELATIVE) {
1951 $type = $ts[
"is_team"]
1955 $calculated_deadlines[$type][$ts[
"member_id"]] = array(
1956 "calculated_deadline" => $ts[
"starting_ts"] + ($this->getRelativeDeadline() * 24 * 60 * 60)
1960 return $calculated_deadlines;
1966 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 _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)