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 
5 require_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
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) {
732  $actions[] = self::ACTION_SHOW_INDIVIDUAL_PLAN;
733  $actions[] = self::ACTION_REMOVE_USER;
734  }
736  $actions[] = self::ACTION_UNMARK_ACCREDITED;
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 ?>
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.
Base class for ILIAS Exception handling.
static statusToRepr($a_status)
Get a user readable representation of a status.
static userSuccessful(ilStudyProgrammeUserProgress $a_progress)
getCurrentAmountOfPoints()
Get the amount of points the user currently achieved.
isRelevant()
Check whether this node is relevant for the user.
static getInstanceForAssignment($a_program_id, $a_assignment_id)
Get the instance for the assignment on the program.
updateParentStatus()
Update the status of the parent of this node.
setRequiredAmountOfPoints($a_points, $a_user_id)
Set the amount of points the user is required to have to complete this node.
getStudyProgramme()
Get the program node where this progress belongs to was made.
unmarkAccredited()
Set the node to in progress.
isSuccessful()
Check whether the user was successful on this node.
getStatus()
Get the status of the progress.
getNodeId()
Get the id of the program node the progress belongs to.
isAccredited()
Check whether the user was accredited on this node.
Exception is thrown when a progress for some programme node and assignment is missing.
static getInstancesForUser($a_program_id, $a_user_id)
Get the instances that user has on program.
getAssignment()
Get the assignment this progress belongs to.
getParentProgress()
Get the progress on the parent node for the same assignment this progress belongs to...
static _getAllReferences($a_id)
get all reference ids of object
static getInstanceByRefId($a_ref_id)
Get an instance of ilObjStudyProgramme, use cache.
canBeCompleted()
Check whether the user can achieve enough points on the subnodes to be able to complete this node...
markNotRelevant($a_user_id)
Set the node to be not relevant for the user.
markAccredited($a_user_id)
Mark this progress as accredited.
getNamesOfCompletedOrAccreditedChildren()
Get a list with the names of the children of this node that a were completed or accredited for the gi...
static getInstancesForAssignment($a_assignment_id)
Get the instance for an assignment.
getLastChange()
Get the timestamp when the last change was made on this progress.
static getPossibleActions($a_node_id, $a_root_prg_id, $a_status)
Get a list with possible actions on a progress record.
getUserId()
Get the id of the user who is assigned.
static where($where, $operator=NULL)
getAmountOfPoints()
Get the amount of points needed to complete the node.
hasIndividualModifications()
Check whether there are individual modifications for the user on this program.
Class ilStudyProgrammeProgress.
getLastChangeBy()
Get the id of the user who did the last change on this progress.
setLPCompleted($a_obj_id, $a_usr_id)
Set this node to be completed due to a completed learning progress.
_refreshStatus($a_obj_id, $a_users=null)
Set dirty.
global $lng
Definition: privfeed.php:40
updateStatus()
Updates the status of this progress based on the status of the progress on the sub nodes...
getMaximumPossibleAmountOfPoints($only_relevant=false)
Get the maximum possible amount of points a user can achieve for the completion of this node...
markRelevant($a_user_id)
Set the node to be relevant for the user.
updateFromProgramNode()
Update the progress from its program node.
getCompletionBy()
Get the id of the user or course that lead to completion of this node.
__construct($a_ids_or_model)
Throws when id does not refer to a study programme progress.
static getInstancesForProgram($a_program_id)
Get the instances for a program node.
Represents the progress of a user at one node of a study programme.
static getInstanceById($a_prgrs_id)
Get an instance by progress id.