1<?
php declare(strict_types = 1);
119 public function __construct($a_id = 0,
bool $a_call_by_reference =
true)
124 $this->type_repository =
$dic[
'model.Type.ilStudyProgrammeTypeRepository'];
125 $this->auto_categories_repository =
$dic[
'model.AutoCategories.ilStudyProgrammeAutoCategoriesRepository'];
126 $this->auto_memberships_repository =
$dic[
'model.AutoMemberships.ilStudyProgrammeAutoMembershipsRepository'];
127 $this->membersourcereader_factory =
$dic[
'model.AutoMemberships.ilStudyProgrammeMembershipSourceReaderFactory'];
129 $this->settings_repository =
$dic[
'model.Settings.ilStudyProgrammeSettingsRepository'];
130 $this->assignment_repository =
$dic[
'model.Assignment.ilStudyProgrammeAssignmentRepository'];
131 $this->progress_repository =
$dic[
'model.Progress.ilStudyProgrammeProgressRepository'];
133 $this->events =
$dic[
'ilStudyProgrammeEvents'];
144 $this->webdir =
$DIC->filesystem()->web();
147 $this->db =
$DIC[
'ilDB'];
148 $this->plugin_admin =
$DIC[
'ilPluginAdmin'];
149 $this->lng =
$DIC[
'lng'];
154 $this->custom_icon_factory =
$DIC[
'object.customicons.factory'];
161 if (self::$study_programme_cache ===
null) {
172 $this->parent =
false;
180 $this->children =
null;
188 $this->lp_children =
null;
194 if (count($refs) < 1) {
195 throw new ilException(
"Could not find ref_id for programme with obj_id $obj_id");
197 return (
int) array_shift($refs);
212 if (self::$study_programme_cache ===
null) {
215 return self::$study_programme_cache->getInstanceByRefId($a_ref_id);
236 return $this->logger;
248 $obj->createReference();
249 self::$study_programme_cache->addInstance($obj);
264 if ($settings->
getObjId() !== (
int) $this->getId()) {
265 throw new Exception(
"The given settings-object does not belong to this programme", 1);
295 $id = (int) parent::create();
307 $type_settings = $this->
getSettings()->getTypeSettings();
309 if ($type_settings->getTypeId()) {
313 $this->type_repository->getAssignedAMDRecordIdsByType($type_settings->getTypeId())
326 public function delete() :
bool
329 if (!parent::delete()) {
336 $this->auto_categories_repository->deleteFor((
int) $this->
getId());
344 $this->events->raise(
'delete', [
'object' => $this,
'obj_id' => $this->
getId()]);
350 $sub_type_id = $this->
getSettings()->getTypeSettings()->getTypeId();
352 $type = $this->type_repository->getType($sub_type_id);
355 return !is_null(
$type) && count($this->type_repository->getAssignedAMDRecordIdsByType(
$type->getId(),
true)) > 0;
375 return $this->
getSettings()->getAssessmentSettings()->getPoints();
385 $settings = $this->
getSettings()->getAssessmentSettings()
386 ->withPoints($a_points);
387 $this->setAssessmentSettings($settings);
414 $this->settings_repository->update(
419 $this->settings_repository->update(
423 $this->settings_repository->update(
432 return $this->
getSettings()->getAssessmentSettings()->getStatus();
442 $settings = $this->
getSettings()->getAssessmentSettings()
443 ->withStatus($a_status);
444 $this->setAssessmentSettings($settings);
461 $type_settings = $this->
getSettings()->getTypeSettings();
462 if (!in_array($type_settings->getTypeId(), array(
"-",
"0"))) {
463 $subtype_id = $type_settings->getTypeId();
464 return $this->type_repository->getType($subtype_id);
483 public static function getAllChildren(
int $a_ref_id,
bool $include_references =
false)
487 $root_id = $root->getId();
490 if ($prg->
getId() == $root_id) {
494 }, $include_references);
503 if ($prg->
getId() == $this->getId()) {
520 public function getChildren(
bool $include_references =
false) : array
524 if ($this->children ===
null) {
525 $ref_ids = $this->tree->getChildsByType($this->
getRefId(),
"prg");
529 $ref_ids = $sorting->sortItems(array(
'prg' => $ref_ids));
530 $ref_ids = $ref_ids[
'prg'];
532 $this->children = array_map(
function ($node_data) {
537 if ($include_references && $this->reference_children ===
null) {
538 $this->reference_children = [];
539 $ref_child_ref_ids = $this->tree->getChildsByType($this->
getRefId(),
"prgr");
540 foreach ($this->children as $prg) {
543 $this->tree->getChildsByType($prg->getRefId(),
"prgr"),
551 return $data[
'child'];
553 array_filter($ref_child_ref_ids,
function (
$data) {
554 return $data[
"deleted"] ===
null;
559 $this->reference_children[] =
563 return $include_references ?
564 array_merge($this->children, $this->reference_children) :
576 if ($this->parent ===
false) {
578 $parent_data = $this->tree->getParentNodeData($this->
getRefId());
579 if ($parent_data[
"type"] !=
"prg") {
580 $this->parent =
null;
602 function ($prg_ref) use (
$tree) {
603 return !
$tree->isDeleted((
int) $prg_ref->getRefId());
618 public function getParents(
bool $include_references =
false) : array
622 $queque = [$current];
623 while ($element = array_shift($queque)) {
624 $parent = $element->getParent();
625 if (
$parent ===
null || $include_references) {
627 if ($this->tree->isDeleted($reference->getRefId())) {
630 $r_parent = $reference->getParent();
631 if (is_null($r_parent)) {
634 array_push($queque, $r_parent);
635 $parents[] = $r_parent;
642 return array_reverse($parents);
650 public function hasChildren(
bool $include_references =
false) : bool
663 return count($this->
getChildren($include_references));
676 while ($cur = $cur->getParent()) {
691 if (count($parents) < 1) {
707 if ($this->lp_children ===
null) {
708 $this->lp_children = array();
710 $ref_ids = $this->tree->getChildsByType($this->
getRefId(),
"crsr");
714 $ref_ids = $sorting->sortItems(array(
'crs_ref' => $ref_ids));
715 $ref_ids = $ref_ids[
'crs_ref'];
718 $lp_obj = $this->object_factory->getInstanceByRefId($node_data[
"child"]);
721 return ($lp_obj instanceof $this) ?
null : $lp_obj;
737 return array_map(
function ($child) {
738 return $child->getId();
762 if (!$this->tree->isInTree($this->getRefId())) {
782 if ($fun($this) !==
false) {
783 foreach ($this->
getChildren($include_references) as $child) {
784 $child->applyToSubTreeNodes($fun, $include_references);
796 $node_data = $this->tree->getNodeData($this->
getRefId());
797 $crsrs = $this->tree->getSubTree($node_data,
true,
"crsr");
799 $completed_crss = array();
800 foreach ($crsrs as $ref) {
807 if ($containing_prg->isActive()) {
808 $completed_crss[] = [
810 ,
"prg_ref_id" => $ref[
"parent"]
811 ,
"crsr_ref_id" => $ref[
"child"]
812 ,
"crsr_id" => $ref[
"obj_id"]
819 return $completed_crss;
844 if ($this->tree->isInTree($a_prg->
getRefId())) {
869 $this->settings_repository->update(
889 $res = parent::putInTree($a_parent_ref);
893 $par->nodeInserted($this);
910 if ($a_prg->
getParent()->getId() !== $this->getId()) {
919 $node_data = $this->tree->getNodeData($a_prg->
getRefId());
920 $this->tree->deleteTree($node_data);
937 if ($progress->getLastChangeBy() !==
null) {
966 $this->settings_repository->update(
984 if (self::getParentId($a_leaf) !== $this->
getId()) {
988 $node_data = $this->tree->getNodeData($a_leaf->
getRefId());
989 $this->tree->deleteTree($node_data);
1022 $parent->clearChildrenCache();
1023 $parent->clearLPChildrenCache();
1048 $this->members_cache =
null;
1052 "ilObjStudyProgramme::assignUser: Can't assign user to program '"
1053 . $this->
getId() .
"', since it's not in active status."
1057 if (is_null($acting_usr_id)) {
1061 $ass = $this->assignment_repository->createFor($this->
getId(), $usr_id, $acting_usr_id);
1072 $this->events->userAssigned($ass);
1085 $this->members_cache =
null;
1086 if ($assignment->
getRootId() != $this->getId()) {
1088 "ilObjStudyProgramme::removeAssignment: Assignment '"
1089 . $assignment->
getId() .
"' does not belong to study "
1090 .
"program '" . $this->getId() .
"'."
1094 $this->assignment_repository->delete($assignment);
1096 $affected_node_ids = $this->progress_repository->deleteForAssignmentId($assignment->
getId());
1097 foreach ($affected_node_ids as $node_obj_id) {
1101 $this->events->userDeassigned($assignment);
1133 foreach ($prg_ids as $prg_id) {
1134 $assignments = array_merge(
1136 $this->assignment_repository->getByUsrIdAndPrgId($a_user_id, $prg_id)
1139 usort($assignments,
function ($a_one, $a_other) {
1141 $a_one->getLastChange()->format(
'Y-m-d'),
1142 $a_other->getLastChange()->format(
'Y-m-d')
1148 }, array_values($assignments));
1172 $usr_ids[] = $progress->getUserId();
1174 return array_unique($usr_ids);
1181 if (!$this->members_cache) {
1182 $this->members_cache = array_map(
1183 function ($assignment) {
1184 return $assignment->getUserId();
1186 $this->assignment_repository->getByPrgId($this->
getId())
1205 $this->members_cache =
null;
1207 foreach ($assignments as $ass) {
1208 $ass->updateFromProgram();
1220 return $this->assignment_repository->getByUsrIdAndPrgId($usr_id, $this->
getId());
1241 return $this->progress_repository->createFor($this->
getSettings(), $ass, $acting_user);
1252 return $this->progress_repository->getByPrgIdAndUserId($this->
getId(), $a_user_id);
1273 $assignment_ids_here = array_unique(
1275 function ($progress) {
1276 return $progress->getAssignmentId();
1283 foreach ($assignment_ids_here as $ass_id) {
1284 foreach ($nodes_below as $node) {
1285 $node_id = $node->getId();
1296 $logger->log(
"Added progress for assingnment $ass_id at node $node_id.");
1298 $node->addMissingProgresses();
1310 return $this->progress_repository->getByPrgId($this->
getId());
1327 if ($progress->isRelevant()) {
1343 if ($progress->isRelevant()) {
1344 $returns[] = $progress->getUserId();
1347 return array_unique($returns);
1359 if ($progress->isSuccessful() && !$progress->isSuccessfulExpired()) {
1360 $returns[] = $progress->getUserId();
1363 return array_unique($returns);
1375 if ($progress->isFailed() || $progress->isSuccessfulExpired()) {
1376 $returns[] = $progress->getUserId();
1393 if ($progress->isRelevant() && !$progress->isSuccessful()) {
1394 $returns[] = $progress->getUserId();
1397 return array_unique($returns);
1411 return $this->auto_categories_repository->getFor($this->
getId());
1426 $ac = $this->auto_categories_repository->create(
1430 $this->auto_categories_repository->update($ac);
1439 $this->auto_categories_repository->delete($this->
getId(), $category_ids);
1447 $this->auto_categories_repository->deleteFor($this->
getId());
1455 foreach (self::getProgrammesMonitoringCategory($cat_ref_id) as $prg) {
1458 $course_ref->setTargetRefId($crs_ref_id);
1459 $course_ref->create();
1460 $course_ref->createReference();
1461 $course_ref->putInTree($prg->getRefId());
1462 $course_ref->setPermissions($crs_ref_id);
1464 $course_ref->update();
1467 $lp->setMode($lp::LP_MODE_COURSE_REFERENCE);
1479 foreach (self::getProgrammesMonitoringCategory($cat_ref_id) as $prg) {
1480 foreach ($prg->getLPChildren() as $child) {
1481 if ((
int) $child->getTargetRefId() === $crs_ref_id) {
1495 $programmes = array_map(
1497 $prg_obj_id = (int) array_shift(array_values($rec));
1500 if ($prg->isAutoContentApplicable()) {
1504 $db::getProgrammesFor($cat_ref_id)
1517 $valid_status = in_array(
1530 return $valid_status && $crslnk_allowed;
1544 return $this->auto_memberships_repository->getFor($this->
getId());
1552 $ams = $this->auto_memberships_repository->create($this->
getId(), $type, $src_id,
false);
1553 $this->auto_memberships_repository->update($ams);
1561 $this->auto_memberships_repository->delete($this->
getId(), $type, $src_id);
1569 $this->auto_memberships_repository->deleteFor($this->
getId());
1577 $ams = $this->auto_memberships_repository->create($this->
getId(), $type, $src_id,
false);
1578 $this->auto_memberships_repository->update($ams);
1590 foreach ($member_ids as $usr_id) {
1596 $ams = $this->auto_memberships_repository->create($this->
getId(), $type, $src_id,
true);
1597 $this->auto_memberships_repository->update($ams);
1607 $source_reader = $this->membersourcereader_factory->getReaderFor($src_type, $src_id);
1608 return $source_reader->getMemberIds();
1619 $programmes = array_map(
1621 $prg_obj_id = (int) array_shift(array_values($rec));
1626 $db::getProgrammesFor($src_type, $src_id)
1633 foreach (self::getProgrammesMonitoringMemberSource($src_type, $src_id) as $prg) {
1634 if ($prg->isActive() &&
1635 !$prg->hasAssignmentsOfSingleProgramForUser($usr_id)) {
1637 $prg->assignUser($usr_id, $assigned_by);
1644 $now =
new DateTimeImmutable();
1645 foreach (self::getProgrammesMonitoringMemberSource($src_type, $src_id) as $prg) {
1646 foreach ($prg->getProgressesOf($usr_id) as $progress) {
1650 $assignments = $prg->getAssignmentsOfSingleProgramForUser($usr_id);
1651 $next_membership_source = $prg->getApplicableMembershipSourceForUser($usr_id, $src_type);
1653 foreach ($assignments as $assignment) {
1654 if (!is_null($next_membership_source) && $next_membership_source->isEnabled()) {
1655 $new_src_type = $next_membership_source->getSourceType();
1657 $assignment = $assignment->withLastChange($assigned_by, $now);
1658 $prg->assignment_repository->update($assignment);
1663 $prg->removeAssignment($user_assignment);
1676 $src_type = $ams->getSourceType();
1677 if ($src_type !== $exclude_type) {
1679 if (in_array($usr_id, $source_members)) {
1711 $prg_ids = array_map(
function ($par) {
1712 return $par->getId();
1714 $prg_ids[] = $this->
getId();
1727 $assignments = array_merge($this->assignment_repository->getByPrgId($prg_id), $assignments);
1738 return $assignments;
1749 if (
$type ==
"crsr") {
1766 $node_data =
$tree->getParentNodeData($a_ref_id);
1767 if ($node_data[
"type"] !==
"prg") {
1776 $now =
new DateTimeImmutable();
1777 foreach ($prg->getProgressesOf($a_user_id) as $progress) {
1778 $progress_deadline = $progress->getDeadline();
1780 (is_null($progress_deadline) || $progress_deadline >= $now)
1783 $prg->succeed($progress->getId(), $a_obj_id);
1797 $tree =
$DIC[
'tree'];
1798 if (!$tree->isInTree($a_object->
getRefId())) {
1802 $nd = $tree->getParentNodeData($a_object->
getRefId());
1803 return $nd[
"obj_id"];
1809 $customIcon = $this->custom_icon_factory->getByObjId($this->getId(), $this->getType());
1810 $subtype = $this->getSubType();
1813 && $this->webdir->has($subtype->getIconPath(
true))
1814 && $subtype->getIconPath(
true) != $subtype->getIconPath(
false)
1816 $icon = $subtype->getIconPath(
true);
1817 $customIcon->saveFromSourceFile($icon);
1819 $customIcon->remove();
1839 if ($a_ref_id ===
null) {
1840 return $a_subobjects;
1844 throw new ilException(
"Ref-Id '$a_ref_id' does not belong to a study programme object.");
1849 $mode = $parent->getLPMode();
1853 $possible_subobjects = $a_subobjects;
1856 $possible_subobjects = [
1857 "prg" => $a_subobjects[
"prg"],
1858 "prgr" => $a_subobjects[
"prgr"]
1862 $possible_subobjects = [
'crsr' => $a_subobjects[
'crsr']];
1865 throw new ilException(
"Undefined mode for study programme: '$mode'");
1868 if ($parent->hasAutomaticContentCategories()) {
1869 $possible_subobjects = array_filter(
1870 $possible_subobjects,
1871 function ($subtype) {
1872 return $subtype ===
'crsr';
1874 ARRAY_FILTER_USE_KEY
1877 return $possible_subobjects;
1884 $lng->loadLanguageModule(
"prg");
1885 $lng->loadLanguageModule(
"mail");
1889 $prg_should_send_mail = $prg->getSettings()->getAutoMailSettings()->getSendReAssignedMail();
1890 if (!$prg_should_send_mail) {
1891 $log->write(
"Send re assign mail is deactivated in study programme settings");
1895 $subject =
$lng->txt(
"re_assigned_mail_subject");
1899 $lng->txt(
"re_assigned_mail_body"),
1900 $lng->txt(
"mail_salutation_" . $gender),
1916 }
catch (Exception
$e) {
1927 $lng->loadLanguageModule(
"prg");
1928 $lng->loadLanguageModule(
"mail");
1932 $subject =
$lng->txt(
"invalidate_mail_subject");
1936 $lng->txt(
"invalidate_mail_body"),
1937 $lng->txt(
"mail_salutation_" . $gender),
1953 }
catch (Exception
$e) {
1965 $lng->loadLanguageModule(
"prg");
1966 $lng->loadLanguageModule(
"mail");
1969 $usr_progress = $usr_progress_db->get($progress_id);
1971 $prg_should_send_mail = $prg->getSettings()->getAutoMailSettings()
1972 ->getReminderNotRestartedByUserDays() > 0;
1974 if (!$prg_should_send_mail) {
1975 $log->write(
"Send info to re assign mail is deactivated in study programme settings");
1979 $subject =
$lng->txt(
"info_to_re_assign_mail_subject");
1983 $lng->txt(
"info_to_re_assign_mail_body"),
1984 $lng->txt(
"mail_salutation_" . $gender),
2000 }
catch (Exception
$e) {
2005 $usr_progress_db->sentExpiryInfoFor($usr_progress->getId());
2017 $lng->loadLanguageModule(
"prg");
2018 $lng->loadLanguageModule(
"mail");
2021 $usr_progress = $usr_progress_db->get($progress_id);
2023 $prg_should_send_mail = $prg->getSettings()->getAutoMailSettings()
2024 ->getProcessingEndsNotSuccessfulDays() > 0;
2026 if (!$prg_should_send_mail) {
2027 $log->write(
"Send risky to fail mail is deactivated in study programme settings");
2031 $subject =
$lng->txt(
"risky_to_fail_mail_subject");
2035 $lng->txt(
"risky_to_fail_mail_body"),
2036 $lng->txt(
"mail_salutation_" . $gender),
2052 }
catch (Exception
$e) {
2057 $usr_progress_db->sentRiskyToFailFor($usr_progress->getId());
2066 $children = $this->getChildren(
true);
2070 foreach ($children as $child) {
2071 $prgrs = $child->getProgressForAssignment($ass_id);
2072 if (!$prgrs->isSuccessful()) {
2075 $ids[] = [$child->getId(), $child->getRefId()];
2077 if (count($ids) > 0) {
2082 $children = $this->getTree()->getChildsByType($this->getRefId(),
"crsr");
2083 $usr_id = $this->getAssignmentRepository()->get($ass_id)->getUserId();
2084 foreach ($children as $child) {
2094 $ids[] = [$crs_id, $ref_id];
2104 list($obj_id, $ref_id) = $entry;
2107 $this->getIdsOfSuccessfulChildren($ass_id)
2113 return (
int) $this->ilUser->getId();
2116 protected function getNow() : DateTimeImmutable
2118 return new DateTimeImmutable();
2123 return $this->assignment_repository->get($progress->
getAssignmentId());
2128 return $this->settings_repository->get($progress->
getNodeId());
2134 $node_ref_id = self::getRefIdFor($node_obj_id);
2136 $prgs = $this->tree->getChildsByType($node_ref_id,
"prg");
2137 $prg_ids = array_map(
2139 return (
int)
$nd[
'obj_id'];
2145 $prg_refs = $this->tree->getChildsByType($node_ref_id,
"prgr");
2146 foreach ($prg_refs as $ref) {
2148 $prg_ref_ids[] = (int) $ref_obj->getReferencedObject()->getId();
2151 return array_merge($prg_ids, $prg_ref_ids);
2159 $children = $this->getObjIdsOfChildren($progress->getNodeId());
2160 $ass_id = $progress->getAssignmentId();
2163 foreach ($children as $child_obj_id) {
2164 $progress = $this->getProgressRepository()->getByPrgIdAndAssignmentId($child_obj_id, $ass_id);
2165 $ret[] = $this->getProgressRepository()->getByPrgIdAndAssignmentId($child_obj_id, $ass_id);
2175 $prg_ref_id = $this->getRefIdFor($progress->
getNodeId());
2176 $parent_node = $this->tree->getParentNodeData($prg_ref_id);
2177 $parent_prg_obj_id = (int) $parent_node[
"obj_id"];
2179 $parent_progress = $this->progress_repository->getByPrgIdAndAssignmentId(
2184 if (!$parent_progress) {
2189 $parent_node = $this->tree->getParentNodeData($ref_id_referencing);
2190 $parent_prg_obj_id = (int) $parent_node[
"obj_id"];
2192 $parent_progress = $this->progress_repository->getByPrgIdAndAssignmentId(
2196 if ($parent_progress) {
2197 return $parent_progress;
2203 return $parent_progress;
2210 foreach ($this->getChildrenProgress($progress) as $child_progress) {
2211 if (!is_null($child_progress) && $child_progress->isRelevant()) {
2212 $sum += $child_progress->getAmountOfPoints();
2221 $children = $this->getChildrenProgress($progress);
2222 foreach ($children as $child_progress) {
2223 if (!is_null($child_progress) && $child_progress->isSuccessful()) {
2224 $sum += $child_progress->getAmountOfPoints();
2232 if (is_null($node_obj_id)) {
2233 $node_obj_id = $this->getId();
2240 $parent_progress = $this->getParentProgress($progress);
2241 if (is_null($parent_progress)) {
2244 $parent_progress = $this->recalculateProgressStatus($parent_progress);
2245 $this->getProgressRepository()->update($parent_progress);
2246 return $this->updateParentProgress($parent_progress);
2254 $node_settings = $this->getSettingsRepository()->get($progress->
getNodeId());
2255 $completion_mode = $node_settings->getLPMode();
2264 $achieved_points = 0;
2266 $node_ref = self::getRefIdFor($progress->
getNodeId());
2267 $children = $this->tree->getChildsByType($node_ref,
"crsr");
2268 foreach ($children as $child) {
2282 $achieved_points = $this->getAchievedPointsOfChildren($progress);
2286 $successful = ($achieved_points >= $required_points);
2289 $progress = $progress
2291 ->withCompletion(
null,
new DateTimeImmutable());
2294 $this->events->userSuccessful($progress);
2298 $progress = $progress
2300 ->withCompletion(
null,
null)
2301 ->withValidityOfQualification(
null);
2310 $today = $this->getNow();
2314 if (is_null($acting_usr_id)) {
2315 $acting_usr_id = $this->getLoggedInUserId();
2321 if (!is_null($deadline)
2324 $progress = $progress->
markFailed($this->getNow(), $acting_usr_id);
2329 if (is_null($deadline)
2332 $progress = $progress->
markNotFailed($this->getNow(), $acting_usr_id);
2345 $progress = $this->getProgressRepository()->
get($progress_id);
2346 $new_status = $progress::STATUS_ACCREDITED;
2348 if (!$progress->isRelevant()) {
2349 $err_collection->
add(
false,
'will_not_modify_irrelevant_progress', $this->getProgressIdString($progress));
2352 if ($progress->getStatus() === $new_status) {
2353 $err_collection->
add(
false,
'status_unchanged', $this->getProgressIdString($progress));
2356 if (!$progress->isTransitionAllowedTo($new_status)) {
2357 $err_collection->
add(
false,
'status_transition_not_allowed', $this->getProgressIdString($progress));
2361 $progress = $progress
2362 ->markAccredited($this->getNow(), $acting_usr_id)
2363 ->withCurrentAmountOfPoints($progress->getAmountOfPoints());
2365 if (!$progress->getValidityOfQualification()) {
2366 $progress = $this->updateProgressValidityFromSettings($progress);
2369 $this->events->userSuccessful($progress);
2371 $this->getProgressRepository()->update($progress);
2372 $this->refreshLPStatus($progress->getUserId());
2373 $this->updateParentProgress($progress);
2374 $err_collection->
add(
true,
'status_changed', $this->getProgressIdString($progress));
2382 $progress = $this->getProgressRepository()->
get($progress_id);
2383 $new_status = $progress::STATUS_IN_PROGRESS;
2385 if (!$progress->isRelevant()) {
2386 $err_collection->
add(
false,
'will_not_modify_irrelevant_progress', $this->getProgressIdString($progress));
2389 if ($progress->getStatus() === $new_status) {
2390 $err_collection->
add(
false,
'status_unchanged', $this->getProgressIdString($progress));
2393 if (!$progress->isTransitionAllowedTo($new_status)
2395 || $progress->getStatus() === $progress::STATUS_COMPLETED
2397 $err_collection->
add(
false,
'status_transition_not_allowed', $this->getProgressIdString($progress));
2401 $progress = $progress
2402 ->unmarkAccredited($this->getNow(), $acting_usr_id);
2404 $achieved_points = $this->getAchievedPointsOfChildren($progress);
2405 $progress = $progress->withCurrentAmountOfPoints($achieved_points);
2407 $progress = $this->applyProgressDeadline($progress);
2409 $this->getProgressRepository()->update($progress);
2410 $this->refreshLPStatus($progress->getUserId());
2411 $this->updateParentProgress($progress);
2412 $err_collection->
add(
true,
'status_changed', $this->getProgressIdString($progress));
2415 public function markFailed(
int $progress_id,
int $acting_usr_id) : void
2417 $progress = $this->getProgressRepository()->get($progress_id);
2418 if (!$progress->isRelevant()) {
2421 $progress = $progress->markFailed($this->getNow(), $acting_usr_id);
2423 $this->getProgressRepository()->update($progress);
2424 $this->refreshLPStatus($progress->getUserId());
2425 $this->updateParentProgress($progress);
2430 if (!$progress->isRelevant()) {
2433 $progress = $this->getProgressRepository()->get($progress_id)
2434 ->markNotFailed($this->getNow(), $acting_usr_id);
2436 $this->getProgressRepository()->update($progress);
2437 $this->refreshLPStatus($progress->getUserId());
2438 $this->updateParentProgress($progress);
2446 $progress = $this->getProgressRepository()->
get($progress_id);
2447 if (!$progress->isRelevant()) {
2448 $err_collection->
add(
false,
'will_not_modify_irrelevant_progress', $this->getProgressIdString($progress));
2451 if (is_null($this->getParentProgress($progress))) {
2452 $err_collection->
add(
false,
'will_not_set_top_progress_to_irrelevant', $this->getProgressIdString($progress));
2456 $err_collection->
add(
false,
'will_not_set_completed_progress_to_irrelevant_', $this->getProgressIdString($progress));
2460 $progress = $progress
2461 ->markNotRelevant($this->getNow(), $acting_usr_id);
2463 $this->getProgressRepository()->update($progress);
2464 $this->refreshLPStatus($progress->getUserId());
2465 $this->updateParentProgress($progress);
2466 $err_collection->
add(
true,
'set_to_irrelevant', $this->getProgressIdString($progress));
2474 $progress = $this->getProgressRepository()->
get($progress_id);
2475 if ($progress->isRelevant()) {
2476 $err_collection->
add(
false,
'will_not_modify_relevant_progress', $this->getProgressIdString($progress));
2480 $progress = $progress
2481 ->markRelevant($this->getNow(), $acting_usr_id);
2483 $progress = $this->recalculateProgressStatus($progress);
2485 $this->getProgressRepository()->update($progress);
2486 $this->refreshLPStatus($progress->getUserId());
2487 $this->updateParentProgress($progress);
2488 $err_collection->
add(
true,
'set_to_relevant', $this->getProgressIdString($progress));
2493 $progress = $this->getProgressRepository()->get($progress_id)
2496 $this->getProgressRepository()->update($progress);
2497 $this->refreshLPStatus($progress->getUserId());
2498 $this->updateParentProgress($progress);
2501 public function succeed(
int $progress_id,
int $triggering_obj_id) : void
2503 $progress = $this->getProgressRepository()->get($progress_id)
2504 ->succeed($this->getNow(), $triggering_obj_id);
2506 $achieved_points = $progress->getAmountOfPoints();
2507 $progress = $progress->withCurrentAmountOfPoints($achieved_points);
2508 $progress = $this->updateProgressValidityFromSettings($progress);
2510 $this->getProgressRepository()->update($progress);
2512 $this->refreshLPStatus($progress->getUserId());
2513 $this->updateParentProgress($progress);
2520 ?DateTimeImmutable $deadline
2522 $progress = $this->getProgressRepository()->
get($progress_id);
2524 if (!$progress->isRelevant()) {
2525 $err_collection->
add(
false,
'will_not_modify_irrelevant_progress', $this->getProgressIdString($progress));
2528 if ($progress->isSuccessful()) {
2529 $err_collection->
add(
false,
'will_not_modify_deadline_on_successful_progress', $this->getProgressIdString($progress));
2533 $progress = $progress
2534 ->withDeadline($deadline)
2535 ->withLastChange($acting_usr_id, $this->getNow())
2536 ->withIndividualModifications(
true);
2538 $progress = $this->applyProgressDeadline($progress, $acting_usr_id);
2540 $this->getProgressRepository()->update($progress);
2541 $this->refreshLPStatus($progress->getUserId());
2542 $this->updateParentProgress($progress);
2543 $err_collection->
add(
true,
'deadline_updated', $this->getProgressIdString($progress));
2550 ?DateTimeImmutable $validity
2552 $progress = $this->getProgressRepository()->
get($progress_id);
2554 if (!$progress->isRelevant()) {
2555 $err_collection->
add(
false,
'will_not_modify_irrelevant_progress', $this->getProgressIdString($progress));
2558 if (!$progress->isSuccessful()) {
2559 $err_collection->
add(
false,
'will_not_modify_validity_on_non_successful_progress', $this->getProgressIdString($progress));
2563 $progress = $progress
2564 ->withValidityOfQualification($validity)
2565 ->withLastChange($acting_usr_id, $this->getNow())
2566 ->withIndividualModifications(
true);
2568 $this->getProgressRepository()->update($progress);
2569 $err_collection->
add(
true,
'validity_updated', $this->getProgressIdString($progress));
2572 $this->refreshLPStatus($progress->getUserId());
2581 $progress = $this->getProgressRepository()->
get($progress_id);
2583 if (!$progress->isRelevant()) {
2584 $err_collection->
add(
false,
'will_not_modify_irrelevant_progress', $this->getProgressIdString($progress));
2587 if ($progress->isSuccessful()) {
2588 $err_collection->
add(
false,
'will_not_modify_successful_progress', $this->getProgressIdString($progress));
2592 $progress = $progress
2593 ->withAmountOfPoints($points)
2594 ->withLastChange($acting_usr_id, $this->getNow())
2595 ->withIndividualModifications(
true);
2597 $progress = $this->recalculateProgressStatus($progress);
2599 $this->getProgressRepository()->update($progress);
2600 $err_collection->
add(
true,
'required_points_updated', $this->getProgressIdString($progress));
2601 $this->refreshLPStatus($progress->getUserId());
2602 $this->updateParentProgress($progress);
2610 $progress = $this->getProgressRepository()->
get($progress_id);
2611 $assignment_id = $progress->getAssignmentId();
2612 $progresses = $this->getProgressRepository()->getByAssignmentId($assignment_id);
2615 foreach ($progresses as $progress) {
2617 $node = $this->getPrgInstanceByObjId($progress->getNodeId());
2618 $progress = $node->updateProgressRelevanceFromSettings($progress);
2619 $progress = $node->resetProgressToSettings($progress, $acting_usr_id);
2620 $this->getProgressRepository()->update($progress);
2622 if (!$node->hasChildren(
true)) {
2623 $leafs[] = [$node, $progress];
2627 foreach ($leafs as $leaf) {
2628 list($node, $progress) = $leaf;
2629 $progress = $this->recalculateProgressStatus($progress);
2630 $progress = $this->applyProgressDeadline($progress);
2631 $this->getProgressRepository()->update($progress);
2632 $this->refreshLPStatus($progress->getUserId(), (
int) $node->getId());
2633 $this->updateParentProgress($progress);
2641 if ($progress->isRelevant()) {
2642 $progress = $this->updateProgressValidityFromSettings($progress);
2643 $progress = $this->updateProgressDeadlineFromSettings($progress);
2645 $progress = $progress
2646 ->withValidityOfQualification(
null)
2647 ->withDeadline(
null);
2650 $progress = $progress->withAmountOfPoints($this->getPoints());
2651 $progress = $progress
2652 ->withLastChange($acting_usr_id, $this->getNow())
2653 ->withIndividualModifications(
false);
2660 if ($this->isActive() && !$progress->isRelevant()) {
2663 if (!$this->isActive() && $progress->isInProgress()) {
2674 || $progress->isSuccessful() ===
false
2679 $settings = $this->getSettings()->getValidityOfQualificationSettings();
2680 $period = $settings->getQualificationPeriod();
2681 $date = $settings->getQualificationDate();
2684 $date = DateTimeImmutable::createFromMutable($date);
2688 $date = $cdate->add(
new DateInterval(
'P' . $period .
'D'));
2691 return $progress->withValidityOfQualification($date);
2696 $settings = $this->getSettings()->getDeadlineSettings();
2697 $period = $settings->getDeadlinePeriod();
2698 $date = $settings->getDeadlineDate();
2700 $date = DateTimeImmutable::createFromMutable($date);
2704 $date = $progress->getAssignmentDate();
2705 $date = $date->add(
new DateInterval(
'P' . $period .
'D'));
2707 return $progress->withDeadline($date);
2715 $possible_points = $this->getPossiblePointsOfRelevantChildren($progress);
2725 $lng->loadLanguageModule(
"prg");
2728 return $lng->txt(
"prg_status_in_progress");
2731 return $lng->txt(
"prg_status_completed");
2734 return $lng->txt(
"prg_status_accredited");
2737 return $lng->txt(
"prg_status_not_relevant");
2740 return $lng->txt(
"prg_status_failed");
2742 throw new ilException(
"Unknown status: '$a_status'");
2749 '%s, progress-id %s',
An exception for terminatinating execution or to throw for unit testing.
return true
Flag indicating whether or not HTTP headers will be sent when outputting captcha image/audio.
static saveObjRecSelection($a_obj_id, $a_sub_type="", array $a_records=null, $a_delete_before=true)
Save repository object record selection.
Component logger with individual log levels by component id.
static _lookupTargetId($a_obj_id)
lookup target id
static _lookupTargetRefId($a_obj_id)
Lookup target ref_id.
static _lookupTitle($a_obj_id)
Overwitten from base class.
static _lookupSourceIds($a_target_id)
Get ids of all container references that target the object with the given id.
static _getInstance($a_obj_id)
get instance by obj_id
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static _hasUserCompleted($a_obj_id, $a_user_id)
Lookup user object completion.
static getLogger($a_component_id)
Get component logger.
static setProgressesCompletedIfParentIsProgrammeInLPCompletedMode(int $a_ref_id, int $a_obj_id, int $a_user_id)
changeProgressValidityDate(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $validity)
getLPChildren()
Get the leafs the study programme contains.
getAssignmentsOf(int $a_user_id)
Get the assignments of user at this program or any node above.
getRoot()
Get the ilObjStudyProgramme that is the root node of the tree this programme is in.
addLeaf(ilStudyProgrammeLeaf $a_leaf)
Insert a leaf in this object.
getAmountOfAssignmentsOf(int $a_user_id)
Get the amount of assignments a user has on this program node or any node above.
getAssignmentsRaw()
Get model objects for the assignments on this programm.
markAccredited(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
setPoints(int $a_points)
Set the amount of points.
getAmountOfChildren($include_references=false)
Get the amount of other StudyProgrammes this StudyProgramme has as children.
getMembers()
get usr_ids with any progress on this node
static sendInvalidateMail(int $ref_id, int $usr_id)
getApplicableMembershipSourceForUser(int $usr_id, string $exclude_type)
static removeCrsFromProgrammes(int $crs_ref_id, int $cat_ref_id)
Check, if a category is under surveilllance and automatically remove the deleted course.
removeLeaf(ilStudyProgrammeLeaf $a_leaf)
Remove a leaf from this object.
$membersourcereader_factory
hasAssignmentsOfSingleProgramForUser(int $usr_id)
Get assignments of user to this program-node only.
deleteAutomaticContentCategories(array $category_ids=[])
Delete configuration of categories with auto-content for this StudyProgramme;.
markRelevant(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
getIdsOfSuccessfulChildren(int $ass_id)
assignUser(int $usr_id, int $acting_usr_id=null)
Assign a user to this node at the study program.
updateSettings(ilStudyProgrammeSettings $settings)
static initStudyProgrammeCache()
applyToSubTreeNodes(Closure $fun, bool $include_references=false)
Apply the given Closure to every node in the subtree starting at this object.
canBeRemoved()
Check weather a node can be removed.
removeAssignment(ilStudyProgrammeAssignment $assignment)
Remove an assignment from this program.
getIdsOfUsersWithNotCompletedAndRelevantProgress()
Get the ids of all users that have not completed this programme but have a relevant progress on it.
static $study_programme_cache
$auto_memberships_repository
isAutoContentApplicable()
AutoContent should only be available in active- or draft-mode, and only, if there is no sub-programme...
static getProgrammesMonitoringMemberSource(string $src_type, int $src_id)
Get all StudyProgrammes monitoring this membership-source.
storeAutomaticMembershipSource(string $type, int $src_id)
Store a source to be monitored for automatic memberships.
deleteAllAutomaticContentCategories()
Delete all configuration of categories with auto-content for this StudyProgramme;.
getReferencesTo(ilObjStudyProgramme $prg)
getCompletedCourses(int $a_user_id)
Get courses in this program that the given user already completed.
applyProgressDeadline(ilStudyProgrammeProgress $progress, int $acting_usr_id=null)
updateProgressDeadlineFromSettings($progress)
static getProgrammesMonitoringCategory(int $cat_ref_id)
Get all StudyProgrammes monitoring this category.
canBeCompleted(ilStudyProgrammeProgress $progress)
getAssignmentRepository()
getProgressIdString(ilStudyProgrammeProgress $progress)
static getInstanceByRefId($a_ref_id)
changeProgressDeadline(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $deadline)
deleteAllAutomaticMembershipSources()
Delete all membership sources of this StudyProgramme;.
getIdsFromNodesOnPathFromRootToHere(bool $include_references=false)
Get the ids from the nodes in the path leading from the root node of this program to this node,...
getPoints()
Get the amount of points.
static getCreatableSubObjects(array $a_subobjects, $a_ref_id)
Filter the list of possible subobjects for the objects that actually could be created on a concrete n...
$auto_categories_repository
refreshLPStatus(int $usr_id, int $node_obj_id=null)
storeAutomaticContentCategory(int $category_ref_id)
Store a Category with auto-content for this StudyProgramme; a category can only be referenced once (p...
moveTo(ilObjStudyProgramme $a_new_parent)
Move this tree node to a new parent.
getProgressesOf(int $a_user_id)
Get the progresses the user has on this node.
static getInstanceByObjId($obj_id)
recalculateProgressStatus(ilStudyProgrammeProgress $progress)
getAssignments()
Get all assignments to this program or any node above.
clearLPChildrenCache()
Clear the cached lp children.
static getParentId(ilObject $a_object)
Get the obj id of the parent object for the given object.
static sendInformToReAssignMail(int $progress_id, int $usr_id)
markFailed(int $progress_id, int $acting_usr_id)
static sendRiskyToFailMail(int $progress_id, int $usr_id)
getLocalMembers()
get usr_ids with assignment on this node
getMembersOfMembershipSource(string $src_type, int $src_id)
Get member-ids of a certain source.
hasAutomaticContentCategories()
disableAutomaticMembershipSource(string $type, int $src_id)
Disable a membership source.
clearParentCache()
Clear the cached parent to query it again at the tree.
addMissingProgresses()
Add missing progress records for all assignments of this programm.
getChildren(bool $include_references=false)
Get all ilObjStudyProgrammes that are direct children of this object.
getProgresses()
Get all progresses on this node.
updateAllAssignments()
Update all assignments to this program node.
getProgressForAssignment(int $assignment_id)
updateProgressValidityFromSettings($progress)
static addMemberToProgrammes(string $src_type, int $src_id, int $usr_id)
statusToRepr($a_status)
Get a user readable representation of a status.
updateProgressRelevanceFromSettings($progress)
nodeInserted(ilObjStudyProgramme $a_prg)
Clears child chache and adds progress for new node.
updatePlanFromRepository(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection=null)
getAutomaticContentCategories()
Get configuration of categories with auto-content for this StudyProgramme;.
getPrgInstanceByObjId(int $obj_id)
static addCrsToProgrammes(int $crs_ref_id, int $cat_ref_id)
Check, if a category is under surveilllance and automatically add the course.
getLastChange()
Get the timestamp of the last change on this program or sub program.
clearChildrenCache()
Clear the cached children.
getObjIdsOfChildren(int $node_obj_id)
__construct($a_id=0, bool $a_call_by_reference=true)
ATTENTION: After using the constructor the object won't be in the cache.
hasProgresses()
Are there any users that have a progress on this programme?
getIdsOfUsersWithRelevantProgress()
Get the ids of all users that have a relevant progress at this programme.
hasChildren(bool $include_references=false)
Does this StudyProgramme have other ilObjStudyProgrammes as children?
static sendReAssignedMail(int $ref_id, int $usr_id)
getChildrenProgress($progress)
deleteAssignmentsAndProgresses()
Delete all assignments from the DB.
setStatus(int $a_status)
Set the status of the node.
changeAmountOfPoints(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?int $points)
getAssignmentsOfSingleProgramForUser(int $usr_id)
Get assignments of user to this program-node only.
getAutomaticMembershipSources()
Get sources for auto-memberships.
getIdsOfUsersWithFailedProgress()
Get the ids of all users that have failed this programme.
getDepth()
Get the depth of this StudyProgramme in the tree starting at the topmost StudyProgramme (not root nod...
static getAllChildren(int $a_ref_id, bool $include_references=false)
Get a list of all ilObjStudyProgrammes in the subtree starting at $a_ref_id.
static createInstance()
Create an instance of ilObjStudyProgramme, put in cache.
getPossiblePointsOfRelevantChildren(ilStudyProgrammeProgress $progress)
getAchievedPointsOfChildren(ilStudyProgrammeProgress $progress)
enableAutomaticMembershipSource(string $type, int $src_id, $assign_now=false)
Enable a membership source.
getProgrammeSettingsForProgress(ilStudyProgrammeProgress $progress)
getSubType()
Gets the SubType Object.
getAssignmentForProgress(ilStudyProgrammeProgress $progress)
succeed(int $progress_id, int $triggering_obj_id)
removeNode(ilObjStudyProgramme $a_prg)
Remove a node from this object.
static getRefIdFor(int $obj_id)
getNamesOfCompletedOrAccreditedChildren(int $ass_id)
hasAssignmentOf(int $a_user_id)
Check whether user is assigned to this program or any node above.
deleteAutomaticMembershipSource(string $type, int $src_id)
Delete a membership source.
updateParentProgress(ilStudyProgrammeProgress $progress)
hasAssignments()
Are there any assignments on this node or any node above?
getParent()
Get the parent ilObjStudyProgramme of this object.
getParentProgress(ilStudyProgrammeProgress $progress)
hasRelevantProgresses()
Are there any users that have a relevant progress on this programme?
getLPChildrenIds()
Get the obj-ids of the leafs the program contains.
updateLastChange()
Update last change timestamp on this node and its parents.
getAmountOfLPChildren()
Get the amount of leafs, the study programme contains.
static removeMemberFromProgrammes(string $src_type, int $src_id, int $usr_id)
putInTree($a_parent_ref)
Overwritten from ilObject.
adjustLPMode()
Adjust the lp mode to match current state of tree:
markNotFailed(int $progress_id, int $acting_usr_id)
static setProgressesCompletedFor(int $a_obj_id, int $a_user_id)
Set all progresses to completed where the object with given id is a leaf and that belong to the user.
addNode(ilObjStudyProgramme $a_prg)
Inserts another ilObjStudyProgramme in this object.
getIdsOfUsersWithCompletedProgress()
Get the ids of all users that have completed this programme.
markNotRelevant(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
unmarkAccredited(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
getParents(bool $include_references=false)
Get all parents of the node, where the root of the program comes first.
resetProgressToSettings(ilStudyProgrammeProgress $progress, int $acting_usr_id)
createProgressForAssignment(ilStudyProgrammeAssignment $ass, int $acting_user=null)
Create a progress on this programme for the given assignment.
invalidate(int $progress_id)
static _lookupLogin($a_user_id)
lookup login
static _lookupGender($a_user_id)
Lookup gender.
static _lookupFullname($a_user_id)
Lookup Full Name.
Class ilObject Basic functions for all objects.
createReference()
creates reference for object
static _lookupTitle($a_id)
lookup object title
static _lookupObjectId($a_ref_id)
lookup object id
getRefId()
get reference id @access public
static _getAllReferences($a_id)
get all reference ids of object
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data@access public
getId()
get object id @access public
static _lookupDeletedDate($a_ref_id)
only called in ilObjectGUI::insertSavedNodes
static _lookupType($a_id, $a_reference=false)
lookup object type
Holds information about multi-actions, mainly in context of member-assignemnts and status changes.
add(bool $success, string $message, string $record_identitifer)
Represents one assignment of the user to a program tree.
Class ilStudyProgrammeProgress.
getId()
Get the id of the progress.
getAssignmentId()
Get the assignment this progress belongs to.
withCurrentAmountOfPoints(int $points_cur)
Set the amount of points the user currently has achieved on this node.
markNotFailed(DateTimeImmutable $date, int $acting_usr_id)
const STATUS_NOT_RELEVANT
getAmountOfPoints()
Get the amount of points the user needs to achieve on the subnodes of this node.
getStatus()
Get the status the user has on this node.
getUserId()
Get the id of the user this progress is for.
withStatus(int $status)
Set the status of this node.
markFailed(DateTimeImmutable $date, int $acting_usr_id)
getNodeId()
Get the obj_id of the program node this progress belongs to.
getObjId()
Get the id of the study program.
Exception is thrown when invariants on the program tree would be violated by manipulation of tree.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
if(!file_exists(getcwd() . '/ilias.ini.php'))
registration confirmation script for ilias
The interface a class has to fullfill if it should be used as leaf in a program.
getRefId()
Get the ILIAS reference id of the leaf.
putInTree($a_ref_id)
Put the leaf object in the repository tree under object identified by $a_ref_id.
createReference()
Create a reference id for this object.
Covers the persistence of settings belonging to a study programme (SP).
Covers the persistence of settings belonging to a study programme (SP).
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
foreach($_POST as $key=> $value) $res