ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 $DIC;
166 $lng = $DIC['lng'];
167 $lng->loadLanguageModule("prg");
168
170 return $lng->txt("prg_status_in_progress");
171 }
173 return $lng->txt("prg_status_completed");
174 }
176 return $lng->txt("prg_status_accredited");
177 }
179 return $lng->txt("prg_status_not_relevant");
180 }
181 throw new ilException("Unknown status: '$a_status'");
182 }
183
194 public function getStudyProgramme() {
195 require_once("./Modules/StudyProgramme/classes/class.ilObjStudyProgramme.php");
196 $refs = ilObject::_getAllReferences($this->progress->getNodeId());
197 if (!count($refs)) {
198 throw new ilException("ilStudyProgrammeUserAssignment::getStudyProgramme: "
199 ."could not find ref_id for program '"
200 .$this->progress->getNodeId()."'.");
201 }
202 return ilObjStudyProgramme::getInstanceByRefId(array_shift($refs));
203 }
204
210 public function getAssignment() {
211 require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeUserAssignment.php");
212 return ilStudyProgrammeUserAssignment::getInstance($this->progress->getAssignmentId());
213 }
214
220 public function getId() {
221 return $this->progress->getId();
222 }
223
229 public function getNodeId() {
230 return $this->progress->getNodeId();
231 }
232
238 public function getUserId() {
239 return $this->progress->getUserId();
240 }
241
247 public function getStatus() {
248 return $this->progress->getStatus();
249 }
250
257 public function getAmountOfPoints() {
258 return $this->progress->getAmountOfPoints();
259 }
260
266 public function getCurrentAmountOfPoints() {
267 if ( $this->isAccredited()
268 || ($this->isSuccessful() && $this->getStudyProgramme()->hasLPChildren())) {
269 return $this->getAmountOfPoints();
270 }
271 return $this->progress->getCurrentAmountOfPoints();
272 }
273
279 public function getLastChange() {
280 return $this->progress->getLastChange();
281 }
282
288 public function getLastChangeBy() {
289 return $this->progress->getLastChangeBy();
290 }
291
297 public function getCompletionBy() {
298 return $this->progress->getCompletionBy();
299 }
300
304 public function delete() {
305 $this->progress->delete();
306 }
307
308
319 public function markAccredited($a_user_id) {
321 $prg = $this->getStudyProgramme();
322 if ($prg->getStatus() == ilStudyProgramme::STATUS_OUTDATED) {
323 throw new ilException("ilStudyProgrammeUserProgress::markAccredited: "
324 ."Can't mark as accredited since program is outdated.");
325 }
326 }
327
328 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_ACCREDITED)
329 ->setCompletionBy($a_user_id)
330 ->update();
331
332 require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeEvents.php");
334
335 $this->updateParentStatus();
336 return $this;
337 }
338
347 public function unmarkAccredited() {
348 if ($this->progress->getStatus() != ilStudyProgrammeProgress::STATUS_ACCREDITED) {
349 throw new ilException("Expected status ACCREDITED.");
350 }
351
352 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_IN_PROGRESS)
353 ->setCompletionBy(null)
354 ->update();
355
356 $this->refreshLPStatus();
357
358 $this->updateParentStatus();
359 return $this;
360 }
361
371 public function markNotRelevant($a_user_id) {
372 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_NOT_RELEVANT)
373 ->setCompletionBy($a_user_id)
374 ->setLastChangeBy($a_user_id)
375 ->update();
376
377 $this->updateStatus();
378 return $this;
379 }
380
390 public function markRelevant($a_user_id) {
391 if ($this->progress->getStatus() != ilStudyProgrammeProgress::STATUS_NOT_RELEVANT) {
392 throw new ilException("Expected status IN_PROGRESS.");
393 }
394
395 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_IN_PROGRESS)
396 ->setCompletionBy($a_user_id)
397 ->setLastChangeBy($a_user_id)
398 ->update();
399
400 $this->updateStatus();
401 return $this;
402 }
403
414 public function setRequiredAmountOfPoints($a_points, $a_user_id) {
415 $this->progress->setAmountOfPoints($a_points)
416 ->setLastChangeBy($a_user_id)
417 ->update();
418
419 $this->updateStatus();
420 return $this;
421 }
422
435 public function getMaximumPossibleAmountOfPoints($only_relevant = false) {
436 $prg = $this->getStudyProgramme();
437 if ($prg->getLPMode() == ilStudyProgramme::MODE_LP_COMPLETED) {
438 return $this->getAmountOfPoints();
439 }
440 $children = $prg->getChildren();
441 $ass = $this->progress->getAssignmentId();
442 $points = array_map(function($child) use ($ass, $only_relevant) {
443 $relevant = $child->getProgressForAssignment($ass)->isRelevant();
444 if($only_relevant) {
445 if($relevant) {
446 return $child->getProgressForAssignment($ass)->getAmountOfPoints();
447 } else {
448 return 0;
449 }
450 } else {
451 return $child->getProgressForAssignment($ass)->getAmountOfPoints();
452 }
453 }, $children);
454
455 return array_reduce($points, function($a, $b) { return $a + $b; }, 0);
456 }
457
464 public function canBeCompleted() {
465 $prg = $this->getStudyProgramme();
466
467 if ($prg->getLPMode() == ilStudyProgramme::MODE_LP_COMPLETED) {
468 return true;
469 }
470
471 if ($this->getMaximumPossibleAmountOfPoints(true) < $this->getAmountOfPoints()) {
472 // Fast track
473 return false;
474 }
475
476 $children_progress = $this->getChildrenProgress();
477 foreach ($children_progress as $progress) {
478 if ($progress->isRelevant() && !$progress->canBeCompleted()) {
479 return false;
480 }
481 }
482 return true;
483 }
484
490 public function hasIndividualModifications() {
491 return $this->getLastChangeBy() !== null;
492 }
493
500 public function isSuccessful() {
501 $status = $this->getStatus();
502
505 }
506
512 public function isAccredited() {
513 $status = $this->getStatus();
514
516 }
517
523 public function isRelevant() {
525 }
526
534 public function updateFromProgramNode() {
535 if ($this->hasIndividualModifications()) {
536 return false;
537 }
539 return false;
540 }
541
542 $prg = $this->getStudyProgramme();
543 $this->progress->setAmountOfPoints($prg->getPoints())
544 ->setStatus($prg->getStatus() == ilStudyProgramme::STATUS_ACTIVE
547 )
548 ->update();
549
550 $this->updateStatus();
551 }
552
557 protected function updateStatus() {
558 $prg = $this->getStudyProgramme();
559 if (( $prg->getLPMode() == ilStudyProgramme::MODE_LP_COMPLETED
560 && $this->getStatus() != ilStudyProgrammeProgress::STATUS_ACCREDITED)
561 || $this->getStatus() == ilStudyProgrammeProgress::STATUS_NOT_RELEVANT) {
562 // Nothing to do here, as the status will be set by LP.
563 // OR current status is NOT RELEVANT
564 return;
565 }
566
567 $add = function($a, $b) { return $a + $b; };
568 $get_points = function($child) {
569 if (!$child->isSuccessful()) {
570 return 0;
571 }
572 return $child->getAmountOfPoints();
573 };
574
575 $achieved_points = array_reduce(array_map($get_points, $this->getChildrenProgress()), $add);
576 if (!$achieved_points) {
577 $achieved_points = 0;
578 }
579 $successful = $achieved_points >= $this->getAmountOfPoints() && $this->hasSuccessfullChildren();
580 $status = $this->getStatus();
581
582 $this->progress->setCurrentAmountOfPoints($achieved_points);
583 if ($successful) {
584 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_COMPLETED);
585 require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeEvents.php");
587 } else {
588 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_IN_PROGRESS);
589 }
590
591 $this->progress->update();
592 $this->refreshLPStatus();
593 $this->updateParentStatus();
594 }
595
596 protected function hasSuccessfullChildren()
597 {
598 foreach($this->getChildrenProgress() as $child) {
599 if($child->isSuccessful()) {
600 return true;
601 }
602 }
603 return false;
604 }
605
609 protected function updateParentStatus() {
610 $parent = $this->getParentProgress();
611 if ($parent) {
612 $parent->updateStatus();
613 }
614 }
615
626 public function setLPCompleted($a_obj_id, $a_usr_id) {
627 if ($this->isSuccessful() || !$this->isRelevant()) {
628 return true;
629 }
630
631 $prg = $this->getStudyProgramme();
632 if ($prg->getLPMode() != ilStudyProgramme::MODE_LP_COMPLETED) {
633 throw new ilException("ilStudyProgrammeUserProgress::setLPCompleted: "
634 ."The node '".$prg->getId()."' is not in LP_COMPLETED mode.");
635 }
636 if ($this->getUserId() != $a_usr_id) {
637 throw new ilException("ilStudyProgrammeUserProgress::setLPCompleted: "
638 ."This progress does belong to user '".$this->getUserId()
639 ."' and not to user '$a_usr_id'");
640 }
641 if (!in_array($a_obj_id, $prg->getLPChildrenIds())) {
642 throw new ilException("ilStudyProgrammeUserProgress::setLPCompleted: "
643 ."Object '$a_obj_id' is no child of node '".$prg->getId()."'.");
644 }
645
646 $this->progress->setStatus(ilStudyProgrammeProgress::STATUS_COMPLETED)
647 ->setCompletionBy($a_obj_id)
648 ->update();
649
650 require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeEvents.php");
652
653 $this->refreshLPStatus();
654 $this->updateParentStatus();
655 }
656
661 protected function getParentProgress() {
662 $prg = $this->getStudyProgramme();
663 $parent = $prg->getParent();
664 if (!$parent) {
665 return null;
666 }
667
668 if($this->getStudyProgramme()->getId() == $this->getAssignment()->getStudyProgramme()->getId()) {
669 return null;
670 }
671
672 return $parent->getProgressForAssignment($this->progress->getAssignmentId());
673 }
674
681 public function getChildrenProgress() {
682 $prg = $this->getStudyProgramme();
683 if ($prg->getLPMode() == ilStudyProgramme::MODE_LP_COMPLETED) {
684 throw new ilException("ilStudyProgrammeUserProgress::getChildrenProgress: "
685 ."There is some problem in the implementation. This "
686 ."method should only be callled for nodes in points "
687 ."mode.");
688 }
689
690 $ass_id = $this->progress->getAssignmentId();
691 return array_map(function($child) use ($ass_id) {
692 return $child->getProgressForAssignment($ass_id);
693 }, $prg->getChildren());
694 }
695
704 $prg = $this->getStudyProgramme();
705 $children = $prg->getChildren();
706 $ass_id = $this->progress->getAssignmentId();
707 $names = array();
708 foreach ($children as $child) {
709 $prgrs = $child->getProgressForAssignment($ass_id);
710 if (!$prgrs->isSuccessful()) {
711 continue;
712 }
713 $names[] = $child->getTitle();
714 }
715 return $names;
716 }
717
718 const ACTION_MARK_ACCREDITED = "mark_accredited";
719 const ACTION_UNMARK_ACCREDITED = "unmark_accredited";
720 const ACTION_SHOW_INDIVIDUAL_PLAN = "show_individual_plan";
721 const ACTION_REMOVE_USER = "remove_user";
722
730 static public function getPossibleActions($a_node_id, $a_root_prg_id, $a_status) {
731 $actions = array();
732 if ($a_node_id == $a_root_prg_id) {
734 $actions[] = self::ACTION_REMOVE_USER;
735 }
738 }
739 else if ($a_status == ilStudyProgrammeProgress::STATUS_IN_PROGRESS) {
740 $actions[] = self::ACTION_MARK_ACCREDITED;
741 }
742 return $actions;
743 }
744
745 protected function refreshLPStatus() {
746 require_once("Services/Tracking/classes/class.ilLPStatusWrapper.php");
748 }
749}
750
751?>
static where($where, $operator=null)
An exception for terminatinating execution or to throw for unit testing.
Base class for ILIAS Exception handling.
static _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:17
global $DIC