19declare(strict_types=1);
76 $this->user_data_fields = array_merge(
99 self::ASSIGNMENT_FIELD_ID => $this->
nextId(),
100 self::ASSIGNMENT_FIELD_USR_ID => $usr_id,
101 self::ASSIGNMENT_FIELD_ROOT_PRG_ID => $prg_obj_id,
102 self::ASSIGNMENT_FIELD_LAST_CHANGE_BY => $assigning_usr_id,
103 self::ASSIGNMENT_FIELD_LAST_CHANGE =>
ilUtil::now(),
104 self::ASSIGNMENT_FIELD_RESTART_DATE =>
null,
106 self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED => $manually
109 $this->progresses = [];
112 $this->user_data_fields,
113 static fn($field) => !str_starts_with($field,
'udf_') && $field !==
'org_units'
116 .
'FROM usr_data WHERE usr_id = ' . $this->db->quote($usr_id,
'integer');
117 $res = $this->db->query($query);
118 $row = array_merge($row, $this->db->fetchAssoc(
$res));
127 self::ASSIGNMENT_FIELD_ID => $assignment->
getId(),
128 self::ASSIGNMENT_FIELD_USR_ID => $assignment->
getUserId(),
129 self::ASSIGNMENT_FIELD_ROOT_PRG_ID => $assignment->
getRootId(),
130 self::ASSIGNMENT_FIELD_LAST_CHANGE_BY => $assignment->
getLastChangeBy(),
136 $this->updateAssignmentRowDB($row);
138 $this->storeProgressRow(
139 $assignment->
getId(),
145 $this->events->raiseCollected();
150 $ass_id = $assignment->getId();
151 $query =
'DELETE FROM ' . self::ASSIGNMENT_TABLE . PHP_EOL
152 .
'WHERE ' . self::ASSIGNMENT_FIELD_ID .
' = ' .
$ass_id;
153 $this->db->manipulate($query);
155 $query =
'DELETE FROM ' . self::PROGRESS_TABLE . PHP_EOL
156 .
'WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID .
' = ' .
$ass_id;
157 $this->db->manipulate($query);
162 $query =
'DELETE FROM ' . self::ASSIGNMENT_TABLE . PHP_EOL
163 .
'WHERE ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID .
'=' . $this->db->quote($prg_obj_id,
'integer');
164 $this->db->manipulate($query);
165 $this->deleteAllOrphanedProgresses();
169 $query =
'DELETE FROM ' . self::PROGRESS_TABLE . PHP_EOL
170 .
'WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID . PHP_EOL
171 .
'NOT IN (' . PHP_EOL
172 .
'SELECT ' . $this->db->quoteIdentifier(self::ASSIGNMENT_FIELD_ID)
173 .
' FROM ' . $this->db->quoteIdentifier(self::ASSIGNMENT_TABLE) . PHP_EOL
175 $this->db->manipulate($query);
181 'ass.' . self::ASSIGNMENT_FIELD_ID .
' = ' . $this->db->quote(
$id,
'integer')
184 return $ass->current();
189 $assignments = array_filter(iterator_to_array(
191 'ass.' . self::ASSIGNMENT_FIELD_USR_ID .
' = ' . $this->db->quote($usr_id,
'integer')
199 $assignments = array_filter(iterator_to_array(
201 'ass.' . self::ASSIGNMENT_FIELD_USR_ID .
' = ' . $this->db->quote($usr_id,
'integer'),
202 self::ASSIGNMENT_FIELD_ROOT_PRG_ID .
' = ' . $this->db->quote($root_prg_obj_id,
'integer')
210 ?array $user_filter =
null,
214 'pgs.' . self::PROGRESS_FIELD_PRG_ID .
' = ' . $this->db->quote($prg_obj_id,
'integer')
217 $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter,
false,
'integer');
219 if ($custom_filters) {
220 $conditions = array_merge($conditions, $custom_filters->toConditions());
223 $assignments = array_filter(iterator_to_array(
224 $this->read($conditions)
231 ?array $user_filter =
null,
235 'pgs.' . self::PROGRESS_FIELD_PRG_ID .
' = ' . $this->db->quote($prg_obj_id,
'integer')
238 $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter,
false,
'integer');
240 if ($custom_filters) {
241 $conditions = array_merge($conditions, $custom_filters->toConditions());
243 return $this->count($conditions);
249 self::ASSIGNMENT_FIELD_ROOT_PRG_ID .
' = ' . $this->db->quote($prg_obj_id,
'integer')
252 $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter,
false,
'integer');
255 $assignments = array_filter(iterator_to_array(
256 $this->read($conditions)
263 $deadline = $this->db->quote(
270 self::PROGRESS_FIELD_STATUS,
278 self::PROGRESS_FIELD_DEADLINE .
' IS NOT NULL',
279 self::PROGRESS_FIELD_DEADLINE .
' < ' . $deadline
282 $assignments = array_filter(iterator_to_array(
283 $this->read($conditions)
289 array $programmes_and_due,
290 bool $discard_formerly_notified =
true
293 if (count($programmes_and_due) == 0) {
298 foreach ($programmes_and_due as $prg_obj_id => $due) {
299 $due = $due->format(self::DATE_FORMAT_ENDOFDAY);
302 . self::PROGRESS_FIELD_VQ_DATE .
'<=' . $this->db->quote($due,
'text')
303 .
' AND (pgs.' . self::PROGRESS_FIELD_PRG_ID .
'=' . $prg_obj_id
304 .
' OR ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID .
'=' . $prg_obj_id .
')';
306 if ($discard_formerly_notified) {
307 $where_clause .=
' AND ' . self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE .
' IS NULL';
310 $where_clause .=
')';
311 $where[] = $where_clause;
315 implode(
' OR ', $where)
317 $assignments = array_filter(iterator_to_array(
318 $this->read($conditions)
325 $now = (new \DateTimeImmutable())->format(self::DATE_FORMAT_ENDOFDAY);
328 self::PROGRESS_FIELD_STATUS,
336 self::PROGRESS_FIELD_VQ_DATE .
' IS NOT NULL',
337 self::PROGRESS_FIELD_VQ_DATE .
' < ' . $this->db->quote($now,
'text'),
338 self::PROGRESS_FIELD_INVALIDATED .
' = 0 ',
341 $assignments = array_filter(iterator_to_array(
342 $this->read($conditions)
348 array $programmes_and_due,
349 bool $discard_formerly_notified =
true
352 if (count($programmes_and_due) == 0) {
357 foreach ($programmes_and_due as $prg_obj_id => $due) {
361 . self::PROGRESS_FIELD_DEADLINE .
'<=' . $this->db->quote($due,
'text')
362 .
'AND (pgs.' . self::PROGRESS_FIELD_PRG_ID .
'=' . $prg_obj_id
363 .
' OR ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID .
'=' . $prg_obj_id .
')'
364 .
' AND ' . $this->db->in(
365 self::PROGRESS_FIELD_STATUS,
375 if ($discard_formerly_notified) {
376 $where_clause .=
' AND ' . self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL .
' IS NULL';
379 $where_clause .=
')';
380 $where[] = $where_clause;
384 implode(
' OR ', $where)
386 $assignments = array_filter(iterator_to_array(
387 $this->read($conditions)
394 $user_fields_without_udf = array_filter(
395 $this->user_data_fields,
396 static fn($field) => !str_starts_with($field,
'udf_') && $field !==
'org_units'
400 .
' ass.' . self::ASSIGNMENT_FIELD_ID .
' AS ' . self::ASSIGNMENT_FIELD_ID
401 .
', ass.' . self::ASSIGNMENT_FIELD_USR_ID .
' AS ' . self::ASSIGNMENT_FIELD_USR_ID
402 .
',' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID
403 .
', ass.' . self::ASSIGNMENT_FIELD_LAST_CHANGE
404 .
', ass.' . self::ASSIGNMENT_FIELD_LAST_CHANGE_BY
405 .
',' . self::ASSIGNMENT_FIELD_RESTART_DATE
406 .
',' . self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID
407 .
',' . self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED
408 .
',' . self::PROGRESS_FIELD_PRG_ID
409 .
',' . self::PROGRESS_FIELD_POINTS
410 .
',' . self::PROGRESS_FIELD_POINTS_CUR
411 .
',' . self::PROGRESS_FIELD_STATUS
412 .
',' . self::PROGRESS_FIELD_COMPLETION_BY
413 .
',' . self::PROGRESS_FIELD_ASSIGNMENT_DATE
414 .
', pgs.' . self::PROGRESS_FIELD_LAST_CHANGE .
' AS p_' . self::PROGRESS_FIELD_LAST_CHANGE
415 .
', pgs.' . self::PROGRESS_FIELD_LAST_CHANGE_BY .
' AS p_' . self::PROGRESS_FIELD_LAST_CHANGE_BY
416 .
',' . self::PROGRESS_FIELD_COMPLETION_DATE
417 .
',' . self::PROGRESS_FIELD_DEADLINE
418 .
',' . self::PROGRESS_FIELD_VQ_DATE
419 .
',' . self::PROGRESS_FIELD_INVALIDATED
420 .
',' . self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL
421 .
',' . self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE
422 .
',' . self::PROGRESS_FIELD_IS_INDIVIDUAL
424 .
', ' . implode(
', ', $user_fields_without_udf)
426 .
' FROM ' . self::ASSIGNMENT_TABLE .
' ass '
427 .
' JOIN ' . self::PROGRESS_TABLE .
' pgs '
428 .
' ON ass.' . self::ASSIGNMENT_FIELD_ID .
' = pgs.' . self::PROGRESS_FIELD_ASSIGNMENT_ID
431 .
' JOIN usr_data memberdata ON ass.usr_id = memberdata.usr_id '
433 .
' WHERE TRUE AND ';
434 $q =
$q . implode(
' AND ', $filter);
435 $q =
$q .
' ORDER BY assignment_id, ass.usr_id';
437 $res = $this->db->query(
$q);
443 return $this->db->nextId(self::ASSIGNMENT_TABLE);
448 $res = $this->query($filter);
449 return $this->db->numRows(
$res);
452 protected function read(array $filter): Generator
454 $res = $this->query($filter);
459 while ($row = $this->db->fetchAssoc(
$res)) {
460 if ($row[self::ASSIGNMENT_FIELD_ID] !== $current_ass) {
461 $current_ass = $row[self::ASSIGNMENT_FIELD_ID];
462 if (!is_null($ass)) {
465 $this->progresses = $this->prebuildProgressesForAssingment((
int) $row[self::ASSIGNMENT_FIELD_ID]);
466 $ass = $this->assignmentByRow($row);
475 $q =
'SELECT * FROM ' . self::PROGRESS_TABLE
476 .
' WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID .
' = ' . $assignment_id;
477 $res = $this->db->query(
$q);
478 while ($row = $this->db->fetchAssoc(
$res)) {
479 $ret[$row[self::PROGRESS_FIELD_PRG_ID]] = $this->buildProgressByRow($row);
487 (
int) $row[self::ASSIGNMENT_FIELD_ID],
488 (
int) $row[self::ASSIGNMENT_FIELD_USR_ID]
491 ->withEvents($this->events)
493 (
int) $row[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY],
494 \DateTimeImmutable::createFromFormat(
496 $row[self::ASSIGNMENT_FIELD_LAST_CHANGE]
500 (
int) $row[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID],
501 $row[self::ASSIGNMENT_FIELD_RESTART_DATE] ?
505 ->withManuallyAssigned((
bool) $row[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED]);
508 $root_pgs_id = (
int) $row[self::ASSIGNMENT_FIELD_ROOT_PRG_ID];
509 $pgs = $this->buildProgressTreeFor($root_pgs_id);
511 $user_information = $this->buildUserInformation($row);
514 ->withProgressTree($pgs)
515 ->withUserInformation($user_information);
521 $children = array_filter(
522 $this->tree->getChilds($this->getRefIdFor($node_obj_id)),
523 fn(
$c) => in_array(
$c[
'type'], [
'prg',
'prgr']),
525 $children = array_map(
531 foreach ($children as $child_obj_id) {
532 $pgss[] = $this->buildProgressTreeFor($child_obj_id);
535 if (!array_key_exists($node_obj_id, $this->progresses)) {
538 $pgs = $this->progresses[$node_obj_id];
540 $pgs->setSubnodes($pgss);
547 if (count($refs) < 1) {
548 throw new ilException(
"Could not find ref_id for programme with obj_id $obj_id");
550 return (
int) array_shift($refs);
560 (
int) $row[self::PROGRESS_FIELD_PRG_ID],
561 (
int) $row[self::PROGRESS_FIELD_STATUS]
565 ->withAmountOfPoints((
int) $row[self::PROGRESS_FIELD_POINTS])
566 ->withCurrentAmountOfPoints((
int) $row[self::PROGRESS_FIELD_POINTS_CUR])
567 ->withAssignmentDate(
568 $row[self::PROGRESS_FIELD_ASSIGNMENT_DATE] ?
573 $row[self::PROGRESS_FIELD_DEADLINE] ?
578 (
int) $row[self::PROGRESS_FIELD_COMPLETION_BY],
579 $row[self::PROGRESS_FIELD_COMPLETION_DATE] ?
584 (
int) $row[self::PROGRESS_FIELD_LAST_CHANGE_BY],
585 $row[self::PROGRESS_FIELD_LAST_CHANGE] ?
589 ->withValidityOfQualification(
590 $row[self::PROGRESS_FIELD_VQ_DATE] ?
594 ->withIndividualModifications((
bool) $row[self::PROGRESS_FIELD_IS_INDIVIDUAL])
595 ->withInvalidated((
bool) $row[self::PROGRESS_FIELD_INVALIDATED]);
606 $orgus = array_values($orgu_repo->findAllUserAssingmentsByUserIds([$usr_id]));
608 $orgu_ref_ids = array_map(
609 fn($orgu_assignment) => $orgu_assignment->getOrguId(),
617 return implode(
', ', $orgus);
622 $udf_data = $this->
profile->getDataFor((
int) $row[self::ASSIGNMENT_FIELD_USR_ID]);
623 $user_data_values = [];
624 foreach ($this->user_data_fields as $field) {
627 $user_data_values[$field] = (bool) $row[$field];
631 $user_data_values[$field] = $this->interimOrguLookup((
int) $row[self::ASSIGNMENT_FIELD_USR_ID]);
633 case str_starts_with($field,
'udf_'):
634 $udf_field_id = str_replace(
'udf_',
'f_', $field);
635 $user_data_values[$field] = $udf_data->getAdditionalFieldByIdentifier($udf_field_id);
638 $user_data_values[$field] = $row[$field];
649 self::ASSIGNMENT_TABLE,
651 self::ASSIGNMENT_FIELD_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_ID]]
652 , self::ASSIGNMENT_FIELD_USR_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_USR_ID]]
653 , self::ASSIGNMENT_FIELD_ROOT_PRG_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_ROOT_PRG_ID]]
654 , self::ASSIGNMENT_FIELD_LAST_CHANGE => [
'text', $row[self::ASSIGNMENT_FIELD_LAST_CHANGE]]
655 , self::ASSIGNMENT_FIELD_LAST_CHANGE_BY => [
'integer', $row[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY]]
656 , self::ASSIGNMENT_FIELD_RESTART_DATE => [
'timestamp', $row[self::ASSIGNMENT_FIELD_RESTART_DATE]]
657 , self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID]]
658 , self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED => [
'integer', $row[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED]]
665 $q =
'UPDATE ' . self::ASSIGNMENT_TABLE
667 .
' ' . self::ASSIGNMENT_FIELD_USR_ID .
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_USR_ID],
'integer')
668 .
' ,' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID .
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_ROOT_PRG_ID],
'integer')
669 .
' ,' . self::ASSIGNMENT_FIELD_LAST_CHANGE .
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_LAST_CHANGE],
'text')
670 .
' ,' . self::ASSIGNMENT_FIELD_LAST_CHANGE_BY .
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY],
'integer')
671 .
' ,' . self::ASSIGNMENT_FIELD_RESTART_DATE .
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_RESTART_DATE],
'timestamp')
672 .
' ,' . self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID .
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID],
'integer')
673 .
' ,' . self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED .
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED],
'integer')
674 .
' WHERE ' . self::ASSIGNMENT_FIELD_ID .
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_ID],
'integer');
675 $this->db->manipulate(
$q);
693 $q =
'INSERT INTO ' . self::PROGRESS_TABLE
695 . self::PROGRESS_FIELD_ASSIGNMENT_ID .
','
696 . self::PROGRESS_FIELD_USR_ID .
','
697 . self::PROGRESS_FIELD_PRG_ID .
','
699 . self::PROGRESS_FIELD_STATUS .
','
700 . self::PROGRESS_FIELD_POINTS .
','
701 . self::PROGRESS_FIELD_POINTS_CUR .
','
702 . self::PROGRESS_FIELD_COMPLETION_BY .
','
703 . self::PROGRESS_FIELD_LAST_CHANGE_BY .
','
704 . self::PROGRESS_FIELD_LAST_CHANGE .
','
705 . self::PROGRESS_FIELD_ASSIGNMENT_DATE .
','
706 . self::PROGRESS_FIELD_COMPLETION_DATE .
','
707 . self::PROGRESS_FIELD_DEADLINE .
','
708 . self::PROGRESS_FIELD_VQ_DATE .
','
709 . self::PROGRESS_FIELD_INVALIDATED .
','
710 . self::PROGRESS_FIELD_IS_INDIVIDUAL
712 . PHP_EOL .
') VALUES (' . PHP_EOL
723 .
' ,' . $assign_date
724 .
' ,' . $completion_date
727 .
' ,' . $invalidated
730 .
'ON DUPLICATE KEY UPDATE' . PHP_EOL
731 . self::PROGRESS_FIELD_STATUS .
'=' . $pgs->
getStatus() .
','
734 . self::PROGRESS_FIELD_COMPLETION_BY .
'=' . $completion .
','
735 . self::PROGRESS_FIELD_LAST_CHANGE_BY .
'=' . $pgs->
getLastChangeBy() .
','
736 . self::PROGRESS_FIELD_LAST_CHANGE .
'=' . $lastchange .
','
737 . self::PROGRESS_FIELD_ASSIGNMENT_DATE .
'=' . $assign_date .
','
738 . self::PROGRESS_FIELD_COMPLETION_DATE .
'=' . $completion_date .
','
739 . self::PROGRESS_FIELD_DEADLINE .
'=' . $deadline .
','
740 . self::PROGRESS_FIELD_VQ_DATE .
'=' . $validity .
','
741 . self::PROGRESS_FIELD_INVALIDATED .
'=' . $invalidated .
','
742 . self::PROGRESS_FIELD_IS_INDIVIDUAL .
'=' . $individual
744 $this->db->manipulate(
$q);
750 self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
751 self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
755 self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE => [
760 $this->db->update(self::PROGRESS_TABLE, $values, $where);
766 self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
767 self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
771 self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE => [
'null',
null]
773 $this->db->update(self::PROGRESS_TABLE, $values, $where);
779 self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
780 self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
784 self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL => [
789 $this->db->update(self::PROGRESS_TABLE, $values, $where);
795 self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
796 self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
800 self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL => [
'null',
null]
802 $this->db->update(self::PROGRESS_TABLE, $values, $where);
807 $assignments = $this->getForUserOnNode($usr_id, $root_prg_obj_id);
808 if ($assignments === []) {
814 =>
$a->getProgressTree()->getAssignmentDate() <=>
$b->getProgressTree()->getAssignmentDate()
816 $assignments = array_reverse($assignments);
817 return current($assignments);
822 $assignments = $this->getForUserOnNode($usr_id, $root_prg_obj_id);
823 if ($assignments === []) {
827 $now = new \DateTimeImmutable();
828 $valid = array_filter($assignments, fn($ass) => $ass->getProgressTree()->hasValidQualification($now));
833 $unlimited = array_filter(
$valid, fn($ass) => $ass->getProgressTree()->getValidityOfQualification() ===
null);
834 if ($unlimited !== []) {
838 =>
$a->getProgressTree()->getAssignmentDate() <=>
$b->getProgressTree()->getAssignmentDate()
840 $unlimited = array_reverse($unlimited);
841 return current($unlimited);
847 =>
$a->getProgressTree()->getValidityOfQualification() <=>
$b->getProgressTree()->getValidityOfQualification()
855 $query =
'SELECT assignment_id FROM (' . PHP_EOL
856 .
'SELECT usr_id, assignment_id, ROW_NUMBER() OVER (' . PHP_EOL
857 .
'PARTITION BY usr_id' . PHP_EOL
858 .
'ORDER BY' . PHP_EOL
859 .
'CASE WHEN vq_date IS NULL THEN 1 ELSE 0 END DESC,' . PHP_EOL
860 .
'vq_date DESC,' . PHP_EOL
861 .
'completion_date DESC' . PHP_EOL
862 .
') AS row_numbers' . PHP_EOL
863 .
'FROM prg_usr_progress' . PHP_EOL
864 .
'WHERE prg_id = ' . $this->db->quote($prg_obj_id,
'integer') . PHP_EOL
865 .
'AND ' . $this->db->in(
'usr_id', $usr_id,
false,
'integer') . PHP_EOL
867 .
') ranked ' . PHP_EOL
868 .
'WHERE row_numbers = 1';
870 $res = $this->db->query($query);
872 fn($r) => $r[
'assignment_id'],
873 $this->db->fetchAll(
$res)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
static _lookupTargetId(int $a_obj_id)
Base class for ILIAS Exception handling.
getSelectableFieldsInfo(?int $a_obj_id=null)
Get selectable fields.
static _lookupObjectId(int $ref_id)
static _lookupType(int $id, bool $reference=false)
static _getAllReferences(int $id)
get all reference ids for object ID
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
deleteAllAssignmentsForProgrammeId(int $prg_obj_id)
resetExpiryInfoSentFor(ilPRGAssignment $ass)
const ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID
prebuildProgressesForAssingment(int $assignment_id)
const PROGRESS_FIELD_INVALIDATED
const PROGRESS_FIELD_COMPLETION_BY
const PROGRESS_FIELD_POINTS
const ASSIGNMENT_FIELD_RESTART_MAIL
getLongestValidAssignment(int $root_prg_obj_id, int $usr_id)
Get the user's assignment on a prg with the longest lasting qualification.
const ASSIGNMENT_FIELD_ID
getRiskyToFail(array $programmes_and_due, bool $discard_formerly_notified=true)
const PROGRESS_FIELD_LAST_CHANGE_BY
const ASSIGNMENT_FIELD_RESTART_DATE
getCertificateRelevantAssignmentIds(int $prg_obj_id, int ... $usr_id)
countAllForNodeIsContained(int $prg_obj_id, ?array $user_filter=null, ?ilPRGAssignmentFilter $custom_filters=null)
Count all assignments for all (or given) users, where the given node is part of the assignment.
getDashboardInstancesforUser(int $usr_id)
getAboutToExpire(array $programmes_and_due, bool $discard_formerly_notified=true)
const ASSIGNMENT_FIELD_ROOT_PRG_ID
getLatestAssignment(int $root_prg_obj_id, int $usr_id)
Get the user's assignment on a prg that was created last.
const ASSIGNMENT_FIELD_MANUALLY_ASSIGNED
const PROGRESS_FIELD_PRG_ID
const PROGRESS_FIELD_ASSIGNMENT_DATE
const ASSIGNMENT_FIELD_LAST_CHANGE
const PROGRESS_FIELD_ASSIGNMENT_ID
const ASSIGNMENT_FIELD_USR_ID
__construct(protected ilDBInterface $db, protected ilTree $tree, protected Profile $profile, protected ilStudyProgrammeSettingsRepository $settings_repo, protected PRGEventsDelayed $events, ilExportFieldsInfo $user_field_info)
insertAssignmentRowDB(array $row)
storeRiskyToFailSentFor(ilPRGAssignment $ass)
storeExpiryInfoSentFor(ilPRGAssignment $ass)
interimOrguLookup(int $usr_id)
resetRiskyToFailSentFor(ilPRGAssignment $ass)
const PROGRESS_FIELD_IS_INDIVIDUAL
getPassedDeadline(\DateTimeImmutable $deadline)
getAllForSpecificNode(int $prg_obj_id, ?array $user_filter=null)
get all assignments for all (or given) users, where the given node is the root-node of the assignment
const PROGRESS_FIELD_USR_ID
getForUserOnNode(int $usr_id, int $root_prg_obj_id)
getExpiredAndNotInvalidated()
deleteAllOrphanedProgresses()
array $progresses
<id => ilPRGProgress>
const PROGRESS_FIELD_STATUS
const PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL
buildUserInformation(array $row)
buildProgressTreeFor(int $node_obj_id)
store(ilPRGAssignment $assignment)
getForUser(int $usr_id)
get all assignments for a user
const ASSIGNMENT_FIELD_LAST_CHANGE_BY
const PROGRESS_FIELD_VQ_DATE
createFor(int $prg_obj_id, int $usr_id, int $assigning_usr_id)
updateAssignmentRowDB(array $values)
const PROGRESS_FIELD_DEADLINE
const PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE
const PROGRESS_FIELD_COMPLETION_DATE
const DATE_FORMAT_ENDOFDAY
assignmentByRow(array $row)
getAllForNodeIsContained(int $prg_obj_id, ?array $user_filter=null, ?ilPRGAssignmentFilter $custom_filters=null)
get all assignments for all (or given) users, where the given node is part of the assignment
storeProgressRow(int $assignment_id, int $usr_id, ilPRGProgress $pgs)
buildProgressByRow(array $row)
const PROGRESS_FIELD_LAST_CHANGE
const PROGRESS_FIELD_POINTS_CUR
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
getRestartedAssignmentId()
getProgresses(array &$ret=[], ?ilPRGProgress $pgs=null)
const NO_RESTARTED_ASSIGNMENT
A Progress is the status of a user on a single node of an assignment; it is unique by assignment_id:u...
hasIndividualModifications()
const STATUS_NOT_RELEVANT
getValidityOfQualification()
getCurrentAmountOfPoints()
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
static now()
Return current timestamp in Y-m-d H:i:s format.
Covers the persistence of settings belonging to a study programme (SP).
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples