ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjStudyProgramme.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23
25{
26 public const CP_TYPE = 'cont';
27
29
33 protected $parent;
34
38 protected ?array $children = null;
39
43 protected ?array $lp_children = null;
44
52
53 // GLOBALS from ILIAS
54
58 protected ?array $members_cache = null;
59
63 protected ?array $reference_children = null;
64
66 protected ilObjUser $ilUser;
68 protected CustomIconFactory $custom_icon_factory;
69 protected ilLogger $logger;
70
75 public function __construct(int $id = 0, bool $call_by_reference = true)
76 {
78 $this->type = "prg";
79
80 $this->type_repository = $dic['model.Type.ilStudyProgrammeTypeRepository'];
81 $this->auto_categories_repository = $dic['model.AutoCategories.ilStudyProgrammeAutoCategoriesRepository'];
82 $this->auto_memberships_repository = $dic['model.AutoMemberships.ilStudyProgrammeAutoMembershipsRepository'];
83 $this->membersourcereader_factory = $dic['model.AutoMemberships.ilStudyProgrammeMembershipSourceReaderFactory'];
84
85 $this->settings_repository = $dic['model.Settings.ilStudyProgrammeSettingsRepository'];
86 $this->assignment_repository = $dic['repo.assignment'];
87 $this->events = $dic['ilStudyProgrammeEvents'];
88
90
91 $this->clearParentCache();
92 $this->clearChildrenCache();
93 $this->clearLPChildrenCache();
94
95 global $DIC;
96 $tree = $DIC['tree'];
97 $ilUser = $DIC['ilUser'];
98 $this->webdir = $DIC->filesystem()->web();
99 $this->tree = $tree;
100 $this->ilUser = $ilUser;
101 $this->db = $DIC['ilDB'];
102 $this->lng = $DIC['lng'];
103 $this->logger = ilLoggerFactory::getLogger($this->type);
104
105 $this->object_factory = ilObjectFactoryWrapper::singleton();
106
107 $this->custom_icon_factory = $DIC['object.customicons.factory'];
108
110 }
111
112 public static function initStudyProgrammeCache(): void
113 {
114 if (self::$study_programme_cache === null) {
115 self::$study_programme_cache = ilObjStudyProgrammeCache::singleton();
116 }
117 }
118
122 protected function clearParentCache(): void
123 {
124 // This is not initialized, but we need null if there is no parent.
125 $this->parent = false;
126 }
127
131 protected function clearChildrenCache(): void
132 {
133 $this->children = null;
134 }
135
139 protected function clearLPChildrenCache(): void
140 {
141 $this->lp_children = null;
142 }
143
144 public static function getRefIdFor(int $obj_id): int
145 {
146 $refs = ilObject::_getAllReferences($obj_id);
147 if (count($refs) < 1) {
148 throw new ilException("Could not find ref_id for programme with obj_id $obj_id");
149 }
150 return (int) array_shift($refs);
151 }
152
153 protected function getPrgInstanceByObjId(int $obj_id): ilObjStudyProgramme
154 {
156 }
157
158 public static function getInstanceByObjId(int $obj_id): ilObjStudyProgramme
159 {
161 }
162
164 {
165 if (self::$study_programme_cache === null) {
167 }
168 return self::$study_programme_cache->getInstanceByRefId((int) $ref_id);
169 }
170
172 {
174 }
176 {
178 }
179 protected function getTree(): ilTree
180 {
181 return $this->tree;
182 }
183 protected function getLogger(): ilLogger
184 {
185 return $this->logger;
186 }
187
193 public static function createInstance(): ilObjStudyProgramme
194 {
195 $obj = new ilObjStudyProgramme();
196 $obj->create();
197 $obj->createReference();
198 self::$study_programme_cache->addInstance($obj);
199 return $obj;
200 }
201
203 // CRUD
205
207 {
208 return $this->getSettingsRepository()->get($this->getId());
209 }
210
211 public function updateSettings(ilStudyProgrammeSettings $settings): bool
212 {
213 if ($settings->getObjId() !== $this->getId()) {
214 throw new Exception("The given settings-object does not belong to this programme", 1);
215 }
216 $this->getSettingsRepository()->update($settings);
217
218 return true;
219 }
220
221 protected function deleteSettings(): void
222 {
223 $this->getSettingsRepository()->delete($this->getSettings());
224 }
225
231 protected function deleteAssignmentsAndProgresses(): void
232 {
233 $this->assignment_repository->deleteAllAssignmentsForProgrammeId($this->getId());
234 }
235
239 public function create(): int
240 {
241 $id = (int) parent::create();
242 $this->getSettingsRepository()->createFor($id);
243 return $id;
244 }
245
249 public function update(): bool
250 {
251 parent::update();
252
253 $type_settings = $this->getSettings()->getTypeSettings();
254 // Update selection for advanced metadata of the type
255 if ($type_settings->getTypeId()) {
257 $this->getId(),
258 'prg_type',
259 $this->type_repository->getAssignedAMDRecordIdsByType($type_settings->getTypeId())
260 );
261 } else {
262 // If no type is assigned, delete relations by passing an empty array
263 ilAdvancedMDRecord::saveObjRecSelection($this->getId(), 'prg_type', array());
264 }
265 return true;
266 }
267
273 public function delete(): bool
274 {
275 // always call parent delete function first!!
276 if (!parent::delete()) {
277 return false;
278 }
279
280 $this->deleteSettings();
282 try {
283 $this->auto_categories_repository->deleteFor($this->getId());
285 // This would be the case when SP is in trash (#17797)
286 }
287
290
291 $this->events->raise('delete', ['object' => $this, 'obj_id' => $this->getId()]);
292 return true;
293 }
294
295 public function hasAdvancedMetadata(): bool
296 {
297 $sub_type_id = $this->getSettings()->getTypeSettings()->getTypeId();
298 $type = null;
299 if ($sub_type_id) {
300 $type = $this->type_repository->getType($sub_type_id);
301 }
302
303 return !is_null($type) && count($this->type_repository->getAssignedAMDRecordIdsByType($type->getId(), true)) > 0;
304 }
305
306 public function cloneObject(int $target_ref_id, int $copy_id = 0, bool $omit_tree = false): ?ilObject
307 {
308 $new_obj = parent::cloneObject($target_ref_id, $copy_id, $omit_tree);
309 $settings = $this->getSettings()->withObjId($new_obj->getId());
310 $settings = $settings->withAssessmentSettings(
311 $settings->getAssessmentSettings()->withStatus(ilStudyProgrammeSettings::STATUS_DRAFT)
312 );
313 $new_obj->updateSettings($settings);
314 return $new_obj;
315 }
316
318 // GETTERS AND SETTERS
320
324 public function getLastChange(): DateTime
325 {
326 return $this->getSettings()->getLastChange();
327 }
328
332 public function getPoints(): int
333 {
334 return $this->getSettings()->getAssessmentSettings()->getPoints();
335 }
336
342 public function setPoints(int $points): ilObjStudyProgramme
343 {
344 $settings = $this->getSettings();
345 $this->updateSettings(
346 $settings->withAssessmentSettings($settings->getAssessmentSettings()->withPoints($points))
347 );
348 $this->updateLastChange();
349 return $this;
350 }
351
352 public function getLPMode(): int
353 {
354 return $this->getSettings()->getLPMode();
355 }
356
365 public function adjustLPMode(): void
366 {
367 // Clear caches here, there have been some changes, because this method
368 // would not have been called otherwise, and the changer just does not
369 // know if we have filled the caches already...
370 $this->clearLPChildrenCache();
371 $this->clearChildrenCache();
372
373 if ($this->tree->isInTree($this->getRefId())) {
374 if ($this->getAmountOfLPChildren() > 0) {
375 $this->settings_repository->update(
377 );
378 } elseif ($this->getAmountOfChildren(true) > 0) {
379 $this->settings_repository->update(
381 );
382 } else {
383 $this->settings_repository->update(
385 );
386 }
387 }
388 }
389
390 public function getStatus(): int
391 {
392 return $this->getSettings()->getAssessmentSettings()->getStatus();
393 }
394
400 public function setStatus(int $a_status): ilObjStudyProgramme
401 {
402 $settings = $this->getSettings();
403 $this->updateSettings(
404 $settings->withAssessmentSettings($settings->getAssessmentSettings()->withStatus($a_status))
405 );
406 $this->updateLastChange();
407 return $this;
408 }
409
410 public function isActive(): bool
411 {
413 }
414
419 {
420 $type_settings = $this->getSettings()->getTypeSettings();
421 if (!in_array($type_settings->getTypeId(), array("-", "0"))) {
422 $subtype_id = $type_settings->getTypeId();
423 return $this->type_repository->getType($subtype_id);
424 }
425
426 return null;
427 }
428
429 public function isCertificateActive(): bool
430 {
431 $global_settings = new ilSetting('certificate');
432 $global_active = (bool) $global_settings->get('active', '0');
433 if (!$global_active) {
434 return false;
435 }
438 return $certificate_template->isCurrentlyActive();
439 }
440
441
443 // TREE NAVIGATION
445
454 public static function getAllChildren(int $a_ref_id, bool $include_references = false): array
455 {
456 $ret = array();
457 $root = self::getInstanceByRefId($a_ref_id);
458 $root_id = $root->getId();
459 $root->applyToSubTreeNodes(function (ilObjStudyProgramme $prg) use (&$ret, $root_id) {
460 // exclude root node of subtree.
461 if ($prg->getId() === $root_id) {
462 return;
463 }
464 $ret[] = $prg;
465 }, $include_references);
466 return $ret;
467 }
468
469 public function getAllPrgChildren(): array
470 {
471 $ret = [];
472 $this->applyToSubTreeNodes(
473 function (ilObjStudyProgramme $prg) use (&$ret) {
474 if ($prg->getId() === $this->getId()) {
475 return;
476 }
477 $ret[] = $prg;
478 }
479 );
480 return $ret;
481 }
482
490 public function getChildren(bool $include_references = false): array
491 {
492 $this->throwIfNotInTree();
493
494 if ($this->children === null) {
495 $ref_ids = $this->tree->getChildsByType($this->getRefId(), "prg");
496
497 // apply container sorting to tree
498 $sorting = ilContainerSorting::_getInstance($this->getId());
499 $ref_ids = $sorting->sortItems(array('prg' => $ref_ids));
500 $ref_ids = $ref_ids['prg'];
501
502 $this->children = array_map(static function ($node_data) {
503 return ilObjStudyProgramme::getInstanceByRefId($node_data["child"]);
504 }, $ref_ids);
505 }
506
507 if ($include_references && $this->reference_children === null) {
508 $this->reference_children = [];
509 $ref_child_ref_ids = $this->tree->getChildsByType($this->getRefId(), "prgr");
510 foreach (
511 array_unique(
512 array_map(
513 static function ($data) {
514 return (int) $data['child'];
515 },
516 array_filter($ref_child_ref_ids, static function ($data) {
517 return $data["deleted"] === null;
518 })
519 )
520 ) as $prg_ref_id
521 ) {
522 $this->reference_children[] =
523 (new ilObjStudyProgrammeReference($prg_ref_id))->getReferencedObject();
524 }
525 }
526 return $include_references ?
527 array_merge($this->children, $this->reference_children) :
529 }
530
537 public function getParent(): ?ilObjStudyProgramme
538 {
539 if ($this->parent === false) {
540 $this->throwIfNotInTree();
541 $parent_data = $this->tree->getParentNodeData($this->getRefId());
542 if ($parent_data["type"] !== "prg") {
543 $this->parent = null;
544 } else {
545 $this->parent = self::getInstanceByRefId($parent_data["ref_id"]);
546 }
547 }
548 return $this->parent;
549 }
550
551 protected function getReferencesTo(ilObjStudyProgramme $prg): array
552 {
554 return array_filter(
555 array_map(
556 static function ($id) {
557 $refs = ilObject::_getAllReferences((int) $id);
559 array_shift($refs)
560 );
561 },
563 ),
564 static function ($prg_ref) use ($tree) {
565 return !$tree->isDeleted($prg_ref->getRefId());
566 }
567 );
568 }
569
570 public function getReferencesToSelf(): array
571 {
572 return $this->getReferencesTo($this);
573 }
574
580 public function getParents(bool $include_references = false): array
581 {
582 $current = $this;
583 $parents = [];
584 $queque = [$current];
585 while ($element = array_shift($queque)) {
586 $parent = $element->getParent();
587 if ($parent === null || $include_references) {
588 foreach ($this->getReferencesTo($element) as $reference) {
589 if ($this->tree->isDeleted($reference->getRefId())) {
590 continue;
591 }
592 $r_parent = $reference->getParent();
593 if (is_null($r_parent)) {
594 continue;
595 }
596 $queque[] = $r_parent;
597 $parents[] = $r_parent;
598 }
599 continue;
600 }
601 $queque[] = $parent;
602 $parents[] = $parent;
603 }
604 return array_reverse($parents);
605 }
606
612 public function hasChildren(bool $include_references = false): bool
613 {
614 return $this->getAmountOfChildren($include_references) > 0;
615 }
616
623 public function getAmountOfChildren($include_references = false): int
624 {
625 return count($this->getChildren($include_references));
626 }
627
634 public function getDepth(): int
635 {
636 $cur = $this;
637 $count = 0;
638 while ($cur = $cur->getParent()) {
639 $count++;
640 }
641 return $count;
642 }
643
648 public function getRoot(): ilObjStudyProgramme
649 {
650 $parents = $this->getParents();
651 if (count($parents) < 1) {
652 return $this;
653 }
654 return $parents[0];
655 }
656
663 public function getLPChildren(): array
664 {
665 $this->throwIfNotInTree();
666
667 if ($this->lp_children === null) {
668 $this->lp_children = array();
669
670 $ref_ids = $this->tree->getChildsByType($this->getRefId(), "crsr");
671
672 // apply container sorting to tree
673 $sorting = ilContainerSorting::_getInstance($this->getId());
674 $ref_ids = $sorting->sortItems(array('crs_ref' => $ref_ids));
675 $ref_ids = $ref_ids['crs_ref'];
676
677 $lp_children = array_map(function ($node_data) {
678 $lp_obj = $this->object_factory->getInstanceByRefId((int) $node_data["child"]);
679
680 // filter out all StudyProgramme instances
681 return ($lp_obj instanceof $this) ? null : $lp_obj;
682 }, $ref_ids);
683
684 $this->lp_children = array_filter($lp_children);
685 }
686 return $this->lp_children;
687 }
688
695 public function getLPChildrenIds(): array
696 {
697 return array_map(static function ($child) {
698 return $child->getId();
699 }, $this->getLPChildren());
700 }
701
706 public function getAmountOfLPChildren(): int
707 {
708 return count($this->getLPChildren());
709 }
710
711 public function hasLPChildren(): bool
712 {
713 return ($this->getAmountOfLPChildren() > 0);
714 }
715
719 protected function throwIfNotInTree(): void
720 {
721 if (!$this->tree->isInTree($this->getRefId())) {
722 throw new ilStudyProgrammeTreeException("This program is not in tree.");
723 }
724 }
725
727 // QUERIES ON SUBTREE
729
737 public function applyToSubTreeNodes(Closure $fun, bool $include_references = false): void
738 {
739 $this->throwIfNotInTree();
740
741 if ($fun($this) !== false) {
742 foreach ($this->getChildren($include_references) as $child) {
743 $child->applyToSubTreeNodes($fun, $include_references);
744 }
745 }
746 }
747
751 public function getCompletedCourses(ilPRGAssignment $assignment): array
752 {
753 $completed_crss = [];
754 $f = function ($prg) use (&$completed_crss, $assignment) {
755 if ($prg->isActive() &&
756 $assignment->getProgressForNode($prg->getId())->isRelevant()
757 ) {
758 foreach ($prg->getLPChildren() as $child) {
759 $crs_id = (int) ilContainerReference::_lookupTargetId((int) $child->getId());
760 $crs_ref_id = (int) ilContainerReference::_lookupTargetRefId((int) $child->getId());
761 $crsr_ref_id = (int) $child->getRefId();
762
763 if (ilObject::_exists($crsr_ref_id, true) &&
764 is_null(ilObject::_lookupDeletedDate($crsr_ref_id)) &&
765 ilObject::_exists($crs_id, false) &&
766 is_null(ilObject::_lookupDeletedDate($crs_ref_id)) &&
767 ilLPStatus::_hasUserCompleted($crs_id, $assignment->getUserId())
768 ) {
769 $completed_crss[] = [
770 'crs_id' => $crs_id,
771 'prg_ref_id' => $prg->getRefId(),
772 'prg_obj_id' => $prg->getId(),
773 'crsr_ref_id' => $crsr_ref_id,
774 'crsr_id' => $child->getId(),
775 'crs_ref_id' => $crs_ref_id,
776 'title' => ilContainerReference::_lookupTitle((int) $child->getId()),
777 ];
778 }
779 }
780 return true;
781 }
782 return false;
783 };
784 $this->applyToSubTreeNodes($f, true);
785 return $completed_crss;
786 }
787
789 // TREE MANIPULATION
791
803 {
804 $this->throwIfNotInTree();
805
807 throw new ilStudyProgrammeTreeException("Program already contains leafs.");
808 }
809
810 if ($this->tree->isInTree($a_prg->getRefId())) {
811 throw new ilStudyProgrammeTreeException("Other program already is in tree.");
812 }
813
814 if ($a_prg->getRefId() === null) {
815 $a_prg->createReference();
816 }
817 $a_prg->putInTree($this->getRefId());
818 return $this;
819 }
820
829 public function nodeInserted($prg): void
830 {
831 if (! $prg instanceof ilObjStudyProgrammeReference &&
832 ! $prg instanceof ilObjStudyProgramme
833 ) {
834 throw new ilStudyProgrammeTreeException("Wrong type of node: " . get_class($prg));
835 }
837 throw new ilStudyProgrammeTreeException("Program already contains leafs.");
838 }
839
841 $this->settings_repository->update(
843 );
844 }
845
846 $this->clearChildrenCache();
847 $this->addMissingProgresses();
848 }
849
857 public function putInTree(int $parent_ref_id): void
858 {
859 parent::putInTree($parent_ref_id);
860
861 if (ilObject::_lookupType($parent_ref_id, true) === "prg") {
862 $par = self::getInstanceByRefId($parent_ref_id);
863 $par->nodeInserted($this);
864 }
865 }
866
877 {
878 if ($a_prg->getParent()->getId() !== $this->getId()) {
879 throw new ilStudyProgrammeTreeException("This is no parent of the given programm.");
880 }
881
882 if (!$a_prg->canBeRemoved()) {
883 throw new ilStudyProgrammeTreeException("The node has relevant assignments.");
884 }
885
886 // *sigh*...
887 $node_data = $this->tree->getNodeData($a_prg->getRefId());
888 $this->tree->deleteTree($node_data);
889 $a_prg->clearParentCache();
890 $this->clearChildrenCache();
891
892 return $this;
893 }
894
899 public function canBeRemoved(): bool
900 {
901 return ! $this->hasRelevantProgresses();
902 }
903
913 public function moveTo(ilObjStudyProgramme $new_parent): ilObjStudyProgramme
914 {
915 global $DIC;
916 $rbacadmin = $DIC['rbacadmin'];
917
918 if ($parent = $this->getParent()) {
919 // TODO: check if there some leafs in the new parent
920
921 $this->tree->moveTree($this->getRefId(), $new_parent->getRefId());
922 // necessary to clean up permissions
923 $rbacadmin->adjustMovedObjectPermissions($this->getRefId(), $parent->getRefId());
924
925 // TODO: lp-progress needs to be updated
926
927 // clear caches on different nodes
928 $this->clearParentCache();
929
930 $parent->clearChildrenCache();
931 $parent->clearLPChildrenCache();
932
933 $new_parent->clearChildrenCache();
934 $new_parent->clearLPChildrenCache();
935 }
936
937 return $this;
938 }
939
941 // USER ASSIGNMENTS
943
954 public function assignUser(int $usr_id, ?int $acting_usr_id = null, $raise_event = true): ilPRGAssignment
955 {
956 $this->members_cache = null;
957
959 throw new ilException(
960 "ilObjStudyProgramme::assignUser: Can't assign user to program '"
961 . $this->getId() . "', since it's not in active status."
962 );
963 }
964
965 if (is_null($acting_usr_id)) {
966 $acting_usr_id = $this->getLoggedInUserId();
967 }
968
969 $ass = $this->assignment_repository->createFor($this->getId(), $usr_id, $acting_usr_id);
970 $ass = $ass
971 ->initAssignmentDates();
972
973 $ass = $ass->resetProgresses(
974 $this->getSettingsRepository(),
975 $acting_usr_id
976 );
977
978 $this->assignment_repository->store($ass);
979
980 if ($raise_event) {
981 $this->events->userAssigned($ass);
982 }
983 return $ass;
984 }
985
994 {
995 $this->members_cache = null;
996 if ($assignment->getRootId() !== $this->getId()) {
997 throw new ilException(
998 "ilObjStudyProgramme::removeAssignment: Assignment '"
999 . $assignment->getId() . "' does not belong to study "
1000 . "program '" . $this->getId() . "'."
1001 );
1002 }
1003
1004 $this->assignment_repository->delete($assignment);
1005
1006 $affected_node_ids = array_map(fn($pgs) => $pgs->getNodeId(), $assignment->getProgresses());
1007 foreach ($affected_node_ids as $node_obj_id) {
1008 $this->refreshLPStatus($assignment->getUserId(), $node_obj_id);
1009 }
1010
1011 $this->events->userDeassigned($assignment);
1012 return $this;
1013 }
1014
1015 public function getSpecificAssignment(int $assignment_id): ilPRGAssignment
1016 {
1017 return $this->assignment_repository->get($assignment_id);
1018 }
1019
1020 public function storeExpiryInfoSentFor(ilPRGAssignment $ass): void
1021 {
1022 $this->assignment_repository->storeExpiryInfoSentFor($ass);
1023 }
1024
1025 public function resetExpiryInfoSentFor(ilPRGAssignment $ass): void
1026 {
1027 $this->assignment_repository->resetExpiryInfoSentFor($ass);
1028 }
1029
1030 public function storeRiskyToFailSentFor(ilPRGAssignment $ass): void
1031 {
1032 $this->assignment_repository->storeRiskyToFailSentFor($ass);
1033 }
1034
1035 public function resetRiskyToFailSentFor(ilPRGAssignment $ass): void
1036 {
1037 $this->assignment_repository->resetRiskyToFailSentFor($ass);
1038 }
1039
1043 public function hasAssignmentOf(int $user_id): bool
1044 {
1045 return $this->getAmountOfAssignmentsOf($user_id) > 0;
1046 }
1047
1053 {
1054 return count($this->getAssignmentsOf($user_id));
1055 }
1056
1064 public function getAssignmentsOf(int $user_id): array
1065 {
1066 $assignments = $this->assignment_repository->getAllForNodeIsContained(
1067 $this->getId(),
1068 [$user_id]
1069 );
1070
1071 usort($assignments, function ($a_one, $a_other) {
1072 return strcmp(
1073 $a_one->getLastChange()->format('Y-m-d'),
1074 $a_other->getLastChange()->format('Y-m-d')
1075 );
1076 });
1077 return $assignments;
1078 }
1079
1083 public function getAssignments(): array
1084 {
1085 return $this->assignment_repository->getAllForNodeIsContained($this->getId());
1086 }
1087
1092 public function getMembers(): array
1093 {
1094 $usr_ids = [];
1095 foreach ($this->getAssignments() as $assignment) {
1096 $usr_ids[] = $assignment->getUserId();
1097 }
1098 return array_unique($usr_ids);
1099 }
1100
1104 public function getLocalMembers(): array
1105 {
1106 if (!$this->members_cache) {
1107 $this->members_cache = array_map(
1108 static function ($assignment) {
1109 return $assignment->getUserId();
1110 },
1111 $this->assignment_repository->getByPrgId($this->getId())
1112 );
1113 }
1114 return $this->members_cache;
1115 }
1116
1120 public function hasAssignments(): bool
1121 {
1122 $filter = new ilPRGAssignmentFilter($this->lng);
1123 $count = $this->assignment_repository->countAllForNodeIsContained(
1124 $this->getId(),
1125 null,
1126 $filter
1127 );
1128 return $count > 0;
1129
1130 }
1131
1137 public function getAssignmentsOfSingleProgramForUser(int $usr_id): array
1138 {
1139 return $this->assignment_repository->getAllForSpecificNode($this->getId(), [$usr_id]);
1140 }
1141
1145 public function hasAssignmentsOfSingleProgramForUser(int $usr_id): bool
1146 {
1147 return count($this->getAssignmentsOfSingleProgramForUser($usr_id)) > 0;
1148 }
1149
1150 public function getCertificateRelevantAssignmentIds(int ...$usr_ids): array
1151 {
1152 return $this->assignment_repository->getCertificateRelevantAssignmentIds(
1153 $this->getId(),
1154 ...$usr_ids
1155 );
1156 }
1157
1158
1160 // USER PROGRESS
1162
1168 public function addMissingProgresses(): void
1169 {
1170 $assignments = $this->getAssignments();
1171 foreach ($assignments as $ass) {
1172 $this->assignment_repository->store($ass);
1173 }
1174 }
1175
1179 public function hasRelevantProgresses(): bool
1180 {
1181 $filter = new ilPRGAssignmentFilter($this->lng);
1182 $filter = $filter->withValues([
1183 'prg_status_hide_irrelevant' => true
1184 ]);
1185 $count = $this->assignment_repository->countAllForNodeIsContained(
1186 $this->getId(),
1187 null,
1188 $filter
1189 );
1190 return $count > 0;
1191 }
1192
1193 public function getIdsOfUsersWithRelevantProgress(): array
1194 {
1195 return array_map(
1196 fn($ass) => $ass->getUserId(),
1197 $this->getAssignments()
1198 );
1199 }
1200
1201
1203 // AUTOMATIC CONTENT CATEGORIES
1205
1210 public function getAutomaticContentCategories(): array
1211 {
1212 return $this->auto_categories_repository->getFor($this->getId());
1213 }
1214
1215 public function hasAutomaticContentCategories(): bool
1216 {
1217 return count($this->getAutomaticContentCategories()) > 0;
1218 }
1219
1220
1225 public function storeAutomaticContentCategory(int $category_ref_id): void
1226 {
1227 $ac = $this->auto_categories_repository->create(
1228 $this->getId(),
1229 $category_ref_id
1230 );
1231 $this->auto_categories_repository->update($ac);
1232 }
1233
1238 public function deleteAutomaticContentCategories(array $category_ids = []): void
1239 {
1240 $this->auto_categories_repository->delete($this->getId(), $category_ids);
1241 }
1242
1247 {
1248 $this->auto_categories_repository->deleteFor($this->getId());
1249 }
1250
1254 public static function addCrsToProgrammes(int $crs_ref_id, int $cat_ref_id): void
1255 {
1256 foreach (self::getProgrammesMonitoringCategory($cat_ref_id) as $prg) {
1257 $course_ref = new ilObjCourseReference();
1258 $course_ref->setTitleType(ilContainerReference::TITLE_TYPE_REUSE);
1259 $course_ref->setTargetRefId($crs_ref_id);
1260 $course_ref->create();
1261 $course_ref->createReference();
1262 $course_ref->putInTree($prg->getRefId());
1263 $course_ref->setPermissions($crs_ref_id);
1264 $course_ref->setTargetId(ilObject::_lookupObjectId($crs_ref_id));
1265 $course_ref->update();
1266 $lp = new ilLPObjSettings($course_ref->getId());
1267 $lp->insert();
1268 $lp->setMode($lp::LP_MODE_COURSE_REFERENCE);
1269 $lp->update(false);
1270 }
1271 }
1272
1278 public static function removeCrsFromProgrammes(int $crs_ref_id, int $cat_ref_id): void
1279 {
1280 foreach (self::getProgrammesMonitoringCategory($cat_ref_id) as $prg) {
1281 foreach ($prg->getLPChildren() as $child) {
1282 if ((int) $child->getTargetRefId() === $crs_ref_id) {
1283 $child->delete();
1284 }
1285 }
1286 }
1287 }
1288
1293 protected static function getProgrammesMonitoringCategory(int $cat_ref_id): array
1294 {
1295 $db = ilStudyProgrammeDIC::dic()['model.AutoCategories.ilStudyProgrammeAutoCategoriesRepository'];
1296 $programmes =
1297 array_filter(
1298 array_map(
1299 static function (array $rec) {
1300 $values = array_values($rec);
1301 $prg_obj_id = (int) array_shift($values);
1302
1303 $references = ilObject::_getAllReferences($prg_obj_id);
1304 $prg_ref_id = (int) array_shift($references);
1305
1306 $prg = self::getInstanceByRefId($prg_ref_id);
1307 if ($prg->isAutoContentApplicable()) {
1308 return $prg;
1309 }
1310 },
1311 $db::getProgrammesFor($cat_ref_id)
1312 )
1313 );
1314 return $programmes;
1315 }
1316
1323 public function isAutoContentApplicable(): bool
1324 {
1325 $valid_status = in_array(
1326 $this->getSettings()->getAssessmentSettings()->getStatus(),
1327 [
1330 ],
1331 true
1332 );
1333
1334 $crslnk_allowed = (
1335 $this->hasLPChildren()
1336 || $this->getAmountOfChildren(true) === 0
1337 );
1338
1339 return $valid_status && $crslnk_allowed;
1340 }
1341
1342
1344 // AUTOMATIC MEMBERSHIPS
1346
1351 public function getAutomaticMembershipSources(): array
1352 {
1353 return $this->auto_memberships_repository->getFor($this->getId());
1354 }
1355
1359 public function storeAutomaticMembershipSource(string $type, int $src_id, bool $search_recursive): void
1360 {
1361 $ams = $this->auto_memberships_repository->create(
1362 $this->getId(),
1363 $type,
1364 $src_id,
1365 false,
1366 null,
1367 null,
1368 $search_recursive
1369 );
1370 $this->auto_memberships_repository->update($ams);
1371 }
1372
1376 public function deleteAutomaticMembershipSource(string $type, int $src_id): void
1377 {
1378 $this->auto_memberships_repository->delete($this->getId(), $type, $src_id);
1379 }
1380
1385 {
1386 $this->auto_memberships_repository->deleteFor($this->getId());
1387 }
1388
1392 public function disableAutomaticMembershipSource(string $type, int $src_id, bool $search_recursive): void
1393 {
1394 $ams = $this->auto_memberships_repository->create(
1395 $this->getId(),
1396 $type,
1397 $src_id,
1398 false,
1399 null,
1400 null,
1401 $search_recursive
1402 );
1403 $this->auto_memberships_repository->update($ams);
1404 }
1405
1410 public function enableAutomaticMembershipSource(string $type, int $src_id, bool $search_recursive, $assign_now = false): void
1411 {
1412 if ($assign_now) {
1414 $member_ids = $this->getMembersOfMembershipSource($type, $src_id);
1415 foreach ($member_ids as $usr_id) {
1416 if (!$this->getAssignmentsOfSingleProgramForUser($usr_id)) {
1417 $this->assignUser($usr_id, $assigned_by);
1418 }
1419 }
1420 }
1421 $ams = $this->auto_memberships_repository->create(
1422 $this->getId(),
1423 $type,
1424 $src_id,
1425 true,
1426 null,
1427 null,
1428 $search_recursive
1429 );
1430 $this->auto_memberships_repository->update($ams);
1431 }
1432
1438 protected function getMembersOfMembershipSource(ilStudyProgrammeAutoMembershipSource $ams, ?int $exclude_id): array
1439 {
1440 $source_reader = $this->membersourcereader_factory->getReaderFor($ams, $exclude_id);
1441 return $source_reader->getMemberIds();
1442 }
1443
1448 protected static function getProgrammesMonitoringMemberSource(string $src_type, int $src_id): array
1449 {
1450 $db = ilStudyProgrammeDIC::dic()['model.AutoMemberships.ilStudyProgrammeAutoMembershipsRepository'];
1451 $programmes = array_map(
1452 static function ($rec) {
1453 $values = array_values($rec);
1454 $prg_obj_id = (int) array_shift($values);
1455
1456 $references = ilObject::_getAllReferences($prg_obj_id);
1457 $prg_ref_id = (int) array_shift($references);
1458
1459 $prg = self::getInstanceByRefId($prg_ref_id);
1460 return $prg;
1461 },
1462 $db::getProgrammesFor($src_type, $src_id)
1463 );
1464 return $programmes;
1465 }
1466
1467 public static function addMemberToProgrammes(string $src_type, int $src_id, int $usr_id): void
1468 {
1469 foreach (self::getProgrammesMonitoringMemberSource($src_type, $src_id) as $prg) {
1470 if ($prg->isActive() &&
1471 !$prg->hasAssignmentsOfSingleProgramForUser($usr_id)) {
1473 $prg->assignUser($usr_id, $assigned_by);
1474 }
1475 }
1476 }
1477
1478 public static function removeMemberFromProgrammes(string $src_type, int $src_id, int $usr_id): void
1479 {
1480 $now = new DateTimeImmutable();
1481 $assignment_repository = ilStudyProgrammeDIC::dic()['repo.assignment'];
1482 foreach (self::getProgrammesMonitoringMemberSource($src_type, $src_id) as $prg) {
1483 $assignments = $prg->getAssignmentsOfSingleProgramForUser($usr_id);
1484 $next_membership_source = $prg->getApplicableMembershipSourceForUser($usr_id, $src_id);
1485
1486 foreach ($assignments as $assignment) {
1487 if (!$assignment->getProgressTree()->isInProgress()) {
1488 continue;
1489 }
1490
1491 if (
1492 $next_membership_source !== null
1493 && $next_membership_source?->isEnabled()
1494 && $next_membership_source->getSourceId() !== $src_id
1495 ) {
1496 $new_src_type = $next_membership_source->getSourceType();
1497 $assigned_by = ilStudyProgrammeAutoMembershipSource::SOURCE_MAPPING[$new_src_type];
1498 $assignment = $assignment->withLastChange($assigned_by, $now);
1499 $assignment_repository->store($assignment);
1500 break;
1501 } else {
1502 $assignment_repository->delete($assignment);
1503 }
1504 }
1505 }
1506 }
1507
1509 int $usr_id,
1510 ?int $exclude_id
1512 foreach ($this->getAutomaticMembershipSources() as $ams) {
1513 if ($ams->isEnabled()) {
1514 $source_members = $this->getMembersOfMembershipSource($ams, $exclude_id);
1515 if (in_array($usr_id, $source_members)) {
1516 return $ams;
1517 }
1518 }
1519 }
1520 return null;
1521 }
1522
1524 // HELPERS
1526
1530 protected function updateLastChange(): void
1531 {
1532 $this->getSettings()->updateLastChange();
1533 if ($parent = $this->getParent()) {
1534 $parent->updateLastChange();
1535 }
1536 $this->update();
1537 }
1538
1550 public static function setProgressesCompletedFor(int $obj_id, int $user_id): void
1551 {
1552 // We only use courses via crs_refs
1553 $type = ilObject::_lookupType($obj_id);
1554 if ($type === "crsr") {
1555 foreach (ilObject::_getAllReferences($obj_id) as $ref_id) {
1556 self::setProgressesCompletedIfParentIsProgrammeInLPCompletedMode($ref_id, $obj_id, $user_id);
1557 }
1558 }
1559 }
1560
1565 int $ref_id,
1566 int $obj_id,
1567 int $user_id
1568 ): void {
1569 global $DIC; // TODO: replace this by a settable static for testing purpose?
1570 $tree = $DIC['tree'];
1571 $node_data = $tree->getParentNodeData($ref_id);
1572 if (count($node_data) === 0 || !array_key_exists('type', $node_data) || $node_data["type"] !== "prg") {
1573 return;
1574 }
1575 self::initStudyProgrammeCache();
1576 $prg = self::getInstanceByRefId($node_data["child"]);
1577 if ($prg->getLPMode() !== ilStudyProgrammeSettings::MODE_LP_COMPLETED) {
1578 return;
1579 }
1580 $prg->succeed($user_id, $obj_id);
1581 }
1582
1583 public function succeed(int $usr_id, int $triggering_obj_id, ?ilPRGAssignment $ass = null): void
1584 {
1585 $progress_node_id = $this->getId();
1586 if (is_null($ass)) {
1587 $user_assignments = $this->assignment_repository
1588 ->getAllForNodeIsContained($progress_node_id, [$usr_id]);
1589 } else {
1590 $user_assignments = [$ass];
1591 }
1592
1593 foreach ($user_assignments as $ass) {
1594 $ass = $ass->succeed(
1595 $this->getSettingsRepository(),
1596 $progress_node_id,
1597 $triggering_obj_id
1598 );
1599 $this->assignment_repository->store($ass);
1600 }
1601 }
1602
1603 public function updateCustomIcon(): void
1604 {
1605 $customIcon = $this->custom_icon_factory->getByObjId($this->getId(), $this->getType());
1606 $subtype = $this->getSubType();
1607
1608 if ($subtype && $subtype->getIconIdentifier()) {
1609 $src = $this->type_repository->getIconPathFS($subtype);
1610
1611 //This is a horrible hack to allow Flysystem/LocalFilesystem to read the file.
1612 $tmp = 'ico_' . $this->getId();
1613 copy($src, \ilFileUtils::getDataDir() . '/temp/' . $tmp);
1614
1615 $customIcon->saveFromTempFileName($tmp);
1616 } else {
1617 $customIcon->remove();
1618 }
1619 }
1620
1622 // HOOKS
1624
1635 public static function getCreatableSubObjects(array $subobjects, $ref_id): array
1636 {
1637 if ($ref_id === null) {
1638 return $subobjects;
1639 }
1640
1641 if (ilObject::_lookupType($ref_id, true) !== "prg") {
1642 throw new ilException("Ref-Id '$ref_id' does not belong to a study programme object.");
1643 }
1644
1645 $parent = self::getInstanceByRefId($ref_id);
1646
1647 $mode = $parent->getLPMode();
1648
1649 switch ($mode) {
1651 $possible_subobjects = $subobjects;
1652 break;
1654 $possible_subobjects = [
1655 "prg" => $subobjects["prg"],
1656 "prgr" => $subobjects["prgr"]
1657 ];
1658 break;
1660 $possible_subobjects = ['crsr' => $subobjects['crsr']];
1661 break;
1662 default:
1663 throw new ilException("Undefined mode for study programme: '$mode'");
1664 }
1665
1666 if ($parent->hasAutomaticContentCategories()) {
1667 $possible_subobjects = array_filter(
1668 $possible_subobjects,
1669 static function ($subtype) {
1670 return $subtype === 'crsr';
1671 },
1672 ARRAY_FILTER_USE_KEY
1673 );
1674 }
1675 return $possible_subobjects;
1676 }
1677
1678
1679 protected function getLoggedInUserId(): int
1680 {
1681 return $this->ilUser->getId();
1682 }
1683
1684 protected function getNow(): DateTimeImmutable
1685 {
1686 return new DateTimeImmutable();
1687 }
1688
1689 protected function refreshLPStatus(int $usr_id, ?int $node_obj_id = null): void
1690 {
1691 if (is_null($node_obj_id)) {
1692 $node_obj_id = $this->getId();
1693 }
1694 ilLPStatusWrapper::_updateStatus($node_obj_id, $usr_id);
1695 }
1696
1697 public function markAccredited(
1698 int $assignment_id,
1699 int $acting_usr_id,
1700 ilPRGMessageCollection $err_collection
1701 ): void {
1702 $progress_node_id = $this->getId();
1703 $assignment = $this->assignment_repository->get($assignment_id)
1704 ->markAccredited(
1705 $this->getSettingsRepository(),
1706 $this->events,
1707 $progress_node_id,
1708 $acting_usr_id,
1709 $err_collection
1710 );
1711
1712 $this->assignment_repository->store($assignment);
1713 }
1714
1715 public function unmarkAccredited(
1716 int $assignment_id,
1717 int $acting_usr_id,
1718 ilPRGMessageCollection $err_collection
1719 ): void {
1720 $progress_node_id = $this->getId();
1721 $assignment = $this->assignment_repository->get($assignment_id)
1722 ->unmarkAccredited(
1723 $this->getSettingsRepository(),
1724 $progress_node_id,
1725 $acting_usr_id,
1726 $err_collection
1727 );
1728
1729 $this->assignment_repository->store($assignment);
1730 $this->refreshLPStatus($assignment->getUserId());
1731 }
1732
1733 public function markNotRelevant(
1734 int $assignment_id,
1735 int $acting_usr_id,
1736 ilPRGMessageCollection $err_collection
1737 ): void {
1738 $progress_node_id = $this->getId();
1739 $assignment = $this->assignment_repository->get($assignment_id)
1740 ->markNotRelevant(
1741 $this->getSettingsRepository(),
1742 $progress_node_id,
1743 $acting_usr_id,
1744 $err_collection
1745 );
1746
1747 $this->assignment_repository->store($assignment);
1748 $this->refreshLPStatus($assignment->getUserId());
1749 }
1750
1751 public function markRelevant(
1752 int $assignment_id,
1753 int $acting_usr_id,
1754 ilPRGMessageCollection $err_collection
1755 ): void {
1756 $progress_node_id = $this->getId();
1757 $assignment = $this->assignment_repository->get($assignment_id)
1758 ->markRelevant(
1759 $this->getSettingsRepository(),
1760 $progress_node_id,
1761 $acting_usr_id,
1762 $err_collection
1763 );
1764
1765 $this->assignment_repository->store($assignment);
1766 $this->refreshLPStatus($assignment->getUserId());
1767 }
1768
1769 public function changeProgressDeadline(
1770 int $assignment_id,
1771 int $acting_usr_id,
1772 ilPRGMessageCollection $err_collection,
1773 ?DateTimeImmutable $deadline
1774 ): void {
1775 $progress_node_id = $this->getId();
1776 $assignment = $this->assignment_repository->get($assignment_id)
1777 ->changeProgressDeadline(
1778 $this->getSettingsRepository(),
1779 $progress_node_id,
1780 $acting_usr_id,
1781 $err_collection,
1782 $deadline
1783 );
1784
1785 $this->assignment_repository->store($assignment);
1786 $this->refreshLPStatus($assignment->getUserId());
1787 }
1788
1790 int $assignment_id,
1791 int $acting_usr_id,
1792 ilPRGMessageCollection $err_collection,
1793 ?DateTimeImmutable $validity
1794 ): void {
1795 $progress_node_id = $this->getId();
1796 $assignment = $this->assignment_repository->get($assignment_id)
1797 ->changeProgressValidityDate(
1798 $this->getSettingsRepository(),
1799 $progress_node_id,
1800 $acting_usr_id,
1801 $err_collection,
1802 $validity
1803 );
1804
1805 $this->assignment_repository->store($assignment);
1806 $this->refreshLPStatus($assignment->getUserId());
1807 }
1808
1809 public function changeAmountOfPoints(
1810 int $assignment_id,
1811 int $acting_usr_id,
1812 ilPRGMessageCollection $err_collection,
1813 int $points
1814 ): void {
1815 $progress_node_id = $this->getId();
1816 $assignment = $this->assignment_repository->get($assignment_id)
1817 ->changeAmountOfPoints(
1818 $this->getSettingsRepository(),
1819 $progress_node_id,
1820 $acting_usr_id,
1821 $err_collection,
1822 $points
1823 );
1824
1825 $this->assignment_repository->store($assignment);
1826 $this->refreshLPStatus($assignment->getUserId());
1827 }
1828
1830 int $assignment_id,
1831 int $acting_usr_id,
1832 ?ilPRGMessageCollection $err_collection = null
1833 ): void {
1834 $assignment = $this->assignment_repository->get($assignment_id)
1836 $this->getSettingsRepository(),
1837 $acting_usr_id,
1838 $err_collection
1839 );
1840
1841 $this->assignment_repository->store($assignment);
1842 $this->refreshLPStatus($assignment->getUserId());
1843 }
1844
1845 public function acknowledgeCourses(
1846 int $assignment_id,
1847 array $nodes,
1848 ?ilPRGMessageCollection $err_collection = null
1849 ): void {
1850 $acting_usr_id = $this->getLoggedInUserId();
1851 $assignment = $this->assignment_repository->get($assignment_id);
1852 foreach ($nodes as $nodeinfo) {
1853 [$node_obj_id, $course_obj_id] = $nodeinfo;
1854
1855 $assignment = $assignment->succeed(
1856 $this->settings_repository,
1857 $node_obj_id,
1858 $course_obj_id
1859 );
1860
1861 $msg = sprintf(
1862 '%s, progress-id (%s/%s)',
1863 $assignment->getUserInformation()->getFullname(),
1864 $assignment->getId(),
1865 (string) $node_obj_id
1866 );
1867 $err_collection->add(true, 'acknowledged_course', $msg);
1868 }
1869 $this->assignment_repository->store($assignment);
1870 $this->refreshLPStatus($assignment->getUserId());
1871 }
1872
1873 public function canBeCompleted(ilPRGProgress $progress): bool
1874 {
1875 if ($this->getStatus() === ilStudyProgrammeSettings::STATUS_DRAFT) {
1876 return false;
1877 }
1878 if ($this->getLPMode() == ilStudyProgrammeSettings::MODE_LP_COMPLETED) {
1879 return true;
1880 }
1881 $possible_points = $progress->getPossiblePointsOfRelevantChildren();
1882 return $possible_points >= $progress->getAmountOfPoints();
1883 }
1884
1888 public function statusToRepr(int $status): string
1889 {
1890 $lng = $this->lng;
1891 $lng->loadLanguageModule("prg");
1892 if ($status === ilPRGProgress::STATUS_IN_PROGRESS) {
1893 return $lng->txt("prg_status_in_progress");
1894 }
1895 if ($status === ilPRGProgress::STATUS_COMPLETED) {
1896 return $lng->txt("prg_status_completed");
1897 }
1898 if ($status === ilPRGProgress::STATUS_ACCREDITED) {
1899 return $lng->txt("prg_status_accredited");
1900 }
1901 if ($status === ilPRGProgress::STATUS_NOT_RELEVANT) {
1902 return $lng->txt("prg_status_not_relevant");
1903 }
1904 if ($status === ilPRGProgress::STATUS_FAILED) {
1905 return $lng->txt("prg_status_failed");
1906 }
1907 throw new ilException("Unknown status: '$status'");
1908 }
1909
1910 public function hasContentPage(): bool
1911 {
1912 return \ilContainerPage::_exists(self::CP_TYPE, $this->getId());
1913 }
1914 public function createContentPage(): void
1915 {
1916 if ($this->hasContentPage()) {
1917 throw new \LogicException('will not create content page - it already exists.');
1918 }
1919 $new_page_object = new \ilContainerPage();
1920 $new_page_object->setId($this->getId());
1921 $new_page_object->setParentId($this->getId());
1922 $new_page_object->createFromXML();
1923 }
1924}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
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)
Class ilContainer.
Base class for ILIAS Exception handling.
static getDataDir()
get data directory (outside webspace)
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...
Cache for ilObjStudyProgrammes.
enableAutomaticMembershipSource(string $type, int $src_id, bool $search_recursive, $assign_now=false)
Enable a membership source.
getLPChildren()
Get the leafs the study programme contains.
getCertificateRelevantAssignmentIds(int ... $usr_ids)
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.
static setProgressesCompletedIfParentIsProgrammeInLPCompletedMode(int $ref_id, int $obj_id, int $user_id)
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...
getMembersOfMembershipSource(ilStudyProgrammeAutoMembershipSource $ams, ?int $exclude_id)
Get member-ids of a certain source.
updateSettings(ilStudyProgrammeSettings $settings)
changeProgressDeadline(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $deadline)
refreshLPStatus(int $usr_id, ?int $node_obj_id=null)
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.
acknowledgeCourses(int $assignment_id, array $nodes, ?ilPRGMessageCollection $err_collection=null)
setPoints(int $points)
Set the amount of points.
resetExpiryInfoSentFor(ilPRGAssignment $ass)
deleteAllAutomaticContentCategories()
Delete all configuration of categories with auto-content for this StudyProgramme;.
static getInstanceByObjId(int $obj_id)
ilPRGAssignmentDBRepository $assignment_repository
getReferencesTo(ilObjStudyProgramme $prg)
static setProgressesCompletedFor(int $obj_id, int $user_id)
Succeed all StudyProgramme(Nodes) where the object with the given id (a CRSR) is in a Programme with ...
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.
cloneObject(int $target_ref_id, int $copy_id=0, bool $omit_tree=false)
deleteAllAutomaticMembershipSources()
Delete all membership sources of this StudyProgramme;.
getPoints()
Get the amount of points.
assignUser(int $usr_id, ?int $acting_usr_id=null, $raise_event=true)
Assign a user to this node at the study program.
removeAssignment(ilPRGAssignment $assignment)
Remove an assignment from this program.
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.
getLocalMembers()
get usr_ids with assignment on this node
getCompletedCourses(ilPRGAssignment $assignment)
Get courses in this program that the given user already completed.
disableAutomaticMembershipSource(string $type, int $src_id, bool $search_recursive)
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.
updatePlanFromRepository(int $assignment_id, int $acting_usr_id, ?ilPRGMessageCollection $err_collection=null)
static addMemberToProgrammes(string $src_type, int $src_id, int $usr_id)
ilStudyProgrammeTypeDBRepository $type_repository
CustomIconFactory $custom_icon_factory
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.
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.
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.
succeed(int $usr_id, int $triggering_obj_id, ?ilPRGAssignment $ass=null)
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.
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:
storeAutomaticMembershipSource(string $type, int $src_id, bool $search_recursive)
Store a source to be monitored for automatic memberships.
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.
Class ilObjectFactoryWrapper.
Class ilObject Basic functions for all objects.
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
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
getProgresses(array &$ret=[], ?ilPRGProgress $pgs=null)
getProgressForNode(int $node_id)
Holds information about multi-actions, mainly in context of member-assignemnts and status changes.
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...
ILIAS Setting Class.
Provides adapters to read member-ids from a specific source.
getObjId()
Get the id of the study program.
Exception is thrown when invariants on the program tree would be violated by manipulation of tree.
Class ilStudyProgrammeType.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
isDeleted(int $a_node_id)
This is a wrapper for isSaved() with a more useful name.
getRefIdFor(int $obj_id)
updatePlanFromRepository(ilStudyProgrammeSettingsRepository $settings_repo, int $acting_usr_id, ilPRGMessageCollection $err_collection)
ilCertificateTemplateRepository $certificate_template_repository
The filesystem interface provides the public interface for the Filesystem service API consumer.
Definition: Filesystem.php:37
fetchCurrentlyUsedCertificate(int $objId)
Covers the persistence of settings belonging to a study programme (SP).
$ref_id
Definition: ltiauth.php:66
$dic
Definition: ltiresult.php:33
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
get(string $class_name)
global $lng
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26