ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
class.ilStudyProgrammeUserProgress.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 2015 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */
4
5require_once("./Modules/StudyProgramme/classes/model/class.ilStudyProgrammeProgress.php");
6
16 protected $progress; // ilStudyProgrammeProgress
17
27 public function __construct($a_ids_or_model) {
28 if ($a_ids_or_model instanceof ilStudyProgrammeProgress) {
29 $this->progress = $a_ids_or_model;
30 }
31 else {
32 if (count($a_ids_or_model) != 3) {
33 throw new ilException("ilStudyProgrammeUserProgress::__construct: "
34 ."expected array with 3 items.");
35 }
36
37 // TODO: ActiveRecord won't be caching the model objects, since
38 // we are not using find. Maybe we should do this ourselves??
39 // Or should we instead cache in getInstance?
40 $this->progress = array_shift(
42 ( "assignment_id" => $a_ids_or_model[0]
43 , "prg_id" => $a_ids_or_model[1]
44 , "usr_id" => $a_ids_or_model[2]
45 ))->get());
46 }
47 if ($this->progress === null) {
48 throw new ilException("ilStudyProgrammeUserProgress::__construct: Could not find progress.");
49 }
50 }
51
61 static public function getInstance($a_assignment_id, $a_program_id, $a_user_id) {
62 return new ilStudyProgrammeUserProgress(array($a_assignment_id, $a_program_id, $a_user_id));
63 }
64
71 static public function getInstanceById($a_prgrs_id) {
72 $prgrs = ilStudyProgrammeProgress::find($a_prgrs_id);
73 if ($prgrs === null) {
74 throw new ilException("Unknown progress id $a_prgrs_id.");
75 }
76 return new ilStudyProgrammeUserProgress($prgrs);
77 }
78
86 static public function getInstancesForUser($a_program_id, $a_user_id) {
87 $progresses = ilStudyProgrammeProgress::where(array
88 ( "prg_id" => $a_program_id
89 , "usr_id" => $a_user_id
90 ))->get();
91 return array_values(array_map(function($dat) {
92 return new ilStudyProgrammeUserProgress($dat);
93 }, $progresses));
94 }
95
106 static public function getInstanceForAssignment($a_program_id, $a_assignment_id) {
107 $progresses = ilStudyProgrammeProgress::where(array
108 ( "prg_id" => $a_program_id
109 , "assignment_id" => $a_assignment_id
110 ))->get();
111 if (count($progresses) == 0) {
112 require_once("Modules/StudyProgramme/classes/exceptions/class.ilStudyProgrammeNoProgressForAssignmentException.php");
114 ("ilStudyProgrammeUserProgress::getInstanceForAssignment: "
115 ."Assignment '$a_assignment_id' does not belong to program "
116 ."'$a_program_id'");
117 }
118 return new ilStudyProgrammeUserProgress(array_shift($progresses));
119 }
120
131 static public function getInstancesForAssignment($a_assignment_id) {
132 $progresses = ilStudyProgrammeProgress::where(array
133 ( "assignment_id" => $a_assignment_id
134 ))->get();
135 if (count($progresses) == 0) {
136 require_once("Modules/StudyProgramme/classes/exceptions/class.ilStudyProgrammeNoProgressForAssignmentException.php");
138 ("ilStudyProgrammeUserProgress::getInstancesForAssignment: "
139 ."Can't find progresses for assignment '$a_assignment_id'.");
140 }
141 return array_map(function($dat) {
142 return new ilStudyProgrammeUserProgress($dat);
143 }, $progresses);
144 }
145
152 static public function getInstancesForProgram($a_program_id) {
153 $progresses = ilStudyProgrammeProgress::where(array
154 ( "prg_id" => $a_program_id
155 ))->get();
156 return array_values(array_map(function($dat) {
157 return new ilStudyProgrammeUserProgress($dat);
158 }, $progresses));
159 }
160
164 static public function statusToRepr($a_status) {
165 global $lng;
166 $lng->loadLanguageModule("prg");
167
169 return $lng->txt("prg_status_in_progress");
170 }
172 return $lng->txt("prg_status_completed");
173 }
175 return $lng->txt("prg_status_accredited");
176 }
178 return $lng->txt("prg_status_not_relevant");
179 }
180 throw new ilException("Unknown status: '$a_status'");
181 }
182
193 public function getStudyProgramme() {
194 require_once("./Modules/StudyProgramme/classes/class.ilObjStudyProgramme.php");
195 $refs = ilObject::_getAllReferences($this->progress->getNodeId());
196 if (!count($refs)) {
197 throw new ilException("ilStudyProgrammeUserAssignment::getStudyProgramme: "
198 ."could not find ref_id for program '"
199 .$this->progress->getNodeId()."'.");
200 }
201 return ilObjStudyProgramme::getInstanceByRefId(array_shift($refs));
202 }
203
209 public function getAssignment() {
210 require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeUserAssignment.php");
211 return ilStudyProgrammeUserAssignment::getInstance($this->progress->getAssignmentId());
212 }
213
219 public function getId() {
220 return $this->progress->getId();
221 }
222
228 public function getNodeId() {
229 return $this->progress->getNodeId();
230 }
231
237 public function getUserId() {
238 return $this->progress->getUserId();
239 }
240
246 public function getStatus() {
247 return $this->progress->getStatus();
248 }
249
256 public function getAmountOfPoints() {
257 return $this->progress->getAmountOfPoints();
258 }
259
265 public function getCurrentAmountOfPoints() {
266 if ( $this->isAccredited()
267 || ($this->isSuccessful() && $this->getStudyProgramme()->hasLPChildren())) {
268 return $this->getAmountOfPoints();
269 }
270 return $this->progress->getCurrentAmountOfPoints();
271 }
272
278 public function getLastChange() {
279 return $this->progress->getLastChange();
280 }
281
287 public function getLastChangeBy() {
288 return $this->progress->getLastChangeBy();
289 }
290
296 public function getCompletionBy() {
297 return $this->progress->getCompletionBy();
298 }
299
303 public function delete() {
304 $this->progress->delete();
305 }
306
307
318 public function markAccredited($a_user_id) {
320 $prg = $this->getStudyProgramme();
321 if ($prg->getStatus() == ilStudyProgramme::STATUS_OUTDATED) {
322 throw new ilException("ilStudyProgrammeUserProgress::markAccredited: "
323 ."Can't mark as accredited since program is outdated.");
324 }
325 }
326
327 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_ACCREDITED)
328 ->setCompletionBy($a_user_id)
329 ->update();
330
331 require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeEvents.php");
333
334 $this->updateParentStatus();
335 return $this;
336 }
337
346 public function unmarkAccredited() {
347 if ($this->progress->getStatus() != ilStudyProgrammeProgress::STATUS_ACCREDITED) {
348 throw new ilException("Expected status ACCREDITED.");
349 }
350
351 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_IN_PROGRESS)
352 ->setCompletionBy(null)
353 ->update();
354
355 $this->refreshLPStatus();
356
357 $this->updateParentStatus();
358 return $this;
359 }
360
370 public function markNotRelevant($a_user_id) {
371 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_NOT_RELEVANT)
372 ->setCompletionBy($a_user_id)
373 ->setLastChangeBy($a_user_id)
374 ->update();
375
376 $this->updateStatus();
377 return $this;
378 }
379
389 public function markRelevant($a_user_id) {
390 if ($this->progress->getStatus() != ilStudyProgrammeProgress::STATUS_NOT_RELEVANT) {
391 throw new ilException("Expected status IN_PROGRESS.");
392 }
393
394 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_IN_PROGRESS)
395 ->setCompletionBy($a_user_id)
396 ->setLastChangeBy($a_user_id)
397 ->update();
398
399 $this->updateStatus();
400 return $this;
401 }
402
413 public function setRequiredAmountOfPoints($a_points, $a_user_id) {
414 $this->progress->setAmountOfPoints($a_points)
415 ->setLastChangeBy($a_user_id)
416 ->update();
417
418 $this->updateStatus();
419 return $this;
420 }
421
434 public function getMaximumPossibleAmountOfPoints($only_relevant = false) {
435 $prg = $this->getStudyProgramme();
436 if ($prg->getLPMode() == ilStudyProgramme::MODE_LP_COMPLETED) {
437 return $this->getAmountOfPoints();
438 }
439 $children = $prg->getChildren();
440 $ass = $this->progress->getAssignmentId();
441 $points = array_map(function($child) use ($ass, $only_relevant) {
442 $relevant = $child->getProgressForAssignment($ass)->isRelevant();
443 if($only_relevant) {
444 if($relevant) {
445 return $child->getProgressForAssignment($ass)->getAmountOfPoints();
446 } else {
447 return 0;
448 }
449 } else {
450 return $child->getProgressForAssignment($ass)->getAmountOfPoints();
451 }
452 }, $children);
453
454 return array_reduce($points, function($a, $b) { return $a + $b; }, 0);
455 }
456
463 public function canBeCompleted() {
464 $prg = $this->getStudyProgramme();
465
466 if ($prg->getLPMode() == ilStudyProgramme::MODE_LP_COMPLETED) {
467 return true;
468 }
469
470 if ($this->getMaximumPossibleAmountOfPoints(true) < $this->getAmountOfPoints()) {
471 // Fast track
472 return false;
473 }
474
475 $children_progress = $this->getChildrenProgress();
476 foreach ($children_progress as $progress) {
477 if ($progress->isRelevant() && !$progress->canBeCompleted()) {
478 return false;
479 }
480 }
481 return true;
482 }
483
489 public function hasIndividualModifications() {
490 return $this->getLastChangeBy() !== null;
491 }
492
499 public function isSuccessful() {
500 $status = $this->getStatus();
501
504 }
505
511 public function isAccredited() {
512 $status = $this->getStatus();
513
515 }
516
522 public function isRelevant() {
524 }
525
533 public function updateFromProgramNode() {
534 if ($this->hasIndividualModifications()) {
535 return false;
536 }
538 return false;
539 }
540
541 $prg = $this->getStudyProgramme();
542 $this->progress->setAmountOfPoints($prg->getPoints())
543 ->setStatus($prg->getStatus() == ilStudyProgramme::STATUS_ACTIVE
546 )
547 ->update();
548
549 $this->updateStatus();
550 }
551
556 protected function updateStatus() {
557 $prg = $this->getStudyProgramme();
558 if (( $prg->getLPMode() == ilStudyProgramme::MODE_LP_COMPLETED
559 && $this->getStatus() != ilStudyProgrammeProgress::STATUS_ACCREDITED)
560 || $this->getStatus() == ilStudyProgrammeProgress::STATUS_NOT_RELEVANT) {
561 // Nothing to do here, as the status will be set by LP.
562 // OR current status is NOT RELEVANT
563 return;
564 }
565
566 $add = function($a, $b) { return $a + $b; };
567 $get_points = function($child) {
568 if (!$child->isSuccessful()) {
569 return 0;
570 }
571 return $child->getAmountOfPoints();
572 };
573
574 $achieved_points = array_reduce(array_map($get_points, $this->getChildrenProgress()), $add);
575 if (!$achieved_points) {
576 $achieved_points = 0;
577 }
578 $successful = $achieved_points >= $this->getAmountOfPoints() && $this->hasSuccessfullChildren();
579 $status = $this->getStatus();
580
581 $this->progress->setCurrentAmountOfPoints($achieved_points);
582 if ($successful) {
583 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_COMPLETED);
584 require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeEvents.php");
586 } else {
587 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_IN_PROGRESS);
588 }
589
590 $this->progress->update();
591 $this->refreshLPStatus();
592 $this->updateParentStatus();
593 }
594
595 protected function hasSuccessfullChildren()
596 {
597 foreach($this->getChildrenProgress() as $child) {
598 if($child->isSuccessful()) {
599 return true;
600 }
601 }
602 return false;
603 }
604
608 protected function updateParentStatus() {
609 $parent = $this->getParentProgress();
610 if ($parent) {
611 $parent->updateStatus();
612 }
613 }
614
625 public function setLPCompleted($a_obj_id, $a_usr_id) {
626 if ($this->isSuccessful() || !$this->isRelevant()) {
627 return true;
628 }
629
630 $prg = $this->getStudyProgramme();
631 if ($prg->getLPMode() != ilStudyProgramme::MODE_LP_COMPLETED) {
632 throw new ilException("ilStudyProgrammeUserProgress::setLPCompleted: "
633 ."The node '".$prg->getId()."' is not in LP_COMPLETED mode.");
634 }
635 if ($this->getUserId() != $a_usr_id) {
636 throw new ilException("ilStudyProgrammeUserProgress::setLPCompleted: "
637 ."This progress does belong to user '".$this->getUserId()
638 ."' and not to user '$a_usr_id'");
639 }
640 if (!in_array($a_obj_id, $prg->getLPChildrenIds())) {
641 throw new ilException("ilStudyProgrammeUserProgress::setLPCompleted: "
642 ."Object '$a_obj_id' is no child of node '".$prg->getId()."'.");
643 }
644
645 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_COMPLETED)
646 ->setCompletionBy($a_obj_id)
647 ->update();
648
649 require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeEvents.php");
651
652 $this->refreshLPStatus();
653 $this->updateParentStatus();
654 }
655
660 protected function getParentProgress() {
661 $prg = $this->getStudyProgramme();
662 $parent = $prg->getParent();
663 if (!$parent) {
664 return null;
665 }
666
667 if($this->getStudyProgramme()->getId() == $this->getAssignment()->getStudyProgramme()->getId()) {
668 return null;
669 }
670
671 return $parent->getProgressForAssignment($this->progress->getAssignmentId());
672 }
673
680 public function getChildrenProgress() {
681 $prg = $this->getStudyProgramme();
682 if ($prg->getLPMode() == ilStudyProgramme::MODE_LP_COMPLETED) {
683 throw new ilException("ilStudyProgrammeUserProgress::getChildrenProgress: "
684 ."There is some problem in the implementation. This "
685 ."method should only be callled for nodes in points "
686 ."mode.");
687 }
688
689 $ass_id = $this->progress->getAssignmentId();
690 return array_map(function($child) use ($ass_id) {
691 return $child->getProgressForAssignment($ass_id);
692 }, $prg->getChildren());
693 }
694
703 $prg = $this->getStudyProgramme();
704 $children = $prg->getChildren();
705 $ass_id = $this->progress->getAssignmentId();
706 $names = array();
707 foreach ($children as $child) {
708 $prgrs = $child->getProgressForAssignment($ass_id);
709 if (!$prgrs->isSuccessful()) {
710 continue;
711 }
712 $names[] = $child->getTitle();
713 }
714 return $names;
715 }
716
717 const ACTION_MARK_ACCREDITED = "mark_accredited";
718 const ACTION_UNMARK_ACCREDITED = "unmark_accredited";
719 const ACTION_SHOW_INDIVIDUAL_PLAN = "show_individual_plan";
720 const ACTION_REMOVE_USER = "remove_user";
721
729 static public function getPossibleActions($a_node_id, $a_root_prg_id, $a_status) {
730 $actions = array();
731 if ($a_node_id == $a_root_prg_id) {
733 $actions[] = self::ACTION_REMOVE_USER;
734 }
737 }
738 else if ($a_status == ilStudyProgrammeProgress::STATUS_IN_PROGRESS) {
739 $actions[] = self::ACTION_MARK_ACCREDITED;
740 }
741 return $actions;
742 }
743
744 protected function refreshLPStatus() {
745 require_once("Services/Tracking/classes/class.ilLPStatusWrapper.php");
747 }
748}
749
750?>
static where($where, $operator=NULL)
Base class for ILIAS Exception handling.
_refreshStatus($a_obj_id, $a_users=null)
Set dirty.
static getInstanceByRefId($a_ref_id)
Get an instance of ilObjStudyProgramme, use cache.
static _getAllReferences($a_id)
get all reference ids of object
static userSuccessful(ilStudyProgrammeUserProgress $a_progress)
Exception is thrown when a progress for some programme node and assignment is missing.
Class ilStudyProgrammeProgress.
Represents the progress of a user at one node of a study programme.
markNotRelevant($a_user_id)
Set the node to be not relevant for the user.
getCompletionBy()
Get the id of the user or course that lead to completion of this node.
getChildrenProgress()
Get the progresses on the child nodes of this node for the same assignment this progress belongs to.
static getInstance($a_assignment_id, $a_program_id, $a_user_id)
Get an instance.
markRelevant($a_user_id)
Set the node to be relevant for the user.
getMaximumPossibleAmountOfPoints($only_relevant=false)
Get the maximum possible amount of points a user can achieve for the completion of this node.
getStatus()
Get the status of the progress.
updateStatus()
Updates the status of this progress based on the status of the progress on the sub nodes.
static statusToRepr($a_status)
Get a user readable representation of a status.
getNamesOfCompletedOrAccreditedChildren()
Get a list with the names of the children of this node that a were completed or accredited for the gi...
__construct($a_ids_or_model)
Throws when id does not refer to a study programme progress.
canBeCompleted()
Check whether the user can achieve enough points on the subnodes to be able to complete this node.
getNodeId()
Get the id of the program node the progress belongs to.
static getInstancesForUser($a_program_id, $a_user_id)
Get the instances that user has on program.
isAccredited()
Check whether the user was accredited on this node.
unmarkAccredited()
Set the node to in progress.
isSuccessful()
Check whether the user was successful on this node.
setLPCompleted($a_obj_id, $a_usr_id)
Set this node to be completed due to a completed learning progress.
getCurrentAmountOfPoints()
Get the amount of points the user currently achieved.
static getInstanceForAssignment($a_program_id, $a_assignment_id)
Get the instance for the assignment on the program.
static getInstancesForAssignment($a_assignment_id)
Get the instance for an assignment.
static getPossibleActions($a_node_id, $a_root_prg_id, $a_status)
Get a list with possible actions on a progress record.
setRequiredAmountOfPoints($a_points, $a_user_id)
Set the amount of points the user is required to have to complete this node.
getAssignment()
Get the assignment this progress belongs to.
updateParentStatus()
Update the status of the parent of this node.
static getInstanceById($a_prgrs_id)
Get an instance by progress id.
getUserId()
Get the id of the user who is assigned.
getAmountOfPoints()
Get the amount of points needed to complete the node.
hasIndividualModifications()
Check whether there are individual modifications for the user on this program.
getStudyProgramme()
Get the program node where this progress belongs to was made.
static getInstancesForProgram($a_program_id)
Get the instances for a program node.
getParentProgress()
Get the progress on the parent node for the same assignment this progress belongs to.
markAccredited($a_user_id)
Mark this progress as accredited.
updateFromProgramNode()
Update the progress from its program node.
isRelevant()
Check whether this node is relevant for the user.
getLastChange()
Get the timestamp when the last change was made on this progress.
getLastChangeBy()
Get the id of the user who did the last change on this progress.
global $lng
Definition: privfeed.php:40