ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilObjStudyProgramme.php
Go to the documentation of this file.
1 <?php
2 
19 declare(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 
62  protected Filesystem $webdir;
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 
106  self::initStudyProgrammeCache();
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  {
152  return self::getInstanceByRefId(self::getRefIdFor($obj_id));
153  }
154 
155  public static function getInstanceByObjId(int $obj_id): ilObjStudyProgramme
156  {
157  return self::getInstanceByRefId(self::getRefIdFor($obj_id));
158  }
159 
161  {
162  if (self::$study_programme_cache === null) {
163  self::initStudyProgrammeCache();
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 
404  public function getSubType(): ?ilStudyProgrammeType
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  {
534  $tree = $this->tree;
535  return array_filter(
536  array_map(
537  static function ($id) {
538  $refs = ilObject::_getAllReferences((int) $id);
539  return new ilObjStudyProgrammeReference(
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 
1225  public function deleteAllAutomaticContentCategories(): void
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 
1355  public function deleteAllAutomaticMembershipSources(): void
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)) {
1428  $assigned_by = ilStudyProgrammeAutoMembershipSource::SOURCE_MAPPING[$src_type];
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 
1808  public function updatePlanFromRepository(
1809  int $assignment_id,
1810  int $acting_usr_id,
1811  ilPRGMessageCollection $err_collection = null
1812  ): void {
1813  $assignment = $this->assignment_repository->get($assignment_id)
1814  ->updatePlanFromRepository(
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  {
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 }
getCompletedCourses(int $usr_id)
Get courses in this program that the given user already completed.
setStatus(int $a_status)
Set the status of the node.
static _hasUserCompleted(int $a_obj_id, int $a_user_id)
Lookup user object completion.
adjustLPMode()
Adjust the lp mode to match current state of tree:
string $type
array $settings
Setting values (LTI parameters, custom parameters and local parameters).
Definition: System.php:200
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addNode(ilObjStudyProgramme $a_prg)
Inserts another ilObjStudyProgramme in this object.
clearLPChildrenCache()
Clear the cached lp children.
static addCrsToProgrammes(int $crs_ref_id, int $cat_ref_id)
Check, if a category is under surveilllance and automatically add the course.
getSubType()
Gets the SubType Object.
static _lookupTitle(int $obj_id)
markRelevant(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
storeAutomaticContentCategory(int $category_ref_id)
Store a Category with auto-content for this StudyProgramme; a category can only be referenced once (p...
static getLogger(string $a_component_id)
Get component logger.
getParent()
Get the parent ilObjStudyProgramme of this object.
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
getApplicableMembershipSourceForUser(int $usr_id, ?int $exclude_id)
changeProgressValidityDate(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $validity)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
isAutoContentApplicable()
AutoContent should only be available in active- or draft-mode, and only, if there is no sub-programme...
assignUser(int $usr_id, int $acting_usr_id=null, $raise_event=true)
Assign a user to this node at the study program.
getMembers()
get usr_ids with any progress on this node
unmarkAccredited(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
ilStudyProgrammeMembershipSourceReaderFactory $membersourcereader_factory
static _lookupFullname(int $a_user_id)
getRefIdFor(int $obj_id)
getChildren(bool $include_references=false)
Get all ilObjStudyProgrammes that are direct children of this object.
static getProgrammesMonitoringMemberSource(string $src_type, int $src_id)
Get all StudyProgrammes monitoring this membership-source.
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.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getAllReferences(int $id)
get all reference ids for object ID
nodeInserted($prg)
Clears child cache and adds progress for new node.
ilTree $tree
isInTree(?int $a_node_id)
get all information of a node.
isDeleted(int $a_node_id)
This is a wrapper for isSaved() with a more useful name.
__construct(int $id=0, bool $call_by_reference=true)
ATTENTION: After using the constructor the object won&#39;t be in the cache.
static saveObjRecSelection(int $a_obj_id, string $a_sub_type="", array $a_records=null, bool $a_delete_before=true)
Save repository object record selection.
disableAutomaticMembershipSource(string $type, int $src_id)
Disable a membership source.
applyToSubTreeNodes(Closure $fun, bool $include_references=false)
Apply the given Closure to every node in the subtree starting at this object.
static getCreatableSubObjects(array $subobjects, $ref_id)
Filter the list of possible subobjects for the objects that actually could be created on a concrete n...
loadLanguageModule(string $a_module)
Load language module.
deleteAssignmentsAndProgresses()
Delete all assignments from the DB.
markNotRelevant(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
storeAutomaticMembershipSource(string $type, int $src_id)
Store a source to be monitored for automatic memberships.
hasAssignmentOf(int $user_id)
Check whether user is assigned to this program or any node above.
storeRiskyToFailSentFor(ilPRGAssignment $ass)
storeExpiryInfoSentFor(ilPRGAssignment $ass)
getLocalMembers()
get usr_ids with assignment on this node
getAssignmentsOf(int $user_id)
Get the assignments of user at this program or any node above.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getParentId(ilObjCourseReference $leaf)
Get the obj id of the parent object for the given object.
changeProgressDeadline(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, ?DateTimeImmutable $deadline)
getAmountOfLPChildren()
Get the amount of leafs the study programme contains.
enableAutomaticMembershipSource(string $type, int $src_id, bool $assign_now=false)
Enable a membership source.
getRoot()
Get the ilObjStudyProgramme that is the root node of the tree this programme is in.
static getProgrammesMonitoringCategory(int $cat_ref_id)
Get all (not OUTDATED) StudyProgrammes monitoring this category.
static removeCrsFromProgrammes(int $crs_ref_id, int $cat_ref_id)
Check, if a category is under surveillance and automatically remove the deleted course.
global $DIC
Definition: feed.php:28
resetRiskyToFailSentFor(ilPRGAssignment $ass)
createReference()
creates reference for object
removeNode(ilObjStudyProgramme $a_prg)
Remove a node from this object.
hasAssignments()
Are there any assignments on this node or any node above?
A Progress is the status of a user on a single node of an assignment; it is unique by assignment_id:u...
getObjIdsOfChildren(int $node_obj_id)
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
$nd
Definition: error.php:12
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...
clearChildrenCache()
Clear the cached children.
getAutomaticContentCategories()
Get configuration of categories with auto-content for this StudyProgramme;.
getParentNodeData(int $a_node_id)
get data of parent node from tree and object_data
resetExpiryInfoSentFor(ilPRGAssignment $ass)
deleteAllAutomaticContentCategories()
Delete all configuration of categories with auto-content for this StudyProgramme;.
ilStudyProgrammeAutoMembershipsDBRepository $auto_memberships_repository
hasRelevantProgresses()
Are there any users that have a relevant progress on this programme?
removeAssignment(ilPRGAssignment $assignment)
Remove an assignment from this program.
ilLanguage $lng
static addMemberToProgrammes(string $src_type, int $src_id, int $usr_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
bool $call_by_reference
getParents(bool $include_references=false)
Get all parents of the node, where the root of the program comes first.
ilDBInterface $db
getAssignmentsOfSingleProgramForUser(int $usr_id)
Get assignments of user to this program-node only.
static ilObjStudyProgrammeCache $study_programme_cache
getSpecificAssignment(int $assignment_id)
acknowledgeCourses(int $assignment_id, array $nodes, ilPRGMessageCollection $err_collection=null)
getProgresses(array &$ret=[], ilPRGProgress $pgs=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupObjectId(int $ref_id)
statusToRepr(int $status)
Get a user readable representation of a status.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
hasAssignmentsOfSingleProgramForUser(int $usr_id)
Get assignments of user to this program-node only.
markAccredited(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection)
changeAmountOfPoints(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection, int $points)
moveTo(ilObjStudyProgramme $new_parent)
Move this tree node to a new parent.
succeed(int $usr_id, int $triggering_obj_id, ilPRGAssignment $ass=null)
getProgressIdString(ilPRGAssignment $assignment, ilPRGProgress $progress)
static removeMemberFromProgrammes(string $src_type, int $src_id, int $usr_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupSourceIds(int $a_target_id)
Get ids of all container references that target the object with the given id.
getMembersOfMembershipSource(string $src_type, int $src_id)
Get member-ids of a certain source.
canBeCompleted(ilPRGProgress $progress)
setPoints(int $points)
Set the amount of points.
updatePlanFromRepository(int $assignment_id, int $acting_usr_id, ilPRGMessageCollection $err_collection=null)
static getInstanceByObjId(int $obj_id)
getLastChange()
Get the timestamp of the last change on this program or sub program.
ilStudyProgrammeEvents $events
getObjId()
Get the id of 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 ...
ilPRGAssignmentDBRepository $assignment_repository
addMissingProgresses()
Add missing progress records for all assignments of this programm.
getReferencesTo(ilObjStudyProgramme $prg)
Class ilStudyProgrammeType.
static getAllChildren(int $a_ref_id, bool $include_references=false)
Get a list of all ilObjStudyProgrammes in the subtree starting at $a_ref_id.
canBeRemoved()
Check weather a node can be removed.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAutomaticMembershipSources()
Get sources for auto-memberships.
getDepth()
Get the depth of this StudyProgramme in the tree starting at the topmost StudyProgramme (not root nod...
hasChildren(bool $include_references=false)
Does this StudyProgramme have other ilObjStudyProgrammes as children?
__construct(Container $dic, ilPlugin $plugin)
ilStudyProgrammeAutoCategoryDBRepository $auto_categories_repository
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
putInTree(int $parent_ref_id)
Overwritten from ilObject.
ilObjectFactoryWrapper $object_factory
static _getInstance(int $a_obj_id)
static _lookupTargetRefId(int $a_obj_id)
getLPChildrenIds()
Get the obj-ids of the leafs the program contains.
static _lookupTargetId(int $a_obj_id)
$dic
Definition: result.php:32
static createInstance()
Create an instance of ilObjStudyProgramme, put in cache.
static getRefIdFor(int $obj_id)
deleteAutomaticContentCategories(array $category_ids=[])
Delete configuration of categories with auto-content for this StudyProgramme;.
getPoints()
Get the amount of points.
ilStudyProgrammeSettingsDBRepository $settings_repository
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
static _lookupType(int $id, bool $reference=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAmountOfChildren($include_references=false)
Get the amount of other StudyProgrammes this StudyProgramme has as children.
refreshLPStatus(int $usr_id, int $node_obj_id=null)
getAmountOfAssignmentsOf(int $user_id)
Get the amount of assignments a user has on this program node or any node above.
ilObjectCustomIconFactory $custom_icon_factory
static _lookupDeletedDate(int $ref_id)
Class FlySystemFileAccessTest disabled disabled disabled.
deleteAllAutomaticMembershipSources()
Delete all membership sources of this StudyProgramme;.
updateLastChange()
Update last change timestamp on this node and its parents.
clearParentCache()
Clear the cached parent to query it again at the tree.
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
deleteAutomaticMembershipSource(string $type, int $src_id)
Delete a membership source.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilStudyProgrammeTypeDBRepository $type_repository
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
updateSettings(ilStudyProgrammeSettings $settings)