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'];
142 $tree = $DIC[
'tree'];
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'];
156 self::initStudyProgrammeCache();
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);
202 return self::getInstanceByRefId(self::getRefIdFor($obj_id));
207 return self::getInstanceByRefId(self::getRefIdFor($obj_id));
212 if (self::$study_programme_cache === null) {
213 self::initStudyProgrammeCache();
215 return self::$study_programme_cache->getInstanceByRefId($a_ref_id);
236 return $this->logger;
248 $obj->createReference();
249 self::$study_programme_cache->addInstance($obj);
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)
486 $root = self::getInstanceByRefId($a_ref_id);
487 $root_id = $root->getId();
490 if ($prg->
getId() == $root_id) {
494 }, $include_references);
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) {
806 $containing_prg = self::getInstanceByRefId($ref[
"parent"]);
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);
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;
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')
1146 return array_map(
function ($ass) use ($assignment_repository) {
1147 return $assignment_repository->getInstanceByModel($ass);
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));
1499 $prg = self::getInstanceByRefId($prg_ref_id);
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));
1623 $prg = self::getInstanceByRefId($prg_ref_id);
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);
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") {
1751 self::setProgressesCompletedIfParentIsProgrammeInLPCompletedMode((
int) $ref_id, $a_obj_id, $a_user_id);
1765 $tree = $DIC[
'tree'];
1766 $node_data =
$tree->getParentNodeData($a_ref_id);
1767 if ($node_data[
"type"] !==
"prg") {
1770 self::initStudyProgrammeCache();
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'];
1803 return $nd[
"obj_id"];
1809 $customIcon = $this->custom_icon_factory->getByObjId($this->
getId(), $this->
getType());
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.");
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");
1886 $log = $DIC[
'ilLog'];
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),
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),
1964 $log = $DIC[
'ilLog'];
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),
2005 $usr_progress_db->sentExpiryInfoFor($usr_progress->getId());
2016 $log = $DIC[
'ilLog'];
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),
2057 $usr_progress_db->sentRiskyToFailFor($usr_progress->getId());
2071 $prgrs = $child->getProgressForAssignment($ass_id);
2072 if (!$prgrs->isSuccessful()) {
2075 $ids[] = [$child->getId(), $child->getRefId()];
2077 if (count($ids) > 0) {
2104 list($obj_id,
$ref_id) = $entry;
2113 return (
int) $this->ilUser->getId();
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);
2160 $ass_id = $progress->getAssignmentId();
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;
2211 if (!is_null($child_progress) && $child_progress->isRelevant()) {
2212 $sum += $child_progress->getAmountOfPoints();
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();
2241 if (is_null($parent_progress)) {
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) {
2286 $successful = ($achieved_points >= $required_points);
2289 $progress = $progress
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)) {
2321 if (!is_null($deadline)
2329 if (is_null($deadline)
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) {
2356 if (!$progress->isTransitionAllowedTo($new_status)) {
2361 $progress = $progress
2362 ->markAccredited($this->
getNow(), $acting_usr_id)
2363 ->withCurrentAmountOfPoints($progress->getAmountOfPoints());
2365 if (!$progress->getValidityOfQualification()) {
2369 $this->events->userSuccessful($progress);
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) {
2393 if (!$progress->isTransitionAllowedTo($new_status)
2395 || $progress->getStatus() === $progress::STATUS_COMPLETED
2401 $progress = $progress
2402 ->unmarkAccredited($this->
getNow(), $acting_usr_id);
2405 $progress = $progress->withCurrentAmountOfPoints($achieved_points);
2415 public function markFailed(
int $progress_id,
int $acting_usr_id) : void
2418 if (!$progress->isRelevant()) {
2421 $progress = $progress->markFailed($this->
getNow(), $acting_usr_id);
2430 if (!$progress->isRelevant()) {
2434 ->markNotFailed($this->
getNow(), $acting_usr_id);
2447 if (!$progress->isRelevant()) {
2448 $err_collection->
add(
false,
'will_not_modify_irrelevant_progress', $this->
getProgressIdString($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);
2475 if ($progress->isRelevant()) {
2480 $progress = $progress
2481 ->markRelevant($this->
getNow(), $acting_usr_id);
2501 public function succeed(
int $progress_id,
int $triggering_obj_id) : void
2504 ->succeed($this->
getNow(), $triggering_obj_id);
2506 $achieved_points = $progress->getAmountOfPoints();
2507 $progress = $progress->withCurrentAmountOfPoints($achieved_points);
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);
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);
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);
2611 $assignment_id = $progress->getAssignmentId();
2615 foreach ($progresses as $progress) {
2618 $progress = $node->updateProgressRelevanceFromSettings($progress);
2619 $progress = $node->resetProgressToSettings($progress, $acting_usr_id);
2622 if (!$node->hasChildren(
true)) {
2623 $leafs[] = [$node, $progress];
2627 foreach ($leafs as $leaf) {
2628 list($node, $progress) = $leaf;
2645 $progress = $progress
2647 ->withDeadline(null);
2651 $progress = $progress
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);
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',
setStatus(int $a_status)
Set the status of the node.
static _lookupLogin($a_user_id)
lookup login
getNamesOfCompletedOrAccreditedChildren(int $ass_id)
The interface a class has to fullfill if it should be used as leaf in a program.
updateAllAssignments()
Update all assignments to this program node.
adjustLPMode()
Adjust the lp mode to match current state of tree:
static _lookupDeletedDate($a_ref_id)
only called in ilObjectGUI::insertSavedNodes
addNode(ilObjStudyProgramme $a_prg)
Inserts another ilObjStudyProgramme in this object.
statusToRepr($a_status)
Get a user readable representation of a status.
clearLPChildrenCache()
Clear the cached lp children.
enableAutomaticMembershipSource(string $type, int $src_id, $assign_now=false)
Enable a membership source.
addLeaf(ilStudyProgrammeLeaf $a_leaf)
Insert a leaf in this object.
static addCrsToProgrammes(int $crs_ref_id, int $cat_ref_id)
Check, if a category is under surveilllance and automatically add the course.
getSubType()
Gets the SubType Object.
static sendRiskyToFailMail(int $progress_id, int $usr_id)
updateProgressRelevanceFromSettings($progress)
storeAutomaticContentCategory(int $category_ref_id)
Store a Category with auto-content for this StudyProgramme; a category can only be referenced once (p...
assignUser(int $usr_id, int $acting_usr_id=null)
Assign a user to this node at the study program.
succeed(int $progress_id, int $triggering_obj_id)
getParent()
Get the parent ilObjStudyProgramme of this object.
getIdsOfUsersWithCompletedProgress()
Get the ids of all users that have completed this programme.
isAutoContentApplicable()
AutoContent should only be available in active- or draft-mode, and only, if there is no sub-programme...
getMembers()
get usr_ids with any progress on this node
getAssignmentRepository()
markFailed(DateTimeImmutable $date, int $acting_usr_id)
removeAssignment(ilStudyProgrammeAssignment $assignment)
Remove an assignment from this program.
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data
setPoints(int $a_points)
Set the amount of points.
getChildren(bool $include_references=false)
Get all ilObjStudyProgrammes that are direct children of this object.
static getProgrammesMonitoringMemberSource(string $src_type, int $src_id)
Get all StudyProgrammes monitoring this membership-source.
getAssignmentId()
Get the assignment this progress belongs to.
invalidate(int $progress_id)
static _lookupFullname($a_user_id)
Lookup Full Name.
getIdsOfSuccessfulChildren(int $ass_id)
createReference()
Create a reference id for this object.
getLPChildren()
Get the leafs the study programme contains.
markNotFailed(DateTimeImmutable $date, int $acting_usr_id)
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
hasProgresses()
Are there any users that have a progress on this programme?
disableAutomaticMembershipSource(string $type, int $src_id)
Disable a membership source.
applyToSubTreeNodes(Closure $fun, bool $include_references=false)
Apply the given Closure to every node in the subtree starting at this object.
markRelevant(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
static _lookupTitle($a_id)
lookup object title
markNotRelevant(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
Component logger with individual log levels by component id.
getProgressForAssignment(int $assignment_id)
static initStudyProgrammeCache()
deleteAssignmentsAndProgresses()
Delete all assignments from the DB.
getAssignmentsRaw()
Get model objects for the assignments on this programm.
storeAutomaticMembershipSource(string $type, int $src_id)
Store a source to be monitored for automatic memberships.
$auto_categories_repository
getIdsOfUsersWithFailedProgress()
Get the ids of all users that have failed this programme.
static _lookupGender($a_user_id)
Lookup gender.
hasAssignmentOf(int $a_user_id)
Check whether user is assigned to this program or any node above.
withCurrentAmountOfPoints(int $points_cur)
Set the amount of points the user currently has achieved on this node.
getLocalMembers()
get usr_ids with assignment on this node
static saveObjRecSelection($a_obj_id, $a_sub_type="", array $a_records=null, $a_delete_before=true)
Save repository object record selection.
getAmountOfAssignmentsOf(int $a_user_id)
Get the amount of assignments a user has on this program node or any node above.
add(bool $success, string $message, string $record_identitifer)
applyProgressDeadline(ilStudyProgrammeProgress $progress, int $acting_usr_id=null)
recalculateProgressStatus(ilStudyProgrammeProgress $progress)
updatePlanFromRepository(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection=null)
static sendInformToReAssignMail(int $progress_id, int $usr_id)
static _getAllReferences($a_id)
get all reference ids of object
getAchievedPointsOfChildren(ilStudyProgrammeProgress $progress)
getAmountOfLPChildren()
Get the amount of leafs, the study programme contains.
createProgressForAssignment(ilStudyProgrammeAssignment $ass, int $acting_user=null)
Create a progress on this programme for the given assignment.
static _lookupObjectId($a_ref_id)
lookup object id
getRoot()
Get the ilObjStudyProgramme that is the root node of the tree this programme is in.
static getProgrammesMonitoringCategory(int $cat_ref_id)
Get all StudyProgrammes monitoring this category.
withLastChange(int $last_change_by, DateTimeImmutable $timestamp)
static getInstanceByRefId($a_ref_id)
static removeCrsFromProgrammes(int $crs_ref_id, int $cat_ref_id)
Check, if a category is under surveilllance and automatically remove the deleted course.
static getInstanceByObjId($obj_id)
updateProgressDeadlineFromSettings($progress)
static getParentId(ilObject $a_object)
Get the obj id of the parent object for the given object.
getChildrenProgress($progress)
createReference()
creates reference for object
removeNode(ilObjStudyProgramme $a_prg)
Remove a node from this object.
hasAssignments()
Are there any assignments on this node or any node above?
changeAmountOfPoints(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?int $points)
getRefId()
Get the ILIAS reference id of the leaf.
getObjIdsOfChildren(int $node_obj_id)
putInTree($a_ref_id)
Put the leaf object in the repository tree under object identified by $a_ref_id.
getId()
Get the id of the progress.
getStatus()
Get the status the user has on this node.
getProgresses()
Get all progresses on this node.
$auto_memberships_repository
getCompletedCourses(int $a_user_id)
Get courses in this program that the given user already completed.
Covers the persistence of settings belonging to a study programme (SP).
unmarkAccredited(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
getProgrammeSettingsForProgress(ilStudyProgrammeProgress $progress)
foreach($_POST as $key=> $value) $res
static _lookupTitle($a_obj_id)
Overwitten from base class.
clearChildrenCache()
Clear the cached children.
getAutomaticContentCategories()
Get configuration of categories with auto-content for this StudyProgramme;.
getId()
get object id public
deleteAllAutomaticContentCategories()
Delete all configuration of categories with auto-content for this StudyProgramme;.
hasRelevantProgresses()
Are there any users that have a relevant progress on this programme?
markFailed(int $progress_id, int $acting_usr_id)
static addMemberToProgrammes(string $src_type, int $src_id, int $usr_id)
static _hasUserCompleted($a_obj_id, $a_user_id)
Lookup user object completion.
getProgressIdString(ilStudyProgrammeProgress $progress)
getParents(bool $include_references=false)
Get all parents of the node, where the root of the program comes first.
nodeInserted(ilObjStudyProgramme $a_prg)
Clears child chache and adds progress for new node.
getIdsOfUsersWithNotCompletedAndRelevantProgress()
Get the ids of all users that have not completed this programme but have a relevant progress on it...
getAssignmentsOfSingleProgramForUser(int $usr_id)
Get assignments of user to this program-node only.
getAssignmentsOf(int $a_user_id)
Get the assignments of user at this program or any node above.
getPossiblePointsOfRelevantChildren(ilStudyProgrammeProgress $progress)
getAmountOfPoints()
Get the amount of points the user needs to achieve on the subnodes of this node.
Represents one assignment of the user to a program tree.
__construct($a_id=0, bool $a_call_by_reference=true)
ATTENTION: After using the constructor the object won't be in the cache.
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...
hasAssignmentsOfSingleProgramForUser(int $usr_id)
Get assignments of user to this program-node only.
const STATUS_NOT_RELEVANT
getType()
get object type public
static removeMemberFromProgrammes(string $src_type, int $src_id, int $usr_id)
static _lookupType($a_id, $a_reference=false)
lookup object type
static setProgressesCompletedIfParentIsProgrammeInLPCompletedMode(int $a_ref_id, int $a_obj_id, int $a_user_id)
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...
static sendInvalidateMail(int $ref_id, int $usr_id)
static sendReAssignedMail(int $ref_id, int $usr_id)
getIdsOfUsersWithRelevantProgress()
Get the ids of all users that have a relevant progress at this programme.
getUserId()
Get the id of the user this progress is for.
getMembersOfMembershipSource(string $src_type, int $src_id)
Get member-ids of a certain source.
Class ilStudyProgrammeProgress.
updateProgressValidityFromSettings($progress)
getLastChange()
Get the timestamp of the last change on this program or sub program.
getObjId()
Get the id of the study program.
hasAutomaticContentCategories()
getParentProgress(ilStudyProgrammeProgress $progress)
withValidityOfQualification(DateTimeImmutable $date=null)
removeLeaf(ilStudyProgrammeLeaf $a_leaf)
Remove a leaf from this object.
updateParentProgress(ilStudyProgrammeProgress $progress)
changeProgressValidityDate(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $validity)
addMissingProgresses()
Add missing progress records for all assignments of this programm.
getProgressesOf(int $a_user_id)
Get the progresses the user has on this node.
getReferencesTo(ilObjStudyProgramme $prg)
putInTree($a_parent_ref)
Overwritten from ilObject.
static getAllChildren(int $a_ref_id, bool $include_references=false)
Get a list of all ilObjStudyProgrammes in the subtree starting at $a_ref_id.
canBeRemoved()
Check weather a node can be removed.
getApplicableMembershipSourceForUser(int $usr_id, string $exclude_type)
getAutomaticMembershipSources()
Get sources for auto-memberships.
getDepth()
Get the depth of this StudyProgramme in the tree starting at the topmost StudyProgramme (not root nod...
hasChildren(bool $include_references=false)
Does this StudyProgramme have other ilObjStudyProgrammes as children?
__construct(Container $dic, ilPlugin $plugin)
withStatus(int $status)
Set the status of this node.
getLPChildrenIds()
Get the obj-ids of the leafs the program contains.
Covers the persistence of settings belonging to a study programme (SP).
getRefId()
get reference id public
static createInstance()
Create an instance of ilObjStudyProgramme, put in cache.
static getRefIdFor(int $obj_id)
markAccredited(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
deleteAutomaticContentCategories(array $category_ids=[])
Delete configuration of categories with auto-content for this StudyProgramme;.
static getLogger($a_component_id)
Get component logger.
getPoints()
Get the amount of points.
static _getInstance($a_obj_id)
get instance by obj_id
$membersourcereader_factory
markNotFailed(int $progress_id, int $acting_usr_id)
static _lookupTargetRefId($a_obj_id)
Lookup target ref_id.
static _lookupSourceIds($a_target_id)
Get ids of all container references that target the object with the given id.
resetProgressToSettings(ilStudyProgrammeProgress $progress, int $acting_usr_id)
Exception is thrown when invariants on the program tree would be violated by manipulation of tree...
getAmountOfChildren($include_references=false)
Get the amount of other StudyProgrammes this StudyProgramme has as children.
refreshLPStatus(int $usr_id, int $node_obj_id=null)
getNodeId()
Get the obj_id of the program node this progress belongs to.
moveTo(ilObjStudyProgramme $a_new_parent)
Move this tree node to a new parent.
withAmountOfPoints(int $points)
Throws when amount of points is smaller then zero.
static _lookupTargetId($a_obj_id)
lookup target id
getAssignmentForProgress(ilStudyProgrammeProgress $progress)
deleteAllAutomaticMembershipSources()
Delete all membership sources of this StudyProgramme;.
canBeCompleted(ilStudyProgrammeProgress $progress)
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...
updateLastChange()
Update last change timestamp on this node and its parents.
clearParentCache()
Clear the cached parent to query it again at the tree.
static $study_programme_cache
deleteAutomaticMembershipSource(string $type, int $src_id)
Delete a membership source.
Holds information about multi-actions, mainly in context of member-assignemnts and status changes...
changeProgressDeadline(int $progress_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $deadline)
updateSettings(ilStudyProgrammeSettings $settings)
getPrgInstanceByObjId(int $obj_id)
getAssignments()
Get all assignments to this program or any node above.