19 declare(strict_types=1);
    73         $this->user_data_fields = array_merge(
    96             self::ASSIGNMENT_FIELD_ID => $this->
nextId(),
    97             self::ASSIGNMENT_FIELD_USR_ID => $usr_id,
    98             self::ASSIGNMENT_FIELD_ROOT_PRG_ID => $prg_obj_id,
    99             self::ASSIGNMENT_FIELD_LAST_CHANGE_BY => $assigning_usr_id,
   100             self::ASSIGNMENT_FIELD_LAST_CHANGE => 
ilUtil::now(),
   101             self::ASSIGNMENT_FIELD_RESTART_DATE => null,
   103             self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED => $manually
   106         $this->progresses = [];
   108         $user_data_fields = array_filter(
   109             $this->user_data_fields,
   110             static fn($field) => !str_starts_with($field, 
'udf_') && $field !== 
'org_units'   112         $query = 
'SELECT ' . implode(
',', $user_data_fields) . PHP_EOL
   113             . 
'FROM usr_data WHERE usr_id = ' . $this->db->quote($usr_id, 
'integer');
   114         $res = $this->db->query($query);
   115         $row = array_merge($row, $this->db->fetchAssoc(
$res));
   124             self::ASSIGNMENT_FIELD_ID => $assignment->
getId(),
   125             self::ASSIGNMENT_FIELD_USR_ID => $assignment->
getUserId(),
   126             self::ASSIGNMENT_FIELD_ROOT_PRG_ID => $assignment->
getRootId(),
   127             self::ASSIGNMENT_FIELD_LAST_CHANGE_BY => $assignment->
getLastChangeBy(),
   136                 $assignment->
getId(),
   142         $this->events->raiseCollected();
   147         $ass_id = $assignment->getId();
   148         $query = 
'DELETE FROM ' . self::ASSIGNMENT_TABLE . PHP_EOL
   149          . 
'WHERE ' . self::ASSIGNMENT_FIELD_ID . 
' = ' . 
$ass_id;
   150         $this->db->manipulate($query);
   152         $query = 
'DELETE FROM ' . self::PROGRESS_TABLE . PHP_EOL
   153          . 
'WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID . 
' = ' . 
$ass_id;
   154         $this->db->manipulate($query);
   159         $query = 
'DELETE FROM ' . self::ASSIGNMENT_TABLE . PHP_EOL
   160             . 
'WHERE ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
'=' . $this->db->quote($prg_obj_id, 
'integer');
   161         $this->db->manipulate($query);
   166         $query = 
'DELETE FROM ' . self::PROGRESS_TABLE . PHP_EOL
   167             . 
'WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID . PHP_EOL
   168             . 
'NOT IN (' . PHP_EOL
   169             . 
'SELECT ' . $this->db->quoteIdentifier(self::ASSIGNMENT_FIELD_ID)
   170             . 
' FROM ' . $this->db->quoteIdentifier(self::ASSIGNMENT_TABLE) . PHP_EOL
   172         $this->db->manipulate($query);
   178             'ass.' . self::ASSIGNMENT_FIELD_ID . 
' = ' . $this->db->quote(
$id, 
'integer')
   181         return $ass->current();
   186         $assignments = array_filter(iterator_to_array(
   188                 'ass.' . self::ASSIGNMENT_FIELD_USR_ID . 
' = ' . $this->db->quote($usr_id, 
'integer')
   196         $assignments = array_filter(iterator_to_array(
   198                 'ass.' . self::ASSIGNMENT_FIELD_USR_ID . 
' = ' . $this->db->quote($usr_id, 
'integer'),
   199                 self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
' = ' . $this->db->quote($root_prg_obj_id, 
'integer')
   207         array $user_filter = null,
   211             'pgs.' . self::PROGRESS_FIELD_PRG_ID . 
' = ' . $this->db->quote($prg_obj_id, 
'integer')
   214             $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter, 
false, 
'integer');
   216         if ($custom_filters) {
   217             $conditions = array_merge($conditions, $custom_filters->toConditions());
   220         $assignments = array_filter(iterator_to_array(
   221             $this->
read($conditions)
   228         array $user_filter = null,
   232             'pgs.' . self::PROGRESS_FIELD_PRG_ID . 
' = ' . $this->db->quote($prg_obj_id, 
'integer')
   235             $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter, 
false, 
'integer');
   237         if ($custom_filters) {
   238             $conditions = array_merge($conditions, $custom_filters->toConditions());
   240         return $this->
count($conditions);
   246             self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
' = ' . $this->db->quote($prg_obj_id, 
'integer')
   249             $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter, 
false, 
'integer');
   252         $assignments = array_filter(iterator_to_array(
   253             $this->
read($conditions)
   260         $deadline = $this->db->quote(
   267                 self::PROGRESS_FIELD_STATUS,
   275             self::PROGRESS_FIELD_DEADLINE . 
' IS NOT NULL',
   276             self::PROGRESS_FIELD_DEADLINE . 
' < ' . $deadline
   279         $assignments = array_filter(iterator_to_array(
   280             $this->
read($conditions)
   286         array $programmes_and_due,
   287         bool $discard_formerly_notified = 
true   290         if (
count($programmes_and_due) == 0) {
   295         foreach ($programmes_and_due as $prg_obj_id => $due) {
   296             $due = $due->format(self::DATE_FORMAT_ENDOFDAY);
   299                 . self::PROGRESS_FIELD_VQ_DATE . 
'<=' . $this->db->quote($due, 
'text')
   300                 . 
' AND (pgs.' . self::PROGRESS_FIELD_PRG_ID . 
'=' . $prg_obj_id
   301                 . 
' OR ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
'=' . $prg_obj_id . 
')';
   303             if ($discard_formerly_notified) {
   304                 $where_clause .= 
' AND ' . self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE . 
' IS NULL';
   307             $where_clause .= 
')';
   308             $where[] = $where_clause;
   312             implode(
' OR ', $where)
   314         $assignments = array_filter(iterator_to_array(
   315             $this->
read($conditions)
   322         $now = (new \DateTimeImmutable())->format(self::DATE_FORMAT_ENDOFDAY);
   325                 self::PROGRESS_FIELD_STATUS,
   333             self::PROGRESS_FIELD_VQ_DATE . 
' IS NOT NULL',
   334             self::PROGRESS_FIELD_VQ_DATE . 
' < ' . $this->db->quote($now, 
'text'),
   335             self::PROGRESS_FIELD_INVALIDATED . 
' = 0 ',
   338         $assignments = array_filter(iterator_to_array(
   339             $this->
read($conditions)
   345         array $programmes_and_due,
   346         bool $discard_formerly_notified = 
true   349         if (
count($programmes_and_due) == 0) {
   354         foreach ($programmes_and_due as $prg_obj_id => $due) {
   358                 . self::PROGRESS_FIELD_DEADLINE . 
'<=' . $this->db->quote($due, 
'text')
   359                 . 
'AND (pgs.' . self::PROGRESS_FIELD_PRG_ID . 
'=' . $prg_obj_id
   360                 . 
' OR ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
'=' . $prg_obj_id . 
')'   361                 . 
' AND ' . $this->db->in(
   362                     self::PROGRESS_FIELD_STATUS,
   372             if ($discard_formerly_notified) {
   373                 $where_clause .= 
' AND ' . self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL . 
' IS NULL';
   376             $where_clause .= 
')';
   377             $where[] = $where_clause;
   381             implode(
' OR ', $where)
   383         $assignments = array_filter(iterator_to_array(
   384             $this->
read($conditions)
   391         $user_fields_without_udf = array_filter(
   392             $this->user_data_fields,
   393             static fn($field) => !str_starts_with($field, 
'udf_') && $field !== 
'org_units'   397             . 
'  ass.' . self::ASSIGNMENT_FIELD_ID . 
' AS ' . self::ASSIGNMENT_FIELD_ID
   398             . 
', ass.' . self::ASSIGNMENT_FIELD_USR_ID . 
' AS ' . self::ASSIGNMENT_FIELD_USR_ID
   399             . 
',' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID
   400             . 
', ass.' . self::ASSIGNMENT_FIELD_LAST_CHANGE
   401             . 
', ass.' . self::ASSIGNMENT_FIELD_LAST_CHANGE_BY
   402             . 
',' . self::ASSIGNMENT_FIELD_RESTART_DATE
   403             . 
',' . self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID
   404             . 
',' . self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED
   405             . 
',' . self::PROGRESS_FIELD_PRG_ID
   406             . 
',' . self::PROGRESS_FIELD_POINTS
   407             . 
',' . self::PROGRESS_FIELD_POINTS_CUR
   408             . 
',' . self::PROGRESS_FIELD_STATUS
   409             . 
',' . self::PROGRESS_FIELD_COMPLETION_BY
   410             . 
',' . self::PROGRESS_FIELD_ASSIGNMENT_DATE
   411             . 
', pgs.' . self::PROGRESS_FIELD_LAST_CHANGE . 
' AS p_' . self::PROGRESS_FIELD_LAST_CHANGE
   412             . 
', pgs.' . self::PROGRESS_FIELD_LAST_CHANGE_BY . 
' AS p_' . self::PROGRESS_FIELD_LAST_CHANGE_BY
   413             . 
',' . self::PROGRESS_FIELD_COMPLETION_DATE
   414             . 
',' . self::PROGRESS_FIELD_DEADLINE
   415             . 
',' . self::PROGRESS_FIELD_VQ_DATE
   416             . 
',' . self::PROGRESS_FIELD_INVALIDATED
   417             . 
',' . self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL
   418             . 
',' . self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE
   419             . 
',' . self::PROGRESS_FIELD_IS_INDIVIDUAL
   421             . 
', ' . implode(
', ', $user_fields_without_udf)
   423             . 
' FROM ' . self::ASSIGNMENT_TABLE . 
' ass '   424             . 
' JOIN ' . self::PROGRESS_TABLE . 
' pgs '   425             . 
' ON ass.' . self::ASSIGNMENT_FIELD_ID . 
' = pgs.' . self::PROGRESS_FIELD_ASSIGNMENT_ID
   428             . 
' JOIN usr_data memberdata ON ass.usr_id = memberdata.usr_id '   430             . 
' WHERE TRUE AND ';
   431         $q = 
$q . implode(
' AND ', $filter);
   432         $q = 
$q . 
' ORDER BY assignment_id, ass.usr_id';
   434         $res = $this->db->query(
$q);
   440         return $this->db->nextId(self::ASSIGNMENT_TABLE);
   446         return $this->db->numRows(
$res);
   456         while ($row = $this->db->fetchAssoc(
$res)) {
   457             if ($row[self::ASSIGNMENT_FIELD_ID] !== $current_ass) {
   458                 $current_ass = $row[self::ASSIGNMENT_FIELD_ID];
   459                 if (!is_null($ass)) {
   472         $q = 
'SELECT * FROM ' . self::PROGRESS_TABLE
   473             . 
' WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID . 
' = ' . $assignment_id;
   474         $res = $this->db->query(
$q);
   475         while ($row = $this->db->fetchAssoc(
$res)) {
   484             (
int) $row[self::ASSIGNMENT_FIELD_ID],
   485             (
int) $row[self::ASSIGNMENT_FIELD_USR_ID]
   488             ->withEvents($this->events)
   490                 (
int) $row[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY],
   491                 \DateTimeImmutable::createFromFormat(
   493                     $row[self::ASSIGNMENT_FIELD_LAST_CHANGE]
   497                 (
int) $row[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID],
   498                 $row[self::ASSIGNMENT_FIELD_RESTART_DATE] ?
   502             ->withManuallyAssigned((
bool) $row[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED]);
   505         $root_pgs_id = (
int) $row[self::ASSIGNMENT_FIELD_ROOT_PRG_ID];
   511             ->withProgressTree($pgs)
   512             ->withUserInformation($user_information);
   518         $children = array_filter(
   519             $this->tree->getChilds($this->getRefIdFor($node_obj_id)),
   520             fn(
$c) => in_array(
$c[
'type'], [
'prg', 
'prgr']),
   528         foreach ($children as $child_obj_id) {
   532         if (!array_key_exists($node_obj_id, $this->progresses)) {
   535             $pgs = $this->progresses[$node_obj_id];
   537         $pgs->setSubnodes($pgss);
   544         if (
count($refs) < 1) {
   545             throw new ilException(
"Could not find ref_id for programme with obj_id $obj_id");
   547         return (
int) array_shift($refs);
   557             (
int) $row[self::PROGRESS_FIELD_PRG_ID],
   558             (
int) $row[self::PROGRESS_FIELD_STATUS]
   562             ->withAmountOfPoints((
int) $row[self::PROGRESS_FIELD_POINTS])
   563             ->withCurrentAmountOfPoints((
int) $row[self::PROGRESS_FIELD_POINTS_CUR])
   564             ->withAssignmentDate(
   565                 $row[self::PROGRESS_FIELD_ASSIGNMENT_DATE] ?
   570                 $row[self::PROGRESS_FIELD_DEADLINE] ?
   575                 (
int) $row[self::PROGRESS_FIELD_COMPLETION_BY],
   576                 $row[self::PROGRESS_FIELD_COMPLETION_DATE] ?
   581                 (
int) $row[self::PROGRESS_FIELD_LAST_CHANGE_BY],
   582                 $row[self::PROGRESS_FIELD_LAST_CHANGE] ?
   586             ->withValidityOfQualification(
   587                 $row[self::PROGRESS_FIELD_VQ_DATE] ?
   591             ->withIndividualModifications((
bool) $row[self::PROGRESS_FIELD_IS_INDIVIDUAL])
   592             ->withInvalidated((
bool) $row[self::PROGRESS_FIELD_INVALIDATED]);
   603         $orgus = array_values($orgu_repo->findAllUserAssingmentsByUserIds([$usr_id]));
   606                 fn($orgu_assignment) => $orgu_assignment->getOrguId(),
   614         return implode(
', ', $orgus);
   620         $user_data_values = [];
   621         foreach ($this->user_data_fields as $field) {
   624                     $user_data_values[$field] = (bool) $row[$field];
   628                     $user_data_values[$field] = $this->
interimOrguLookup((
int) $row[self::ASSIGNMENT_FIELD_USR_ID]);
   630                 case str_starts_with($field, 
'udf_'):
   631                     $udf_field_id = str_replace(
'udf_', 
'f_', $field);
   632                     $user_data_values[$field] = $udf_data->get($udf_field_id);
   635                     $user_data_values[$field] = $row[$field];
   646             self::ASSIGNMENT_TABLE,
   648                 self::ASSIGNMENT_FIELD_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_ID]]
   649                 , self::ASSIGNMENT_FIELD_USR_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_USR_ID]]
   650                 , self::ASSIGNMENT_FIELD_ROOT_PRG_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_ROOT_PRG_ID]]
   651                 , self::ASSIGNMENT_FIELD_LAST_CHANGE => [
'text', $row[self::ASSIGNMENT_FIELD_LAST_CHANGE]]
   652                 , self::ASSIGNMENT_FIELD_LAST_CHANGE_BY => [
'integer', $row[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY]]
   653                 , self::ASSIGNMENT_FIELD_RESTART_DATE => [
'timestamp', $row[self::ASSIGNMENT_FIELD_RESTART_DATE]]
   654                 , self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID]]
   655                 , self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED => [
'integer', $row[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED]]
   662         $q = 
'UPDATE ' . self::ASSIGNMENT_TABLE
   664             . 
' ' . self::ASSIGNMENT_FIELD_USR_ID . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_USR_ID], 
'integer')
   665             . 
' ,' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_ROOT_PRG_ID], 
'integer')
   666             . 
' ,' . self::ASSIGNMENT_FIELD_LAST_CHANGE . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_LAST_CHANGE], 
'text')
   667             . 
' ,' . self::ASSIGNMENT_FIELD_LAST_CHANGE_BY . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY], 
'integer')
   668             . 
' ,' . self::ASSIGNMENT_FIELD_RESTART_DATE . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_RESTART_DATE], 
'timestamp')
   669             . 
' ,' . self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID], 
'integer')
   670             . 
' ,' . self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED], 
'integer')
   671             . 
' WHERE ' . self::ASSIGNMENT_FIELD_ID . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_ID], 
'integer');
   672         $this->db->manipulate(
$q);
   690         $q = 
'INSERT INTO ' . self::PROGRESS_TABLE
   692             . self::PROGRESS_FIELD_ASSIGNMENT_ID . 
','   693             . self::PROGRESS_FIELD_USR_ID . 
','   694             . self::PROGRESS_FIELD_PRG_ID . 
','   696             . self::PROGRESS_FIELD_STATUS . 
','   697             . self::PROGRESS_FIELD_POINTS . 
','   698             . self::PROGRESS_FIELD_POINTS_CUR . 
','   699             . self::PROGRESS_FIELD_COMPLETION_BY . 
','   700             . self::PROGRESS_FIELD_LAST_CHANGE_BY . 
','   701             . self::PROGRESS_FIELD_LAST_CHANGE . 
','   702             . self::PROGRESS_FIELD_ASSIGNMENT_DATE . 
','   703             . self::PROGRESS_FIELD_COMPLETION_DATE . 
','   704             . self::PROGRESS_FIELD_DEADLINE . 
','   705             . self::PROGRESS_FIELD_VQ_DATE . 
','   706             . self::PROGRESS_FIELD_INVALIDATED . 
','   707             . self::PROGRESS_FIELD_IS_INDIVIDUAL
   709             . PHP_EOL . 
') VALUES (' . PHP_EOL
   720             . 
' ,' . $assign_date
   721             . 
' ,' . $completion_date
   724             . 
' ,' . $invalidated
   727             . 
'ON DUPLICATE KEY UPDATE' . PHP_EOL
   728             . self::PROGRESS_FIELD_STATUS . 
'=' . $pgs->
getStatus() . 
','   731             . self::PROGRESS_FIELD_COMPLETION_BY . 
'=' . $completion . 
','   732             . self::PROGRESS_FIELD_LAST_CHANGE_BY . 
'=' . $pgs->
getLastChangeBy() . 
','   733             . self::PROGRESS_FIELD_LAST_CHANGE . 
'=' . $lastchange . 
','   734             . self::PROGRESS_FIELD_ASSIGNMENT_DATE . 
'=' . $assign_date . 
','   735             . self::PROGRESS_FIELD_COMPLETION_DATE . 
'=' . $completion_date . 
','   736             . self::PROGRESS_FIELD_DEADLINE . 
'=' . $deadline . 
','   737             . self::PROGRESS_FIELD_VQ_DATE . 
'=' . $validity . 
','   738             . self::PROGRESS_FIELD_INVALIDATED . 
'=' . $invalidated . 
','   739             . self::PROGRESS_FIELD_IS_INDIVIDUAL . 
'=' . $individual
   741         $this->db->manipulate(
$q);
   747             self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
   748             self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
   752             self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE => [
   757         $this->db->update(self::PROGRESS_TABLE, $values, $where);
   763             self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
   764             self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
   768             self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE => [
'null', null]
   770         $this->db->update(self::PROGRESS_TABLE, $values, $where);
   776             self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
   777             self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
   781             self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL => [
   786         $this->db->update(self::PROGRESS_TABLE, $values, $where);
   792             self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
   793             self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
   797             self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL => [
'null', null]
   799         $this->db->update(self::PROGRESS_TABLE, $values, $where);
   805         if ($assignments === []) {
   813         $assignments = array_reverse($assignments);
   814         return current($assignments);
   820         if ($assignments === []) {
   824         $now = new \DateTimeImmutable();
   825         $valid = array_filter($assignments, fn($ass) => $ass->getProgressTree()->hasValidQualification($now));
   830         $unlimited = array_filter(
$valid, fn($ass) => $ass->getProgressTree()->getValidityOfQualification() === null);
   831         if ($unlimited !== []) {
   837             $unlimited = array_reverse($unlimited);
   838             return current($unlimited);
   846         $valid = array_reverse($valid);
   847         return current($valid);
   852         $query = 
'SELECT assignment_id FROM (' . PHP_EOL
   853             . 
'SELECT usr_id, assignment_id, ROW_NUMBER() OVER (' . PHP_EOL
   854                 . 
'PARTITION BY usr_id' . PHP_EOL
   855                 . 
'ORDER BY' . PHP_EOL
   856                 . 
'CASE WHEN vq_date IS NULL THEN 1 ELSE 0 END DESC,' . PHP_EOL
   857                 . 
'vq_date DESC,' . PHP_EOL
   858                 . 
'completion_date DESC' . PHP_EOL
   859             . 
') AS row_numbers' . PHP_EOL
   860         . 
'FROM prg_usr_progress' . PHP_EOL
   861         . 
'WHERE prg_id = ' . $this->db->quote($prg_obj_id, 
'integer') . PHP_EOL
   862         . 
'AND ' . $this->db->in(
'usr_id', $usr_id, 
false, 
'integer') . PHP_EOL
   864         . 
') ranked ' . PHP_EOL
   865         . 
'WHERE row_numbers = 1';
   867         $res = $this->db->query($query);
   869             fn(
$r) => 
$r[
'assignment_id'],
   870             $this->db->fetchAll(
$res)
 deleteAllOrphanedProgresses()
 
const PROGRESS_FIELD_POINTS_CUR
 
getForUser(int $usr_id)
get all assignments for a user 
 
interimOrguLookup(int $usr_id)
 
const ASSIGNMENT_FIELD_LAST_CHANGE_BY
 
const ASSIGNMENT_FIELD_ROOT_PRG_ID
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
const PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL
 
resetRiskyToFailSentFor(ilPRGAssignment $ass)
 
const PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE
 
const PROGRESS_FIELD_INVALIDATED
 
const PROGRESS_FIELD_ASSIGNMENT_ID
 
insertAssignmentRowDB(array $row)
 
getRiskyToFail(array $programmes_and_due, bool $discard_formerly_notified=true)
 
static _getAllReferences(int $id)
get all reference ids for object ID 
 
getLongestValidAssignment(int $root_prg_obj_id, int $usr_id)
Get the user's assignment on a prg with the longest lasting qualification. 
 
storeRiskyToFailSentFor(ilPRGAssignment $ass)
 
getDashboardInstancesforUser(int $usr_id)
 
getLatestAssignment(int $root_prg_obj_id, int $usr_id)
Get the user's assignment on a prg that was created last. 
 
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...
 
createFor(int $prg_obj_id, int $usr_id, int $assigning_usr_id)
 
getSelectableFieldsInfo(?int $a_obj_id=null)
Get selectable fields. 
 
const ASSIGNMENT_FIELD_RESTART_MAIL
 
getValidityOfQualification()
 
const PROGRESS_FIELD_POINTS
 
static now()
Return current timestamp in Y-m-d H:i:s format. 
 
const PROGRESS_FIELD_PRG_ID
 
__construct(protected ilDBInterface $db, protected ilTree $tree, protected ilStudyProgrammeSettingsRepository $settings_repo, protected PRGEventsDelayed $events, ilExportFieldsInfo $user_field_info)
 
deleteAllAssignmentsForProgrammeId(int $prg_obj_id)
 
const PROGRESS_FIELD_LAST_CHANGE_BY
 
static _lookupObjId(int $ref_id)
 
resetExpiryInfoSentFor(ilPRGAssignment $ass)
 
prebuildProgressesForAssingment(int $assignment_id)
 
getRestartedAssignmentId()
 
buildProgressByRow(array $row)
 
A Progress is the status of a user on a single node of an assignment; it is unique by assignment_id:u...
 
const PROGRESS_FIELD_STATUS
 
const ASSIGNMENT_FIELD_ID
 
assignmentByRow(array $row)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
hasIndividualModifications()
 
const ASSIGNMENT_FIELD_MANUALLY_ASSIGNED
 
static _lookupTitle(int $obj_id)
 
const PROGRESS_FIELD_DEADLINE
 
const PROGRESS_FIELD_ASSIGNMENT_DATE
 
array $progresses
<id => ilPRGProgress> 
 
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...
 
store(ilPRGAssignment $assignment)
 
getProgresses(array &$ret=[], ilPRGProgress $pgs=null)
 
const PROGRESS_FIELD_LAST_CHANGE
 
static _lookupObjectId(int $ref_id)
 
const ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID
 
const PROGRESS_FIELD_VQ_DATE
 
getForUserOnNode(int $usr_id, int $root_prg_obj_id)
 
storeExpiryInfoSentFor(ilPRGAssignment $ass)
 
const STATUS_NOT_RELEVANT
 
getCurrentAmountOfPoints()
 
getPassedDeadline(\DateTimeImmutable $deadline)
 
const NO_RESTARTED_ASSIGNMENT
 
const ASSIGNMENT_FIELD_USR_ID
 
getExpiredAndNotInvalidated()
 
const DATE_FORMAT_ENDOFDAY
 
const PROGRESS_FIELD_COMPLETION_DATE
 
const PROGRESS_FIELD_COMPLETION_BY
 
storeProgressRow(int $assignment_id, int $usr_id, ilPRGProgress $pgs)
 
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
 
buildProgressTreeFor(int $node_obj_id)
 
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins 
 
const ASSIGNMENT_FIELD_RESTART_DATE
 
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples 
 
buildUserInformation(array $row)
 
static _lookupTargetId(int $a_obj_id)
 
const ASSIGNMENT_FIELD_LAST_CHANGE
 
const PROGRESS_FIELD_USR_ID
 
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 ...
 
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
 
getAboutToExpire(array $programmes_and_due, bool $discard_formerly_notified=true)
 
static _lookupType(int $id, bool $reference=false)
 
updateAssignmentRowDB(array $values)
 
getCertificateRelevantAssignmentIds(int $prg_obj_id, int ... $usr_id)
 
const PROGRESS_FIELD_IS_INDIVIDUAL