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_fields = array_filter(
   109             $this->user_data_fields,
   110             fn(
$f) => !str_starts_with(
$f, 
'udf_') && 
$f !== 
'org_units'   114             . implode(
',', $user_fields)
   116             . 
'FROM usr_data WHERE usr_id = ' . $this->db->quote($usr_id, 
'integer');
   118         $res = $this->db->query($query);
   119         $row = array_merge($row, $this->db->fetchAssoc(
$res));
   128             self::ASSIGNMENT_FIELD_ID => $assignment->
getId(),
   129             self::ASSIGNMENT_FIELD_USR_ID => $assignment->
getUserId(),
   130             self::ASSIGNMENT_FIELD_ROOT_PRG_ID => $assignment->
getRootId(),
   131             self::ASSIGNMENT_FIELD_LAST_CHANGE_BY => $assignment->
getLastChangeBy(),
   140                 $assignment->
getId(),
   146         $this->events->raiseCollected();
   151         $ass_id = $assignment->getId();
   152         $query = 
'DELETE FROM ' . self::ASSIGNMENT_TABLE . PHP_EOL
   153          . 
'WHERE ' . self::ASSIGNMENT_FIELD_ID . 
' = ' . $ass_id;
   154         $this->db->manipulate($query);
   156         $query = 
'DELETE FROM ' . self::PROGRESS_TABLE . PHP_EOL
   157          . 
'WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID . 
' = ' . $ass_id;
   158         $this->db->manipulate($query);
   163         $query = 
'DELETE FROM ' . self::ASSIGNMENT_TABLE . PHP_EOL
   164             . 
'WHERE ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
'=' . $this->db->quote($prg_obj_id, 
'integer');
   165         $this->db->manipulate($query);
   170         $query = 
'DELETE FROM ' . self::PROGRESS_TABLE . PHP_EOL
   171             . 
'WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID . PHP_EOL
   172             . 
'NOT IN (' . PHP_EOL
   173             . 
'SELECT ' . $this->db->quoteIdentifier(self::ASSIGNMENT_FIELD_ID)
   174             . 
' FROM ' . $this->db->quoteIdentifier(self::ASSIGNMENT_TABLE) . PHP_EOL
   176         $this->db->manipulate($query);
   182             'ass.' . self::ASSIGNMENT_FIELD_ID . 
' = ' . $this->db->quote(
$id, 
'integer')
   185         return $ass->current();
   190         $assignments = array_filter(iterator_to_array(
   192                 'ass.' . self::ASSIGNMENT_FIELD_USR_ID . 
' = ' . $this->db->quote($usr_id, 
'integer')
   200         $assignments = array_filter(iterator_to_array(
   202                 'ass.' . self::ASSIGNMENT_FIELD_USR_ID . 
' = ' . $this->db->quote($usr_id, 
'integer'),
   203                 self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
' = ' . $this->db->quote($root_prg_obj_id, 
'integer')
   211         array $user_filter = null,
   215             'pgs.' . self::PROGRESS_FIELD_PRG_ID . 
' = ' . $this->db->quote($prg_obj_id, 
'integer')
   218             $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter, 
false, 
'integer');
   220         if ($custom_filters) {
   221             $conditions = array_merge($conditions, $custom_filters->toConditions());
   224         $assignments = array_filter(iterator_to_array(
   225             $this->
read($conditions)
   232         array $user_filter = null,
   236             'pgs.' . self::PROGRESS_FIELD_PRG_ID . 
' = ' . $this->db->quote($prg_obj_id, 
'integer')
   239             $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter, 
false, 
'integer');
   241         if ($custom_filters) {
   242             $conditions = array_merge($conditions, $custom_filters->toConditions());
   244         return $this->
count($conditions);
   250             self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
' = ' . $this->db->quote($prg_obj_id, 
'integer')
   253             $conditions[] = $this->db->in(
'ass.' . self::ASSIGNMENT_FIELD_USR_ID, $user_filter, 
false, 
'integer');
   256         $assignments = array_filter(iterator_to_array(
   257             $this->
read($conditions)
   264         $deadline = $this->db->quote(
   271                 self::PROGRESS_FIELD_STATUS,
   279             self::PROGRESS_FIELD_DEADLINE . 
' IS NOT NULL',
   280             self::PROGRESS_FIELD_DEADLINE . 
' < ' . $deadline
   283         $assignments = array_filter(iterator_to_array(
   284             $this->
read($conditions)
   290         array $programmes_and_due,
   291         bool $discard_formerly_notified = 
true   294         if (
count($programmes_and_due) == 0) {
   299         foreach ($programmes_and_due as $prg_obj_id => $due) {
   300             $due = $due->format(self::DATE_FORMAT_ENDOFDAY);
   303                 . self::PROGRESS_FIELD_VQ_DATE . 
'<=' . $this->db->quote($due, 
'text')
   304                 . 
' AND (pgs.' . self::PROGRESS_FIELD_PRG_ID . 
'=' . $prg_obj_id
   305                 . 
' OR ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
'=' . $prg_obj_id . 
')';
   307             if ($discard_formerly_notified) {
   308                 $where_clause .= 
' AND ' . self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE . 
' IS NULL';
   311             $where_clause .= 
')';
   312             $where[] = $where_clause;
   316             implode(
' OR ', $where)
   318         $assignments = array_filter(iterator_to_array(
   319             $this->
read($conditions)
   326         $now = (new \DateTimeImmutable())->format(self::DATE_FORMAT_ENDOFDAY);
   329                 self::PROGRESS_FIELD_STATUS,
   337             self::PROGRESS_FIELD_VQ_DATE . 
' IS NOT NULL',
   338             self::PROGRESS_FIELD_VQ_DATE . 
' < ' . $this->db->quote($now, 
'text'),
   339             self::PROGRESS_FIELD_INVALIDATED . 
' = 0 ',
   342         $assignments = array_filter(iterator_to_array(
   343             $this->
read($conditions)
   349         array $programmes_and_due,
   350         bool $discard_formerly_notified = 
true   353         if (
count($programmes_and_due) == 0) {
   358         foreach ($programmes_and_due as $prg_obj_id => $due) {
   362                 . self::PROGRESS_FIELD_DEADLINE . 
'<=' . $this->db->quote($due, 
'text')
   363                 . 
'AND (pgs.' . self::PROGRESS_FIELD_PRG_ID . 
'=' . $prg_obj_id
   364                 . 
' OR ' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
'=' . $prg_obj_id . 
')'   365                 . 
' AND ' . $this->db->in(
   366                     self::PROGRESS_FIELD_STATUS,
   376             if ($discard_formerly_notified) {
   377                 $where_clause .= 
' AND ' . self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL . 
' IS NULL';
   380             $where_clause .= 
')';
   381             $where[] = $where_clause;
   385             implode(
' OR ', $where)
   387         $assignments = array_filter(iterator_to_array(
   388             $this->
read($conditions)
   395         $user_fields_without_udf = array_filter(
   396             $this->user_data_fields,
   397             static fn($field) => !str_starts_with($field, 
'udf_') && $field !== 
'org_units'   401             . 
'  ass.' . self::ASSIGNMENT_FIELD_ID . 
' AS ' . self::ASSIGNMENT_FIELD_ID
   402             . 
', ass.' . self::ASSIGNMENT_FIELD_USR_ID . 
' AS ' . self::ASSIGNMENT_FIELD_USR_ID
   403             . 
',' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID
   404             . 
', ass.' . self::ASSIGNMENT_FIELD_LAST_CHANGE
   405             . 
', ass.' . self::ASSIGNMENT_FIELD_LAST_CHANGE_BY
   406             . 
',' . self::ASSIGNMENT_FIELD_RESTART_DATE
   407             . 
',' . self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID
   408             . 
',' . self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED
   409             . 
',' . self::PROGRESS_FIELD_PRG_ID
   410             . 
',' . self::PROGRESS_FIELD_POINTS
   411             . 
',' . self::PROGRESS_FIELD_POINTS_CUR
   412             . 
',' . self::PROGRESS_FIELD_STATUS
   413             . 
',' . self::PROGRESS_FIELD_COMPLETION_BY
   414             . 
',' . self::PROGRESS_FIELD_ASSIGNMENT_DATE
   415             . 
', pgs.' . self::PROGRESS_FIELD_LAST_CHANGE . 
' AS p_' . self::PROGRESS_FIELD_LAST_CHANGE
   416             . 
', pgs.' . self::PROGRESS_FIELD_LAST_CHANGE_BY . 
' AS p_' . self::PROGRESS_FIELD_LAST_CHANGE_BY
   417             . 
',' . self::PROGRESS_FIELD_COMPLETION_DATE
   418             . 
',' . self::PROGRESS_FIELD_DEADLINE
   419             . 
',' . self::PROGRESS_FIELD_VQ_DATE
   420             . 
',' . self::PROGRESS_FIELD_INVALIDATED
   421             . 
',' . self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL
   422             . 
',' . self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE
   423             . 
',' . self::PROGRESS_FIELD_IS_INDIVIDUAL
   425             . 
', ' . implode(
', ', $user_fields_without_udf)
   427             . 
' FROM ' . self::ASSIGNMENT_TABLE . 
' ass '   428             . 
' JOIN ' . self::PROGRESS_TABLE . 
' pgs '   429             . 
' ON ass.' . self::ASSIGNMENT_FIELD_ID . 
' = pgs.' . self::PROGRESS_FIELD_ASSIGNMENT_ID
   432             . 
' JOIN usr_data memberdata ON ass.usr_id = memberdata.usr_id '   434             . 
' WHERE TRUE AND ';
   435         $q = 
$q . implode(
' AND ', $filter);
   436         $q = 
$q . 
' ORDER BY assignment_id, ass.usr_id';
   438         $res = $this->db->query(
$q);
   444         return $this->db->nextId(self::ASSIGNMENT_TABLE);
   450         return $this->db->numRows(
$res);
   460         while ($row = $this->db->fetchAssoc(
$res)) {
   461             if ($row[self::ASSIGNMENT_FIELD_ID] !== $current_ass) {
   462                 $current_ass = $row[self::ASSIGNMENT_FIELD_ID];
   463                 if (!is_null($ass)) {
   476         $q = 
'SELECT * FROM ' . self::PROGRESS_TABLE
   477             . 
' WHERE ' . self::PROGRESS_FIELD_ASSIGNMENT_ID . 
' = ' . $assignment_id;
   478         $res = $this->db->query(
$q);
   479         while ($row = $this->db->fetchAssoc(
$res)) {
   488             (
int) $row[self::ASSIGNMENT_FIELD_ID],
   489             (
int) $row[self::ASSIGNMENT_FIELD_USR_ID]
   492             ->withEvents($this->events)
   494                 (
int) $row[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY],
   495                 \DateTimeImmutable::createFromFormat(
   497                     $row[self::ASSIGNMENT_FIELD_LAST_CHANGE]
   501                 (
int) $row[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID],
   502                 $row[self::ASSIGNMENT_FIELD_RESTART_DATE] ?
   506             ->withManuallyAssigned((
bool) $row[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED]);
   509         $root_pgs_id = (
int) $row[self::ASSIGNMENT_FIELD_ROOT_PRG_ID];
   515             ->withProgressTree($pgs)
   516             ->withUserInformation($user_information);
   522         $children = array_filter(
   523             $this->tree->getChilds($this->getRefIdFor($node_obj_id)),
   524             fn(
$c) => in_array(
$c[
'type'], [
'prg', 
'prgr']),
   526         $children = array_map(
   532         foreach ($children as $child_obj_id) {
   536         if (!array_key_exists($node_obj_id, $this->progresses)) {
   539             $pgs = $this->progresses[$node_obj_id];
   541         $pgs->setSubnodes($pgss);
   548         if (
count($refs) < 1) {
   549             throw new ilException(
"Could not find ref_id for programme with obj_id $obj_id");
   551         return (
int) array_shift($refs);
   561             (
int) $row[self::PROGRESS_FIELD_PRG_ID],
   562             (
int) $row[self::PROGRESS_FIELD_STATUS]
   566             ->withAmountOfPoints((
int) $row[self::PROGRESS_FIELD_POINTS])
   567             ->withCurrentAmountOfPoints((
int) $row[self::PROGRESS_FIELD_POINTS_CUR])
   568             ->withAssignmentDate(
   569                 $row[self::PROGRESS_FIELD_ASSIGNMENT_DATE] ?
   574                 $row[self::PROGRESS_FIELD_DEADLINE] ?
   579                 (
int) $row[self::PROGRESS_FIELD_COMPLETION_BY],
   580                 $row[self::PROGRESS_FIELD_COMPLETION_DATE] ?
   585                 (
int) $row[self::PROGRESS_FIELD_LAST_CHANGE_BY],
   586                 $row[self::PROGRESS_FIELD_LAST_CHANGE] ?
   590             ->withValidityOfQualification(
   591                 $row[self::PROGRESS_FIELD_VQ_DATE] ?
   595             ->withIndividualModifications((
bool) $row[self::PROGRESS_FIELD_IS_INDIVIDUAL])
   596             ->withInvalidated((
bool) $row[self::PROGRESS_FIELD_INVALIDATED]);
   607         $orgus = array_values($orgu_repo->findAllUserAssingmentsByUserIds([$usr_id]));
   609             $orgu_ref_ids = array_map(
   610                 fn($orgu_assignment) => $orgu_assignment->getOrguId(),
   618         return implode(
', ', $orgus);
   624         $user_data_values = [];
   625         foreach ($this->user_data_fields as $field) {
   628                     $user_data_values[$field] = (bool) $row[$field];
   632                     $user_data_values[$field] = $this->
interimOrguLookup((
int) $row[self::ASSIGNMENT_FIELD_USR_ID]);
   634                 case str_starts_with($field, 
'udf_'):
   635                     $udf_field_id = str_replace(
'udf_', 
'f_', $field);
   636                     $user_data_values[$field] = $udf_data->get($udf_field_id);
   639                     $user_data_values[$field] = $row[$field];
   650             self::ASSIGNMENT_TABLE,
   652                 self::ASSIGNMENT_FIELD_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_ID]]
   653                 , self::ASSIGNMENT_FIELD_USR_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_USR_ID]]
   654                 , self::ASSIGNMENT_FIELD_ROOT_PRG_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_ROOT_PRG_ID]]
   655                 , self::ASSIGNMENT_FIELD_LAST_CHANGE => [
'text', $row[self::ASSIGNMENT_FIELD_LAST_CHANGE]]
   656                 , self::ASSIGNMENT_FIELD_LAST_CHANGE_BY => [
'integer', $row[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY]]
   657                 , self::ASSIGNMENT_FIELD_RESTART_DATE => [
'timestamp', $row[self::ASSIGNMENT_FIELD_RESTART_DATE]]
   658                 , self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID => [
'integer', $row[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID]]
   659                 , self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED => [
'integer', $row[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED]]
   666         $q = 
'UPDATE ' . self::ASSIGNMENT_TABLE
   668             . 
' ' . self::ASSIGNMENT_FIELD_USR_ID . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_USR_ID], 
'integer')
   669             . 
' ,' . self::ASSIGNMENT_FIELD_ROOT_PRG_ID . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_ROOT_PRG_ID], 
'integer')
   670             . 
' ,' . self::ASSIGNMENT_FIELD_LAST_CHANGE . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_LAST_CHANGE], 
'text')
   671             . 
' ,' . self::ASSIGNMENT_FIELD_LAST_CHANGE_BY . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_LAST_CHANGE_BY], 
'integer')
   672             . 
' ,' . self::ASSIGNMENT_FIELD_RESTART_DATE . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_RESTART_DATE], 
'timestamp')
   673             . 
' ,' . self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_RESTARTED_ASSIGNMENT_ID], 
'integer')
   674             . 
' ,' . self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_MANUALLY_ASSIGNED], 
'integer')
   675             . 
' WHERE ' . self::ASSIGNMENT_FIELD_ID . 
' = ' . $this->db->quote($values[self::ASSIGNMENT_FIELD_ID], 
'integer');
   676         $this->db->manipulate(
$q);
   694         $q = 
'INSERT INTO ' . self::PROGRESS_TABLE
   696             . self::PROGRESS_FIELD_ASSIGNMENT_ID . 
','   697             . self::PROGRESS_FIELD_USR_ID . 
','   698             . self::PROGRESS_FIELD_PRG_ID . 
','   700             . self::PROGRESS_FIELD_STATUS . 
','   701             . self::PROGRESS_FIELD_POINTS . 
','   702             . self::PROGRESS_FIELD_POINTS_CUR . 
','   703             . self::PROGRESS_FIELD_COMPLETION_BY . 
','   704             . self::PROGRESS_FIELD_LAST_CHANGE_BY . 
','   705             . self::PROGRESS_FIELD_LAST_CHANGE . 
','   706             . self::PROGRESS_FIELD_ASSIGNMENT_DATE . 
','   707             . self::PROGRESS_FIELD_COMPLETION_DATE . 
','   708             . self::PROGRESS_FIELD_DEADLINE . 
','   709             . self::PROGRESS_FIELD_VQ_DATE . 
','   710             . self::PROGRESS_FIELD_INVALIDATED . 
','   711             . self::PROGRESS_FIELD_IS_INDIVIDUAL
   713             . PHP_EOL . 
') VALUES (' . PHP_EOL
   724             . 
' ,' . $assign_date
   725             . 
' ,' . $completion_date
   728             . 
' ,' . $invalidated
   731             . 
'ON DUPLICATE KEY UPDATE' . PHP_EOL
   732             . self::PROGRESS_FIELD_STATUS . 
'=' . $pgs->
getStatus() . 
','   735             . self::PROGRESS_FIELD_COMPLETION_BY . 
'=' . $completion . 
','   736             . self::PROGRESS_FIELD_LAST_CHANGE_BY . 
'=' . $pgs->
getLastChangeBy() . 
','   737             . self::PROGRESS_FIELD_LAST_CHANGE . 
'=' . $lastchange . 
','   738             . self::PROGRESS_FIELD_ASSIGNMENT_DATE . 
'=' . $assign_date . 
','   739             . self::PROGRESS_FIELD_COMPLETION_DATE . 
'=' . $completion_date . 
','   740             . self::PROGRESS_FIELD_DEADLINE . 
'=' . $deadline . 
','   741             . self::PROGRESS_FIELD_VQ_DATE . 
'=' . $validity . 
','   742             . self::PROGRESS_FIELD_INVALIDATED . 
'=' . $invalidated . 
','   743             . self::PROGRESS_FIELD_IS_INDIVIDUAL . 
'=' . $individual
   745         $this->db->manipulate(
$q);
   751             self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
   752             self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
   756             self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE => [
   761         $this->db->update(self::PROGRESS_TABLE, $values, $where);
   767             self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
   768             self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
   772             self::PROGRESS_FIELD_MAIL_SENT_WILLEXPIRE => [
'null', null]
   774         $this->db->update(self::PROGRESS_TABLE, $values, $where);
   780             self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
   781             self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
   785             self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL => [
   790         $this->db->update(self::PROGRESS_TABLE, $values, $where);
   796             self::PROGRESS_FIELD_ASSIGNMENT_ID => [
'integer', $ass->
getId()],
   797             self::PROGRESS_FIELD_PRG_ID => [
'integer', $ass->
getRootId()]
   801             self::PROGRESS_FIELD_MAIL_SENT_RISKYTOFAIL => [
'null', null]
   803         $this->db->update(self::PROGRESS_TABLE, $values, $where);
   809         if ($assignments === []) {
   817         $assignments = array_reverse($assignments);
   818         return current($assignments);
   824         if ($assignments === []) {
   828         $now = new \DateTimeImmutable();
   829         $valid = array_filter($assignments, fn($ass) => $ass->getProgressTree()->hasValidQualification($now));
   834         $unlimited = array_filter(
$valid, fn($ass) => $ass->getProgressTree()->getValidityOfQualification() === null);
   835         if ($unlimited !== []) {
   841             $unlimited = array_reverse($unlimited);
   842             return current($unlimited);
   850         $valid = array_reverse($valid);
   851         return current($valid);
   856         $query = 
'SELECT assignment_id FROM (' . PHP_EOL
   857             . 
'SELECT usr_id, assignment_id, ROW_NUMBER() OVER (' . PHP_EOL
   858                 . 
'PARTITION BY usr_id' . PHP_EOL
   859                 . 
'ORDER BY' . PHP_EOL
   860                 . 
'CASE WHEN vq_date IS NULL THEN 1 ELSE 0 END DESC,' . PHP_EOL
   861                 . 
'vq_date DESC,' . PHP_EOL
   862                 . 
'completion_date DESC' . PHP_EOL
   863             . 
') AS row_numbers' . PHP_EOL
   864         . 
'FROM prg_usr_progress' . PHP_EOL
   865         . 
'WHERE prg_id = ' . $this->db->quote($prg_obj_id, 
'integer') . PHP_EOL
   866         . 
'AND ' . $this->db->in(
'usr_id', $usr_id, 
false, 
'integer') . PHP_EOL
   868         . 
') ranked ' . PHP_EOL
   869         . 
'WHERE row_numbers = 1';
   871         $res = $this->db->query($query);
   873             fn(
$r) => 
$r[
'assignment_id'],
   874             $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)
 
const ASSIGNMENT_FIELD_RESTART_DATE
 
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins 
 
$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