ILIAS  release_8 Revision v8.24
class.ilObjStudyProgramme.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
24{
26
30 protected $parent;
31
35 protected ?array $children = null;
36
40 protected ?array $lp_children = null;
41
49
50 // GLOBALS from ILIAS
51
55 protected ?array $members_cache = null;
56
60 protected ?array $reference_children = null;
61
63 protected ilObjUser $ilUser;
66 protected ilLogger $logger;
67
72 public function __construct(int $id = 0, bool $call_by_reference = true)
73 {
75 $this->type = "prg";
76
77 $this->type_repository = $dic['model.Type.ilStudyProgrammeTypeRepository'];
78 $this->auto_categories_repository = $dic['model.AutoCategories.ilStudyProgrammeAutoCategoriesRepository'];
79 $this->auto_memberships_repository = $dic['model.AutoMemberships.ilStudyProgrammeAutoMembershipsRepository'];
80 $this->membersourcereader_factory = $dic['model.AutoMemberships.ilStudyProgrammeMembershipSourceReaderFactory'];
81
82 $this->settings_repository = $dic['model.Settings.ilStudyProgrammeSettingsRepository'];
83 $this->assignment_repository = $dic['repo.assignment'];
84 $this->events = $dic['ilStudyProgrammeEvents'];
85
87
88 $this->clearParentCache();
89 $this->clearChildrenCache();
90 $this->clearLPChildrenCache();
91
92 global $DIC;
93 $tree = $DIC['tree'];
94 $ilUser = $DIC['ilUser'];
95 $this->webdir = $DIC->filesystem()->web();
96 $this->tree = $tree;
97 $this->ilUser = $ilUser;
98 $this->db = $DIC['ilDB'];
99 $this->lng = $DIC['lng'];
100 $this->logger = ilLoggerFactory::getLogger($this->type);
101
102 $this->object_factory = ilObjectFactoryWrapper::singleton();
103
104 $this->custom_icon_factory = $DIC['object.customicons.factory'];
105
107 }
108
109 public static function initStudyProgrammeCache(): void
110 {
111 if (self::$study_programme_cache === null) {
112 self::$study_programme_cache = ilObjStudyProgrammeCache::singleton();
113 }
114 }
115
119 protected function clearParentCache(): void
120 {
121 // This is not initialized, but we need null if there is no parent.
122 $this->parent = false;
123 }
124
128 protected function clearChildrenCache(): void
129 {
130 $this->children = null;
131 }
132
136 protected function clearLPChildrenCache(): void
137 {
138 $this->lp_children = null;
139 }
140
141 public static function getRefIdFor(int $obj_id): int
142 {
143 $refs = ilObject::_getAllReferences($obj_id);
144 if (count($refs) < 1) {
145 throw new ilException("Could not find ref_id for programme with obj_id $obj_id");
146 }
147 return (int) array_shift($refs);
148 }
149
150 protected function getPrgInstanceByObjId(int $obj_id): ilObjStudyProgramme
151 {
153 }
154
155 public static function getInstanceByObjId(int $obj_id): ilObjStudyProgramme
156 {
158 }
159
161 {
162 if (self::$study_programme_cache === null) {
164 }
165 return self::$study_programme_cache->getInstanceByRefId((int) $ref_id);
166 }
167
169 {
171 }
173 {
175 }
176 protected function getTree(): ilTree
177 {
178 return $this->tree;
179 }
180 protected function getLogger(): ilLogger
181 {
182 return $this->logger;
183 }
184
190 public static function createInstance(): ilObjStudyProgramme
191 {
192 $obj = new ilObjStudyProgramme();
193 $obj->create();
194 $obj->createReference();
195 self::$study_programme_cache->addInstance($obj);
196 return $obj;
197 }
198
200 // CRUD
202
204 {
205 return $this->getSettingsRepository()->get($this->getId());
206 }
207
209 {
210 if ($settings->getObjId() !== $this->getId()) {
211 throw new Exception("The given settings-object does not belong to this programme", 1);
212 }
213 $this->getSettingsRepository()->update($settings);
214
215 return true;
216 }
217
218 protected function deleteSettings(): void
219 {
220 $this->getSettingsRepository()->delete($this->getSettings());
221 }
222
228 protected function deleteAssignmentsAndProgresses(): void
229 {
230 $this->assignment_repository->deleteAllAssignmentsForProgrammeId($this->getId());
231 }
232
236 public function create(): int
237 {
238 $id = (int) parent::create();
239 $this->getSettingsRepository()->createFor($id);
240 return $id;
241 }
242
246 public function update(): bool
247 {
248 parent::update();
249
250 $type_settings = $this->getSettings()->getTypeSettings();
251 // Update selection for advanced metadata of the type
252 if ($type_settings->getTypeId()) {
254 $this->getId(),
255 'prg_type',
256 $this->type_repository->getAssignedAMDRecordIdsByType($type_settings->getTypeId())
257 );
258 } else {
259 // If no type is assigned, delete relations by passing an empty array
260 ilAdvancedMDRecord::saveObjRecSelection($this->getId(), 'prg_type', array());
261 }
262 return true;
263 }
264
270 public function delete(): bool
271 {
272 // always call parent delete function first!!
273 if (!parent::delete()) {
274 return false;
275 }
276
277 $this->deleteSettings();
279 try {
280 $this->auto_categories_repository->deleteFor($this->getId());
282 // This would be the case when SP is in trash (#17797)
283 }
284
287
288 $this->events->raise('delete', ['object' => $this, 'obj_id' => $this->getId()]);
289 return true;
290 }
291
292 public function hasAdvancedMetadata(): bool
293 {
294 $sub_type_id = $this->getSettings()->getTypeSettings()->getTypeId();
295 $type = null;
296 if ($sub_type_id) {
297 $type = $this->type_repository->getType($sub_type_id);
298 }
299
300 return !is_null($type) && count($this->type_repository->getAssignedAMDRecordIdsByType($type->getId(), true)) > 0;
301 }
302
304 // GETTERS AND SETTERS
306
310 public function getLastChange(): DateTime
311 {
312 return $this->getSettings()->getLastChange();
313 }
314
318 public function getPoints(): int
319 {
320 return $this->getSettings()->getAssessmentSettings()->getPoints();
321 }
322
328 public function setPoints(int $points): ilObjStudyProgramme
329 {
330 $settings = $this->getSettings();
331 $this->updateSettings(
332 $settings->withAssessmentSettings($settings->getAssessmentSettings()->withPoints($points))
333 );
334 $this->updateLastChange();
335 return $this;
336 }
337
338 public function getLPMode(): int
339 {
340 return $this->getSettings()->getLPMode();
341 }
342
351 public function adjustLPMode(): void
352 {
353 // Clear caches here, there have been some changes, because this method
354 // would not have been called otherwise, and the changer just does not
355 // know if we have filled the caches already...
356 $this->clearLPChildrenCache();
357 $this->clearChildrenCache();
358
359 if ($this->tree->isInTree($this->getRefId())) {
360 if ($this->getAmountOfLPChildren() > 0) {
361 $this->settings_repository->update(
363 );
364 } elseif ($this->getAmountOfChildren(true) > 0) {
365 $this->settings_repository->update(
367 );
368 } else {
369 $this->settings_repository->update(
371 );
372 }
373 }
374 }
375
376 public function getStatus(): int
377 {
378 return $this->getSettings()->getAssessmentSettings()->getStatus();
379 }
380
386 public function setStatus(int $a_status): ilObjStudyProgramme
387 {
388 $settings = $this->getSettings();
389 $this->updateSettings(
390 $settings->withAssessmentSettings($settings->getAssessmentSettings()->withStatus($a_status))
391 );
392 $this->updateLastChange();
393 return $this;
394 }
395
396 public function isActive(): bool
397 {
399 }
400
405 {
406 $type_settings = $this->getSettings()->getTypeSettings();
407 if (!in_array($type_settings->getTypeId(), array("-", "0"))) {
408 $subtype_id = $type_settings->getTypeId();
409 return $this->type_repository->getType($subtype_id);
410 }
411
412 return null;
413 }
414
415
417 // TREE NAVIGATION
419
428 public static function getAllChildren(int $a_ref_id, bool $include_references = false): array
429 {
430 $ret = array();
431 $root = self::getInstanceByRefId($a_ref_id);
432 $root_id = $root->getId();
433 $root->applyToSubTreeNodes(function (ilObjStudyProgramme $prg) use (&$ret, $root_id) {
434 // exclude root node of subtree.
435 if ($prg->getId() === $root_id) {
436 return;
437 }
438 $ret[] = $prg;
439 }, $include_references);
440 return $ret;
441 }
442
443 public function getAllPrgChildren(): array
444 {
445 $ret = [];
446 $this->applyToSubTreeNodes(
447 function (ilObjStudyProgramme $prg) use (&$ret) {
448 if ($prg->getId() === $this->getId()) {
449 return;
450 }
451 $ret[] = $prg;
452 }
453 );
454 return $ret;
455 }
456
464 public function getChildren(bool $include_references = false): array
465 {
466 $this->throwIfNotInTree();
467
468 if ($this->children === null) {
469 $ref_ids = $this->tree->getChildsByType($this->getRefId(), "prg");
470
471 // apply container sorting to tree
472 $sorting = ilContainerSorting::_getInstance($this->getId());
473 $ref_ids = $sorting->sortItems(array('prg' => $ref_ids));
474 $ref_ids = $ref_ids['prg'];
475
476 $this->children = array_map(static function ($node_data) {
477 return ilObjStudyProgramme::getInstanceByRefId($node_data["child"]);
478 }, $ref_ids);
479 }
480
481 if ($include_references && $this->reference_children === null) {
482 $this->reference_children = [];
483 $ref_child_ref_ids = $this->tree->getChildsByType($this->getRefId(), "prgr");
484 foreach ($this->children as $prg) {
485 $ref_child_ref_ids =
486 array_merge(
487 $this->tree->getChildsByType($prg->getRefId(), "prgr"),
488 $ref_child_ref_ids
489 );
490 }
491 foreach (
492 array_unique(
493 array_map(
494 static function ($data) {
495 return (int) $data['child'];
496 },
497 array_filter($ref_child_ref_ids, static function ($data) {
498 return $data["deleted"] === null;
499 })
500 )
501 ) as $prg_ref_id
502 ) {
503 $this->reference_children[] =
504 (new ilObjStudyProgrammeReference($prg_ref_id))->getReferencedObject();
505 }
506 }
507 return $include_references ?
508 array_merge($this->children, $this->reference_children) :
510 }
511
518 public function getParent(): ?ilObjStudyProgramme
519 {
520 if ($this->parent === false) {
521 $this->throwIfNotInTree();
522 $parent_data = $this->tree->getParentNodeData($this->getRefId());
523 if ($parent_data["type"] !== "prg") {
524 $this->parent = null;
525 } else {
526 $this->parent = self::getInstanceByRefId($parent_data["ref_id"]);
527 }
528 }
529 return $this->parent;
530 }
531
532 protected function getReferencesTo(ilObjStudyProgramme $prg): array
533 {
535 return array_filter(
536 array_map(
537 static function ($id) {
538 $refs = ilObject::_getAllReferences((int) $id);
540 array_shift($refs)
541 );
542 },
544 ),
545 static function ($prg_ref) use ($tree) {
546 return !$tree->isDeleted($prg_ref->getRefId());
547 }
548 );
549 }
550
551 public function getReferencesToSelf(): array
552 {
553 return $this->getReferencesTo($this);
554 }
555
561 public function getParents(bool $include_references = false): array
562 {
563 $current = $this;
564 $parents = [];
565 $queque = [$current];
566 while ($element = array_shift($queque)) {
567 $parent = $element->getParent();
568 if ($parent === null || $include_references) {
569 foreach ($this->getReferencesTo($element) as $reference) {
570 if ($this->tree->isDeleted($reference->getRefId())) {
571 continue;
572 }
573 $r_parent = $reference->getParent();
574 if (is_null($r_parent)) {
575 continue;
576 }
577 $queque[] = $r_parent;
578 $parents[] = $r_parent;
579 }
580 continue;
581 }
582 $queque[] = $parent;
583 $parents[] = $parent;
584 }
585 return array_reverse($parents);
586 }
587
593 public function hasChildren(bool $include_references = false): bool
594 {
595 return $this->getAmountOfChildren($include_references) > 0;
596 }
597
604 public function getAmountOfChildren($include_references = false): int
605 {
606 return count($this->getChildren($include_references));
607 }
608
615 public function getDepth(): int
616 {
617 $cur = $this;
618 $count = 0;
619 while ($cur = $cur->getParent()) {
620 $count++;
621 }
622 return $count;
623 }
624
629 public function getRoot(): ilObjStudyProgramme
630 {
631 $parents = $this->getParents();
632 if (count($parents) < 1) {
633 return $this;
634 }
635 return $parents[0];
636 }
637
644 public function getLPChildren(): array
645 {
646 $this->throwIfNotInTree();
647
648 if ($this->lp_children === null) {
649 $this->lp_children = array();
650
651 $ref_ids = $this->tree->getChildsByType($this->getRefId(), "crsr");
652
653 // apply container sorting to tree
654 $sorting = ilContainerSorting::_getInstance($this->getId());
655 $ref_ids = $sorting->sortItems(array('crs_ref' => $ref_ids));
656 $ref_ids = $ref_ids['crs_ref'];
657
658 $lp_children = array_map(function ($node_data) {
659 $lp_obj = $this->object_factory->getInstanceByRefId((int) $node_data["child"]);
660
661 // filter out all StudyProgramme instances
662 return ($lp_obj instanceof $this) ? null : $lp_obj;
663 }, $ref_ids);
664
665 $this->lp_children = array_filter($lp_children);
666 }
667 return $this->lp_children;
668 }
669
676 public function getLPChildrenIds(): array
677 {
678 return array_map(static function ($child) {
679 return $child->getId();
680 }, $this->getLPChildren());
681 }
682
687 public function getAmountOfLPChildren(): int
688 {
689 return count($this->getLPChildren());
690 }
691
692 public function hasLPChildren(): bool
693 {
694 return ($this->getAmountOfLPChildren() > 0);
695 }
696
700 protected function throwIfNotInTree(): void
701 {
702 if (!$this->tree->isInTree($this->getRefId())) {
703 throw new ilStudyProgrammeTreeException("This program is not in tree.");
704 }
705 }
706
708 // QUERIES ON SUBTREE
710
718 public function applyToSubTreeNodes(Closure $fun, bool $include_references = false): void
719 {
720 $this->throwIfNotInTree();
721
722 if ($fun($this) !== false) {
723 foreach ($this->getChildren($include_references) as $child) {
724 $child->applyToSubTreeNodes($fun, $include_references);
725 }
726 }
727 }
728
734 public function getCompletedCourses(int $usr_id): array
735 {
736 $node_data = $this->tree->getNodeData($this->getRefId());
737 $crsrs = $this->tree->getSubTree($node_data, true, ["crsr"]);
738
739 $completed_crss = array();
740 foreach ($crsrs as $ref) {
741 $crs_id = (int) ilContainerReference::_lookupTargetId((int) $ref["obj_id"]);
742 $crs_ref_id = (int) ilContainerReference::_lookupTargetRefId((int) $ref["obj_id"]);
743
744 if (ilObject::_exists((int) $ref['ref_id'], true) &&
745 is_null(ilObject::_lookupDeletedDate((int) $ref['ref_id'])) &&
746 ilObject::_exists($crs_id, false) &&
747 is_null(ilObject::_lookupDeletedDate($crs_ref_id)) &&
748 ilLPStatus::_hasUserCompleted($crs_id, $usr_id)
749 ) {
750 $containing_prg = self::getInstanceByRefId((int) $ref["parent"]);
751 if ($containing_prg->isActive()) {
752 $completed_crss[] = [
753 "crs_id" => $crs_id
754 , "prg_ref_id" => (int) $ref["parent"]
755 , "prg_obj_id" => $containing_prg->getId()
756 , "crsr_ref_id" => (int) $ref["child"]
757 , "crsr_id" => (int) $ref["obj_id"]
758 , "crs_ref_id" => (int) $crs_ref_id
759 , "crs_id" => (int) $crs_id
760
761 , "title" => ilContainerReference::_lookupTitle((int) $ref["obj_id"])
762 ];
763 }
764 }
765 }
766 return $completed_crss;
767 }
768
770 // TREE MANIPULATION
772
784 {
785 $this->throwIfNotInTree();
786
788 throw new ilStudyProgrammeTreeException("Program already contains leafs.");
789 }
790
791 if ($this->tree->isInTree($a_prg->getRefId())) {
792 throw new ilStudyProgrammeTreeException("Other program already is in tree.");
793 }
794
795 if ($a_prg->getRefId() === null) {
796 $a_prg->createReference();
797 }
798 $a_prg->putInTree($this->getRefId());
799 return $this;
800 }
801
810 public function nodeInserted($prg): void
811 {
812 if (! $prg instanceof ilObjStudyProgrammeReference &&
813 ! $prg instanceof ilObjStudyProgramme
814 ) {
815 throw new ilStudyProgrammeTreeException("Wrong type of node: " . get_class($prg));
816 }
818 throw new ilStudyProgrammeTreeException("Program already contains leafs.");
819 }
820
822 $this->settings_repository->update(
824 );
825 }
826
827 $this->clearChildrenCache();
828 $this->addMissingProgresses();
829 }
830
838 public function putInTree(int $parent_ref_id): void
839 {
840 parent::putInTree($parent_ref_id);
841
842 if (ilObject::_lookupType($parent_ref_id, true) === "prg") {
843 $par = self::getInstanceByRefId($parent_ref_id);
844 $par->nodeInserted($this);
845 }
846 }
847
858 {
859 if ($a_prg->getParent()->getId() !== $this->getId()) {
860 throw new ilStudyProgrammeTreeException("This is no parent of the given programm.");
861 }
862
863 if (!$a_prg->canBeRemoved()) {
864 throw new ilStudyProgrammeTreeException("The node has relevant assignments.");
865 }
866
867 // *sigh*...
868 $node_data = $this->tree->getNodeData($a_prg->getRefId());
869 $this->tree->deleteTree($node_data);
870 $a_prg->clearParentCache();
871 $this->clearChildrenCache();
872
873 return $this;
874 }
875
880 public function canBeRemoved(): bool
881 {
882 return ! $this->hasRelevantProgresses();
883 }
884
894 public function moveTo(ilObjStudyProgramme $new_parent): ilObjStudyProgramme
895 {
896 global $DIC;
897 $rbacadmin = $DIC['rbacadmin'];
898
899 if ($parent = $this->getParent()) {
900 // TODO: check if there some leafs in the new parent
901
902 $this->tree->moveTree($this->getRefId(), $new_parent->getRefId());
903 // necessary to clean up permissions
904 $rbacadmin->adjustMovedObjectPermissions($this->getRefId(), $parent->getRefId());
905
906 // TODO: lp-progress needs to be updated
907
908 // clear caches on different nodes
909 $this->clearParentCache();
910
911 $parent->clearChildrenCache();
912 $parent->clearLPChildrenCache();
913
914 $new_parent->clearChildrenCache();
915 $new_parent->clearLPChildrenCache();
916 }
917
918 return $this;
919 }
920
922 // USER ASSIGNMENTS
924
925 protected function getMessageCollection(string $topic): ilPRGMessageCollection
926 {
927 $msgs = new ilPRGMessageCollection();
928 return $msgs->withNewTopic($topic);
929 }
930
941 public function assignUser(int $usr_id, int $acting_usr_id = null, $raise_event = true): ilPRGAssignment
942 {
943 $this->members_cache = null;
944
946 throw new ilException(
947 "ilObjStudyProgramme::assignUser: Can't assign user to program '"
948 . $this->getId() . "', since it's not in active status."
949 );
950 }
951
952 if (is_null($acting_usr_id)) {
953 $acting_usr_id = $this->getLoggedInUserId();
954 }
955
956 $ass = $this->assignment_repository->createFor($this->getId(), $usr_id, $acting_usr_id);
957 $ass = $ass
958 ->initAssignmentDates();
959
960 $ass = $ass->resetProgresses(
961 $this->getSettingsRepository(),
962 $acting_usr_id
963 );
964
965 $this->assignment_repository->store($ass);
966
967 if ($raise_event) {
968 $this->events->userAssigned($ass);
969 }
970 return $ass;
971 }
972
981 {
982 $this->members_cache = null;
983 if ($assignment->getRootId() !== $this->getId()) {
984 throw new ilException(
985 "ilObjStudyProgramme::removeAssignment: Assignment '"
986 . $assignment->getId() . "' does not belong to study "
987 . "program '" . $this->getId() . "'."
988 );
989 }
990
991 $this->assignment_repository->delete($assignment);
992
993 $affected_node_ids = array_map(fn ($pgs) => $pgs->getNodeId(), $assignment->getProgresses());
994 foreach ($affected_node_ids as $node_obj_id) {
995 $this->refreshLPStatus($assignment->getUserId(), $node_obj_id);
996 }
997
998 $this->events->userDeassigned($assignment);
999 return $this;
1000 }
1001
1002 public function getSpecificAssignment(int $assignment_id): ilPRGAssignment
1003 {
1004 return $this->assignment_repository->get($assignment_id);
1005 }
1006
1007 public function storeExpiryInfoSentFor(ilPRGAssignment $ass): void
1008 {
1009 $this->assignment_repository->storeExpiryInfoSentFor($ass);
1010 }
1011
1012 public function resetExpiryInfoSentFor(ilPRGAssignment $ass): void
1013 {
1014 $this->assignment_repository->resetExpiryInfoSentFor($ass);
1015 }
1016
1017 public function storeRiskyToFailSentFor(ilPRGAssignment $ass): void
1018 {
1019 $this->assignment_repository->storeRiskyToFailSentFor($ass);
1020 }
1021
1022 public function resetRiskyToFailSentFor(ilPRGAssignment $ass): void
1023 {
1024 $this->assignment_repository->resetRiskyToFailSentFor($ass);
1025 }
1026
1030 public function hasAssignmentOf(int $user_id): bool
1031 {
1032 return $this->getAmountOfAssignmentsOf($user_id) > 0;
1033 }
1034
1039 public function getAmountOfAssignmentsOf(int $user_id): int
1040 {
1041 return count($this->getAssignmentsOf($user_id));
1042 }
1043
1051 public function getAssignmentsOf(int $user_id): array
1052 {
1053 $assignments = $this->assignment_repository->getAllForNodeIsContained(
1054 $this->getId(),
1055 [$user_id]
1056 );
1057
1058 usort($assignments, function ($a_one, $a_other) {
1059 return strcmp(
1060 $a_one->getLastChange()->format('Y-m-d'),
1061 $a_other->getLastChange()->format('Y-m-d')
1062 );
1063 });
1064 return $assignments;
1065 }
1066
1070 public function getAssignments(): array
1071 {
1072 return $this->assignment_repository->getAllForNodeIsContained($this->getId());
1073 }
1074
1079 public function getMembers(): array
1080 {
1081 $usr_ids = [];
1082 foreach ($this->getAssignments() as $assignment) {
1083 $usr_ids[] = $assignment->getUserId();
1084 }
1085 return array_unique($usr_ids);
1086 }
1087
1091 public function getLocalMembers(): array
1092 {
1093 if (!$this->members_cache) {
1094 $this->members_cache = array_map(
1095 static function ($assignment) {
1096 return $assignment->getUserId();
1097 },
1098 $this->assignment_repository->getByPrgId($this->getId())
1099 );
1100 }
1101 return $this->members_cache;
1102 }
1103
1107 public function hasAssignments(): bool
1108 {
1109 $filter = new ilPRGAssignmentFilter($this->lng);
1110 $count = $this->assignment_repository->countAllForNodeIsContained(
1111 $this->getId(),
1112 null,
1113 $filter
1114 );
1115 return $count > 0;
1116
1117 }
1118
1124 public function getAssignmentsOfSingleProgramForUser(int $usr_id): array
1125 {
1126 return $this->assignment_repository->getAllForSpecificNode($this->getId(), [$usr_id]);
1127 }
1128
1132 public function hasAssignmentsOfSingleProgramForUser(int $usr_id): bool
1133 {
1134 return count($this->getAssignmentsOfSingleProgramForUser($usr_id)) > 0;
1135 }
1136
1137
1139 // USER PROGRESS
1141
1147 public function addMissingProgresses(): void
1148 {
1149 $assignments = $this->getAssignments();
1150 foreach ($assignments as $ass) {
1151 $this->assignment_repository->store($ass);
1152 }
1153 }
1154
1158 public function hasRelevantProgresses(): bool
1159 {
1160 $filter = new ilPRGAssignmentFilter($this->lng);
1161 $filter = $filter->withValues([
1162 'prg_status_hide_irrelevant' => true
1163 ]);
1164 $count = $this->assignment_repository->countAllForNodeIsContained(
1165 $this->getId(),
1166 null,
1167 $filter
1168 );
1169 return $count > 0;
1170 }
1171
1172 public function getIdsOfUsersWithRelevantProgress(): array
1173 {
1174 return array_map(
1175 fn ($ass) => $ass->getUserId(),
1176 $this->getAssignments()
1177 );
1178 }
1179
1180
1182 // AUTOMATIC CONTENT CATEGORIES
1184
1189 public function getAutomaticContentCategories(): array
1190 {
1191 return $this->auto_categories_repository->getFor($this->getId());
1192 }
1193
1194 public function hasAutomaticContentCategories(): bool
1195 {
1196 return count($this->getAutomaticContentCategories()) > 0;
1197 }
1198
1199
1204 public function storeAutomaticContentCategory(int $category_ref_id): void
1205 {
1206 $ac = $this->auto_categories_repository->create(
1207 $this->getId(),
1208 $category_ref_id
1209 );
1210 $this->auto_categories_repository->update($ac);
1211 }
1212
1217 public function deleteAutomaticContentCategories(array $category_ids = []): void
1218 {
1219 $this->auto_categories_repository->delete($this->getId(), $category_ids);
1220 }
1221
1226 {
1227 $this->auto_categories_repository->deleteFor($this->getId());
1228 }
1229
1233 public static function addCrsToProgrammes(int $crs_ref_id, int $cat_ref_id): void
1234 {
1235 foreach (self::getProgrammesMonitoringCategory($cat_ref_id) as $prg) {
1236 $course_ref = new ilObjCourseReference();
1237 $course_ref->setTitleType(ilContainerReference::TITLE_TYPE_REUSE);
1238 $course_ref->setTargetRefId($crs_ref_id);
1239 $course_ref->create();
1240 $course_ref->createReference();
1241 $course_ref->putInTree($prg->getRefId());
1242 $course_ref->setPermissions($crs_ref_id);
1243 $course_ref->setTargetId(ilObject::_lookupObjectId($crs_ref_id));
1244 $course_ref->update();
1245 $lp = new ilLPObjSettings($course_ref->getId());
1246 $lp->insert();
1247 $lp->setMode($lp::LP_MODE_COURSE_REFERENCE);
1248 $lp->update(false);
1249 }
1250 }
1251
1257 public static function removeCrsFromProgrammes(int $crs_ref_id, int $cat_ref_id): void
1258 {
1259 foreach (self::getProgrammesMonitoringCategory($cat_ref_id) as $prg) {
1260 foreach ($prg->getLPChildren() as $child) {
1261 if ((int) $child->getTargetRefId() === $crs_ref_id) {
1262 $child->delete();
1263 }
1264 }
1265 }
1266 }
1267
1272 protected static function getProgrammesMonitoringCategory(int $cat_ref_id): array
1273 {
1274 $db = ilStudyProgrammeDIC::dic()['model.AutoCategories.ilStudyProgrammeAutoCategoriesRepository'];
1275 $programmes =
1276 array_filter(
1277 array_map(
1278 static function (array $rec) {
1279 $values = array_values($rec);
1280 $prg_obj_id = (int) array_shift($values);
1281
1282 $references = ilObject::_getAllReferences($prg_obj_id);
1283 $prg_ref_id = (int) array_shift($references);
1284
1285 $prg = self::getInstanceByRefId($prg_ref_id);
1286 if ($prg->isAutoContentApplicable()) {
1287 return $prg;
1288 }
1289 },
1290 $db::getProgrammesFor($cat_ref_id)
1291 )
1292 );
1293 return $programmes;
1294 }
1295
1302 public function isAutoContentApplicable(): bool
1303 {
1304 $valid_status = in_array(
1305 $this->getSettings()->getAssessmentSettings()->getStatus(),
1306 [
1309 ],
1310 true
1311 );
1312
1313 $crslnk_allowed = (
1314 $this->hasLPChildren()
1315 || $this->getAmountOfChildren(true) === 0
1316 );
1317
1318 return $valid_status && $crslnk_allowed;
1319 }
1320
1321
1323 // AUTOMATIC MEMBERSHIPS
1325
1330 public function getAutomaticMembershipSources(): array
1331 {
1332 return $this->auto_memberships_repository->getFor($this->getId());
1333 }
1334
1338 public function storeAutomaticMembershipSource(string $type, int $src_id): void
1339 {
1340 $ams = $this->auto_memberships_repository->create($this->getId(), $type, $src_id, false);
1341 $this->auto_memberships_repository->update($ams);
1342 }
1343
1347 public function deleteAutomaticMembershipSource(string $type, int $src_id): void
1348 {
1349 $this->auto_memberships_repository->delete($this->getId(), $type, $src_id);
1350 }
1351
1356 {
1357 $this->auto_memberships_repository->deleteFor($this->getId());
1358 }
1359
1363 public function disableAutomaticMembershipSource(string $type, int $src_id): void
1364 {
1365 $ams = $this->auto_memberships_repository->create($this->getId(), $type, $src_id, false);
1366 $this->auto_memberships_repository->update($ams);
1367 }
1368
1373 public function enableAutomaticMembershipSource(string $type, int $src_id, bool $assign_now = false): void
1374 {
1375 if ($assign_now) {
1377 $member_ids = $this->getMembersOfMembershipSource($type, $src_id);
1378 foreach ($member_ids as $usr_id) {
1379 if (!$this->getAssignmentsOfSingleProgramForUser($usr_id)) {
1380 $this->assignUser($usr_id, $assigned_by);
1381 }
1382 }
1383 }
1384 $ams = $this->auto_memberships_repository->create($this->getId(), $type, $src_id, true);
1385 $this->auto_memberships_repository->update($ams);
1386 }
1387
1393 protected function getMembersOfMembershipSource(string $src_type, int $src_id): array
1394 {
1395 $source_reader = $this->membersourcereader_factory->getReaderFor($src_type, $src_id);
1396 return $source_reader->getMemberIds();
1397 }
1398
1399
1404 protected static function getProgrammesMonitoringMemberSource(string $src_type, int $src_id): array
1405 {
1406 $db = ilStudyProgrammeDIC::dic()['model.AutoMemberships.ilStudyProgrammeAutoMembershipsRepository'];
1407 $programmes = array_map(
1408 static function ($rec) {
1409 $values = array_values($rec);
1410 $prg_obj_id = (int) array_shift($values);
1411
1412 $references = ilObject::_getAllReferences($prg_obj_id);
1413 $prg_ref_id = (int) array_shift($references);
1414
1415 $prg = self::getInstanceByRefId($prg_ref_id);
1416 return $prg;
1417 },
1418 $db::getProgrammesFor($src_type, $src_id)
1419 );
1420 return $programmes;
1421 }
1422
1423 public static function addMemberToProgrammes(string $src_type, int $src_id, int $usr_id): void
1424 {
1425 foreach (self::getProgrammesMonitoringMemberSource($src_type, $src_id) as $prg) {
1426 if ($prg->isActive() &&
1427 !$prg->hasAssignmentsOfSingleProgramForUser($usr_id)) {
1429 $prg->assignUser($usr_id, $assigned_by);
1430 }
1431 }
1432 }
1433
1434 public static function removeMemberFromProgrammes(string $src_type, int $src_id, int $usr_id): void
1435 {
1436 $now = new DateTimeImmutable();
1437 $assignment_repository = ilStudyProgrammeDIC::dic()['repo.assignment'];
1438 foreach (self::getProgrammesMonitoringMemberSource($src_type, $src_id) as $prg) {
1439 $assignments = $prg->getAssignmentsOfSingleProgramForUser($usr_id);
1440 $next_membership_source = $prg->getApplicableMembershipSourceForUser($usr_id, $src_id);
1441
1442 foreach ($assignments as $assignment) {
1443 if (!$assignment->getProgressTree()->isInProgress()) {
1444 continue;
1445 }
1446
1447 if (!is_null($next_membership_source) && $next_membership_source->isEnabled()) {
1448 $new_src_type = $next_membership_source->getSourceType();
1449 $assigned_by = ilStudyProgrammeAutoMembershipSource::SOURCE_MAPPING[$new_src_type];
1450 $assignment = $assignment->withLastChange($assigned_by, $now);
1451 $assignment_repository->store($assignment);
1452 break;
1453 } else {
1454 $assignment_repository->delete($assignment);
1455 }
1456 }
1457 }
1458 }
1459
1461 int $usr_id,
1462 ?int $exclude_id
1464 foreach ($this->getAutomaticMembershipSources() as $ams) {
1465 $src_id = $ams->getSourceId();
1466 if ($src_id !== $exclude_id
1467 && $ams->isEnabled()
1468 ) {
1469 $source_members = $this->getMembersOfMembershipSource($ams->getSourceType(), $src_id);
1470 if (in_array($usr_id, $source_members)) {
1471 return $ams;
1472 }
1473 }
1474 }
1475 return null;
1476 }
1477
1479 // HELPERS
1481
1485 protected function updateLastChange(): void
1486 {
1487 $this->getSettings()->updateLastChange();
1488 if ($parent = $this->getParent()) {
1489 $parent->updateLastChange();
1490 }
1491 $this->update();
1492 }
1493
1506 int $ref_id,
1507 int $obj_id,
1508 int $user_id
1509 ): void {
1510 global $DIC; // TODO: replace this by a settable static for testing purpose?
1511 $tree = $DIC['tree'];
1512 $node_data = $tree->getParentNodeData($ref_id);
1513 if (count($node_data) === 0 || !array_key_exists('type', $node_data) || $node_data["type"] !== "prg") {
1514 return;
1515 }
1516 self::initStudyProgrammeCache();
1517 $prg = self::getInstanceByRefId($node_data["child"]);
1518 if ($prg->getLPMode() !== ilStudyProgrammeSettings::MODE_LP_COMPLETED) {
1519 return;
1520 }
1521 $prg->succeed($user_id, $obj_id);
1522 }
1523
1524 public function succeed(int $usr_id, int $triggering_obj_id, ilPRGAssignment $ass = null): void
1525 {
1526 $progress_node_id = $this->getId();
1527 if (is_null($ass)) {
1528 $user_assignments = $this->assignment_repository
1529 ->getAllForNodeIsContained($progress_node_id, [$usr_id]);
1530 } else {
1531 $user_assignments = [$ass];
1532 }
1533
1534 foreach ($user_assignments as $ass) {
1535 $ass = $ass->succeed(
1536 $this->getSettingsRepository(),
1537 $progress_node_id,
1538 $triggering_obj_id
1539 );
1540 $this->assignment_repository->store($ass);
1541 }
1542 }
1543
1548 protected static function getParentId(ilObjCourseReference $leaf): ?int
1549 {
1550 global $DIC;
1551 $tree = $DIC['tree'];
1552 if (!$tree->isInTree($leaf->getRefId())) {
1553 return null;
1554 }
1555
1556 $nd = $tree->getParentNodeData($leaf->getRefId());
1557 return $nd["obj_id"];
1558 }
1559
1560
1561 public function updateCustomIcon(): void
1562 {
1563 $customIcon = $this->custom_icon_factory->getByObjId($this->getId(), $this->getType());
1564 $subtype = $this->getSubType();
1565
1566 if ($subtype
1567 && $this->webdir->has($subtype->getIconPath(true))
1568 && $subtype->getIconPath(true) !== $subtype->getIconPath(false)
1569 ) {
1570 $icon = $subtype->getIconPath(true);
1571 $customIcon->saveFromSourceFile($icon);
1572 } else {
1573 $customIcon->remove();
1574 }
1575 }
1576
1578 // HOOKS
1580
1591 public static function getCreatableSubObjects(array $subobjects, $ref_id): array
1592 {
1593 if ($ref_id === null) {
1594 return $subobjects;
1595 }
1596
1597 if (ilObject::_lookupType($ref_id, true) !== "prg") {
1598 throw new ilException("Ref-Id '$ref_id' does not belong to a study programme object.");
1599 }
1600
1601 $parent = self::getInstanceByRefId($ref_id);
1602
1603 $mode = $parent->getLPMode();
1604
1605 switch ($mode) {
1607 $possible_subobjects = $subobjects;
1608 break;
1610 $possible_subobjects = [
1611 "prg" => $subobjects["prg"],
1612 "prgr" => $subobjects["prgr"]
1613 ];
1614 break;
1616 $possible_subobjects = ['crsr' => $subobjects['crsr']];
1617 break;
1618 default:
1619 throw new ilException("Undefined mode for study programme: '$mode'");
1620 }
1621
1622 if ($parent->hasAutomaticContentCategories()) {
1623 $possible_subobjects = array_filter(
1624 $possible_subobjects,
1625 static function ($subtype) {
1626 return $subtype === 'crsr';
1627 },
1628 ARRAY_FILTER_USE_KEY
1629 );
1630 }
1631 return $possible_subobjects;
1632 }
1633
1634
1635 protected function getLoggedInUserId(): int
1636 {
1637 return $this->ilUser->getId();
1638 }
1639
1640 protected function getNow(): DateTimeImmutable
1641 {
1642 return new DateTimeImmutable();
1643 }
1644
1645 protected function getObjIdsOfChildren(int $node_obj_id): array
1646 {
1647 $node_ref_id = self::getRefIdFor($node_obj_id);
1648
1649 $prgs = $this->tree->getChildsByType($node_ref_id, "prg");
1650 $prg_ids = array_map(
1651 static function ($nd) {
1652 return (int) $nd['obj_id'];
1653 },
1654 $prgs
1655 );
1656
1657 $prg_ref_ids = [];
1658 $prg_refs = $this->tree->getChildsByType($node_ref_id, "prgr");
1659 foreach ($prg_refs as $ref) {
1660 $ref_obj = new ilObjStudyProgrammeReference((int) $ref['ref_id']);
1661 $prg_ref_ids[] = $ref_obj->getReferencedObject()->getId();
1662 }
1663
1664 return array_merge($prg_ids, $prg_ref_ids);
1665 }
1666
1667 protected function refreshLPStatus(int $usr_id, int $node_obj_id = null): void
1668 {
1669 if (is_null($node_obj_id)) {
1670 $node_obj_id = $this->getId();
1671 }
1672 ilLPStatusWrapper::_updateStatus($node_obj_id, $usr_id);
1673 }
1674
1675 public function markAccredited(
1676 int $assignment_id,
1677 int $acting_usr_id,
1678 ilPRGMessageCollection $err_collection
1679 ): void {
1680 $progress_node_id = $this->getId();
1681 $assignment = $this->assignment_repository->get($assignment_id)
1682 ->markAccredited(
1683 $this->getSettingsRepository(),
1684 $this->events,
1685 $progress_node_id,
1686 $acting_usr_id,
1687 $err_collection
1688 );
1689
1690 $this->assignment_repository->store($assignment);
1691 }
1692
1693 public function unmarkAccredited(
1694 int $assignment_id,
1695 int $acting_usr_id,
1696 ilPRGMessageCollection $err_collection
1697 ): void {
1698 $progress_node_id = $this->getId();
1699 $assignment = $this->assignment_repository->get($assignment_id)
1700 ->unmarkAccredited(
1701 $this->getSettingsRepository(),
1702 $progress_node_id,
1703 $acting_usr_id,
1704 $err_collection
1705 );
1706
1707 $this->assignment_repository->store($assignment);
1708 $this->refreshLPStatus($assignment->getUserId());
1709 }
1710
1711 public function markNotRelevant(
1712 int $assignment_id,
1713 int $acting_usr_id,
1714 ilPRGMessageCollection $err_collection
1715 ): void {
1716 $progress_node_id = $this->getId();
1717 $assignment = $this->assignment_repository->get($assignment_id)
1718 ->markNotRelevant(
1719 $this->getSettingsRepository(),
1720 $progress_node_id,
1721 $acting_usr_id,
1722 $err_collection
1723 );
1724
1725 $this->assignment_repository->store($assignment);
1726 $this->refreshLPStatus($assignment->getUserId());
1727 }
1728
1729 public function markRelevant(
1730 int $assignment_id,
1731 int $acting_usr_id,
1732 ilPRGMessageCollection $err_collection
1733 ): void {
1734 $progress_node_id = $this->getId();
1735 $assignment = $this->assignment_repository->get($assignment_id)
1736 ->markRelevant(
1737 $this->getSettingsRepository(),
1738 $progress_node_id,
1739 $acting_usr_id,
1740 $err_collection
1741 );
1742
1743 $this->assignment_repository->store($assignment);
1744 $this->refreshLPStatus($assignment->getUserId());
1745 }
1746
1747
1748 public function changeProgressDeadline(
1749 int $assignment_id,
1750 int $acting_usr_id,
1751 ilPRGMessageCollection $err_collection,
1752 ?DateTimeImmutable $deadline
1753 ): void {
1754 $progress_node_id = $this->getId();
1755 $assignment = $this->assignment_repository->get($assignment_id)
1756 ->changeProgressDeadline(
1757 $this->getSettingsRepository(),
1758 $progress_node_id,
1759 $acting_usr_id,
1760 $err_collection,
1761 $deadline
1762 );
1763
1764 $this->assignment_repository->store($assignment);
1765 $this->refreshLPStatus($assignment->getUserId());
1766 }
1767
1769 int $assignment_id,
1770 int $acting_usr_id,
1771 ilPRGMessageCollection $err_collection,
1772 ?DateTimeImmutable $validity
1773 ): void {
1774 $progress_node_id = $this->getId();
1775 $assignment = $this->assignment_repository->get($assignment_id)
1776 ->changeProgressValidityDate(
1777 $this->getSettingsRepository(),
1778 $progress_node_id,
1779 $acting_usr_id,
1780 $err_collection,
1781 $validity
1782 );
1783
1784 $this->assignment_repository->store($assignment);
1785 $this->refreshLPStatus($assignment->getUserId());
1786 }
1787
1788 public function changeAmountOfPoints(
1789 int $assignment_id,
1790 int $acting_usr_id,
1791 ilPRGMessageCollection $err_collection,
1792 int $points
1793 ): void {
1794 $progress_node_id = $this->getId();
1795 $assignment = $this->assignment_repository->get($assignment_id)
1796 ->changeAmountOfPoints(
1797 $this->getSettingsRepository(),
1798 $progress_node_id,
1799 $acting_usr_id,
1800 $err_collection,
1801 $points
1802 );
1803
1804 $this->assignment_repository->store($assignment);
1805 $this->refreshLPStatus($assignment->getUserId());
1806 }
1807
1809 int $assignment_id,
1810 int $acting_usr_id,
1811 ilPRGMessageCollection $err_collection = null
1812 ): void {
1813 $assignment = $this->assignment_repository->get($assignment_id)
1815 $this->getSettingsRepository(),
1816 $acting_usr_id,
1817 $err_collection
1818 );
1819
1820 $this->assignment_repository->store($assignment);
1821 $this->refreshLPStatus($assignment->getUserId());
1822 }
1823
1824 public function acknowledgeCourses(
1825 int $assignment_id,
1826 array $nodes,
1827 ilPRGMessageCollection $err_collection = null
1828 ): void {
1829 $acting_usr_id = $this->getLoggedInUserId();
1830 $assignment = $this->assignment_repository->get($assignment_id);
1831 foreach($nodes as $nodeinfo) {
1832 [$node_obj_id, $course_obj_id] = $nodeinfo;
1833
1834 $assignment = $assignment->succeed(
1835 $this->settings_repository,
1836 $node_obj_id,
1837 $course_obj_id
1838 );
1839
1840 $msg = sprintf(
1841 '%s, progress-id (%s/%s)',
1842 $assignment->getUserInformation()->getFullname(),
1843 $assignment->getId(),
1844 (string) $node_obj_id
1845 );
1846 $err_collection->add(true, 'acknowledged_course', $msg);
1847 }
1848 $this->assignment_repository->store($assignment);
1849 $this->refreshLPStatus($assignment->getUserId());
1850 }
1851
1852 public function canBeCompleted(ilPRGProgress $progress): bool
1853 {
1854 if ($this->getLPMode() == ilStudyProgrammeSettings::MODE_LP_COMPLETED) {
1855 return true;
1856 }
1857 $possible_points = $progress->getPossiblePointsOfRelevantChildren();
1858 return $possible_points >= $progress->getAmountOfPoints();
1859 }
1860
1864 public function statusToRepr(int $status): string
1865 {
1866 $lng = $this->lng;
1867 $lng->loadLanguageModule("prg");
1868 if ($status === ilPRGProgress::STATUS_IN_PROGRESS) {
1869 return $lng->txt("prg_status_in_progress");
1870 }
1871 if ($status === ilPRGProgress::STATUS_COMPLETED) {
1872 return $lng->txt("prg_status_completed");
1873 }
1874 if ($status === ilPRGProgress::STATUS_ACCREDITED) {
1875 return $lng->txt("prg_status_accredited");
1876 }
1877 if ($status === ilPRGProgress::STATUS_NOT_RELEVANT) {
1878 return $lng->txt("prg_status_not_relevant");
1879 }
1880 if ($status === ilPRGProgress::STATUS_FAILED) {
1881 return $lng->txt("prg_status_failed");
1882 }
1883 throw new ilException("Unknown status: '$status'");
1884 }
1885
1886 protected function getProgressIdString(ilPRGAssignment $assignment, ilPRGProgress $progress): string
1887 {
1888 $username = ilObjUser::_lookupFullname($assignment->getUserId());
1889 return sprintf(
1890 '%s, progress-id (%s/%s)',
1891 $username,
1892 $assignment->getId(),
1893 $progress->getNodeId()
1894 );
1895 }
1896}
static saveObjRecSelection(int $a_obj_id, string $a_sub_type="", array $a_records=null, bool $a_delete_before=true)
Save repository object record selection.
static _lookupTitle(int $obj_id)
static _lookupSourceIds(int $a_target_id)
Get ids of all container references that target the object with the given id.
static _lookupTargetId(int $a_obj_id)
static _lookupTargetRefId(int $a_obj_id)
static _getInstance(int $a_obj_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
static _hasUserCompleted(int $a_obj_id, int $a_user_id)
Lookup user object completion.
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getLPChildren()
Get the leafs the study programme contains.
hasAssignmentOf(int $user_id)
Check whether user is assigned to this program or any node above.
getAssignmentsOf(int $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.
assignUser(int $usr_id, int $acting_usr_id=null, $raise_event=true)
Assign a user to this node at the study program.
static setProgressesCompletedIfParentIsProgrammeInLPCompletedMode(int $ref_id, int $obj_id, int $user_id)
Succeed all StudyProgramme(Nodes) where the object with the given id (a CRSR) is in a Programme with ...
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
canBeCompleted(ilPRGProgress $progress)
__construct(int $id=0, bool $call_by_reference=true)
ATTENTION: After using the constructor the object won't be in the cache.
static removeCrsFromProgrammes(int $crs_ref_id, int $cat_ref_id)
Check, if a category is under surveillance and automatically remove the deleted course.
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;.
ilStudyProgrammeSettingsDBRepository $settings_repository
getSpecificAssignment(int $assignment_id)
static getCreatableSubObjects(array $subobjects, $ref_id)
Filter the list of possible subobjects for the objects that actually could be created on a concrete n...
updateSettings(ilStudyProgrammeSettings $settings)
changeProgressDeadline(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $deadline)
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.
changeAmountOfPoints(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, int $points)
changeProgressValidityDate(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $validity)
isAutoContentApplicable()
AutoContent should only be available in active- or draft-mode, and only, if there is no sub-programme...
resetRiskyToFailSentFor(ilPRGAssignment $ass)
static getProgrammesMonitoringMemberSource(string $src_type, int $src_id)
Get all StudyProgrammes monitoring this membership-source.
setPoints(int $points)
Set the amount of points.
resetExpiryInfoSentFor(ilPRGAssignment $ass)
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;.
static getInstanceByObjId(int $obj_id)
ilPRGAssignmentDBRepository $assignment_repository
updatePlanFromRepository(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection=null)
getReferencesTo(ilObjStudyProgramme $prg)
statusToRepr(int $status)
Get a user readable representation of a status.
markRelevant(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
nodeInserted($prg)
Clears child cache and adds progress for new node.
static getProgrammesMonitoringCategory(int $cat_ref_id)
Get all (not OUTDATED) StudyProgrammes monitoring this category.
deleteAllAutomaticMembershipSources()
Delete all membership sources of this StudyProgramme;.
getPoints()
Get the amount of points.
removeAssignment(ilPRGAssignment $assignment)
Remove an assignment from this program.
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...
ilStudyProgrammeEvents $events
clearLPChildrenCache()
Clear the cached lp children.
moveTo(ilObjStudyProgramme $new_parent)
Move this tree node to a new parent.
enableAutomaticMembershipSource(string $type, int $src_id, bool $assign_now=false)
Enable a membership source.
getLocalMembers()
get usr_ids with assignment on this node
getMembersOfMembershipSource(string $src_type, int $src_id)
Get member-ids of a certain source.
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.
storeRiskyToFailSentFor(ilPRGAssignment $ass)
getChildren(bool $include_references=false)
Get all ilObjStudyProgrammes that are direct children of this object.
getCompletedCourses(int $usr_id)
Get courses in this program that the given user already completed.
static addMemberToProgrammes(string $src_type, int $src_id, int $usr_id)
ilStudyProgrammeTypeDBRepository $type_repository
static getParentId(ilObjCourseReference $leaf)
Get the obj id of the parent object for the given object.
ilObjectFactoryWrapper $object_factory
getAutomaticContentCategories()
Get configuration of categories with auto-content for this StudyProgramme;.
static addCrsToProgrammes(int $crs_ref_id, int $cat_ref_id)
Check, if a category is under surveilllance and automatically add the course.
acknowledgeCourses(int $assignment_id, array $nodes, ilPRGMessageCollection $err_collection=null)
getLastChange()
Get the timestamp of the last change on this program or sub program.
getApplicableMembershipSourceForUser(int $usr_id, ?int $exclude_id)
clearChildrenCache()
Clear the cached children.
getObjIdsOfChildren(int $node_obj_id)
getProgressIdString(ilPRGAssignment $assignment, ilPRGProgress $progress)
ilObjectCustomIconFactory $custom_icon_factory
storeExpiryInfoSentFor(ilPRGAssignment $ass)
putInTree(int $parent_ref_id)
Overwritten from ilObject.
hasChildren(bool $include_references=false)
Does this StudyProgramme have other ilObjStudyProgrammes as children?
ilStudyProgrammeAutoMembershipsDBRepository $auto_memberships_repository
deleteAssignmentsAndProgresses()
Delete all assignments from the DB.
setStatus(int $a_status)
Set the status of the node.
getAssignmentsOfSingleProgramForUser(int $usr_id)
Get assignments of user to this program-node only.
getAutomaticMembershipSources()
Get sources for auto-memberships.
unmarkAccredited(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
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.
succeed(int $usr_id, int $triggering_obj_id, ilPRGAssignment $ass=null)
static ilObjStudyProgrammeCache $study_programme_cache
getSubType()
Gets the SubType Object.
getAmountOfAssignmentsOf(int $user_id)
Get the amount of assignments a user has on this program node or any node above.
ilStudyProgrammeAutoCategoryDBRepository $auto_categories_repository
removeNode(ilObjStudyProgramme $a_prg)
Remove a node from this object.
static getRefIdFor(int $obj_id)
markAccredited(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
deleteAutomaticMembershipSource(string $type, int $src_id)
Delete a membership source.
hasAssignments()
Are there any assignments on this node or any node above?
getParent()
Get the parent ilObjStudyProgramme of this object.
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)
adjustLPMode()
Adjust the lp mode to match current state of tree:
addNode(ilObjStudyProgramme $a_prg)
Inserts another ilObjStudyProgramme in this object.
ilStudyProgrammeMembershipSourceReaderFactory $membersourcereader_factory
getParents(bool $include_references=false)
Get all parents of the node, where the root of the program comes first.
markNotRelevant(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
User class.
static _lookupFullname(int $a_user_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupObjectId(int $ref_id)
static _lookupType(int $id, bool $reference=false)
createReference()
creates reference for object
static _getAllReferences(int $id)
get all reference ids for object ID
static _lookupDeletedDate(int $ref_id)
ilTree $tree
bool $call_by_reference
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
string $type
ilDBInterface $db
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
getProgresses(array &$ret=[], ilPRGProgress $pgs=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
add(bool $success, string $message, string $record_identitifer)
A Progress is the status of a user on a single node of an assignment; it is unique by assignment_id:u...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilStudyProgrammeType.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
isDeleted(int $a_node_id)
This is a wrapper for isSaved() with a more useful name.
$nd
Definition: error.php:12
global $DIC
Definition: feed.php:28
getRefIdFor(int $obj_id)
updatePlanFromRepository(ilStudyProgrammeSettingsRepository $settings_repo, int $acting_usr_id, ilPRGMessageCollection $err_collection)
Interface Filesystem.
Definition: Filesystem.php:40
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$ref_id
Definition: ltiauth.php:67
Class FlySystemFileAccessTest \Provider\FlySystem @runTestsInSeparateProcesses @preserveGlobalState d...
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
getSettings()
Get an array of all setting values.
Definition: System.php:287
array $settings
Setting values (LTI parameters, custom parameters and local parameters).
Definition: System.php:200
get(string $key, Refinery\Transformation $t)
Get passed parameter, if not data passed, get key from http request.
$dic
Definition: result.php:32
$lng