ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
ilLMTracker Class Reference

Track access to ILIAS learning modules. More...

+ Collaboration diagram for ilLMTracker:

Public Member Functions

 trackAccess ($a_page_id, $user_id)
 Track access to lm page. More...
 
 trackLastPageAccess ($usr_id, $lm_id, $obj_id)
 Track last accessed page for a learning module. More...
 
 setCurrentPage ($a_val)
 Set current page. More...
 
 getCurrentPage ()
 Get current page. More...
 
 getAllQuestionsCorrect ()
 Have all questoins been answered correctly (and questions exist)? More...
 
 getIconForLMObject ($a_node, $a_highlighted_node=0)
 Get icon for lm object. More...
 
 hasPredIncorrectAnswers ($a_obj_id, $a_ignore_unlock=false)
 Has predecessing incorrect answers. More...
 
 getBlockedUsersInformation ()
 Get blocked users information. More...
 

Static Public Member Functions

static getInstance ($a_ref_id, $a_user_id=0)
 Get instance. More...
 
static getInstanceByObjId ($a_obj_id, $a_user_id=0)
 Get instance. More...
 
static _isNodeVisible ($a_node)
 Is node visible for the learner. More...
 

Data Fields

const NOT_ATTEMPTED = 0
 
const IN_PROGRESS = 1
 
const COMPLETED = 2
 
const FAILED = 3
 
const CURRENT = 99
 

Static Public Attributes

static $instances = array()
 
static $instancesbyobj = array()
 

Protected Member Functions

 trackPageAndChapterAccess ($a_page_id)
 Track page and chapter access. More...
 
 loadLMTrackingData ()
 Load LM tracking data. More...
 
 determineProgressStatus ($a_obj_id, &$a_has_pred_incorrect_answers, &$a_has_pred_incorrect_not_unlocked_answers)
 Determine progress status of nodes. More...
 

Protected Attributes

 $db
 
 $lng
 
 $plugin_admin
 
 $user
 
 $lm_ref_id
 
 $lm_obj_id
 
 $lm_tree
 
 $lm_obj_ids = array()
 
 $tree_arr = array()
 
 $re_arr = array()
 
 $loaded_for_node = false
 
 $dirty = false
 
 $page_questions = array()
 
 $all_questions = array()
 
 $answer_status = array()
 
 $has_incorrect_answers = false
 
 $current_page_id = 0
 

Private Member Functions

 __construct ($a_id, $a_by_obj_id=false, $a_user_id)
 Constructor. More...
 

Detailed Description

Track access to ILIAS learning modules.

Author
Alex Killing alex..nosp@m.kill.nosp@m.ing@g.nosp@m.mx.d.nosp@m.e
Version
$Id$

Definition at line 12 of file class.ilLMTracker.php.

Constructor & Destructor Documentation

◆ __construct()

ilLMTracker::__construct (   $a_id,
  $a_by_obj_id = false,
  $a_user_id 
)
private

Constructor.

Parameters
ilObjLearningModule$a_lmlearning module

Definition at line 66 of file class.ilLMTracker.php.

References $DIC, ilObject\_lookupObjId(), ilLMTree\getInstance(), and user().

67  {
68  global $DIC;
69 
70  $this->db = $DIC->database();
71  $this->lng = $DIC->language();
72  $this->plugin_admin = $DIC["ilPluginAdmin"];
73  $this->user = $DIC->user();
74  $this->user_id = $a_user_id;
75 
76  if ($a_by_obj_id) {
77  $this->lm_ref_id = 0;
78  $this->lm_obj_id = $a_id;
79  } else {
80  $this->lm_ref_id = $a_id;
81  $this->lm_obj_id = ilObject::_lookupObjId($a_id);
82  }
83 
84  include_once("./Modules/LearningModule/classes/class.ilLMTree.php");
85  $this->lm_tree = ilLMTree::getInstance($this->lm_obj_id);
86  }
global $DIC
Definition: saml.php:7
user()
Definition: user.php:4
static _lookupObjId($a_id)
static getInstance($a_tree_id)
Get Instance.
+ Here is the call graph for this function:

Member Function Documentation

◆ _isNodeVisible()

static ilLMTracker::_isNodeVisible (   $a_node)
static

Is node visible for the learner.

Parameters
mixed$a_nodenode object/array
Returns
boolean node visible true/false

Definition at line 628 of file class.ilLMTracker.php.

References $lm_set, ilPageObject\_lookupActivationData(), ilPageObject\_lookupActive(), and ilUtil\now().

629  {
630  include_once("./Services/COPage/classes/class.ilPageObject.php");
631 
632  if ($a_node["type"] != "pg") {
633  return true;
634  }
635 
636  $lm_set = new ilSetting("lm");
637  $active = ilPageObject::_lookupActive(
638  $a_node["child"],
639  "lm",
640  $lm_set->get("time_scheduled_page_activation")
641  );
642 
643  if (!$active) {
644  $act_data = ilPageObject::_lookupActivationData((int) $a_node["child"], "lm");
645  if ($act_data["show_activation_info"] &&
646  (ilUtil::now() < $act_data["activation_start"])) {
647  return true;
648  } else {
649  return false;
650  }
651  } else {
652  return true;
653  }
654  }
static now()
Return current timestamp in Y-m-d H:i:s format.
static _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation=false, $a_lang="-")
lookup activation status
static _lookupActivationData($a_id, $a_parent_type, $a_lang="-")
Lookup activation data.
$lm_set
+ Here is the call graph for this function:

◆ determineProgressStatus()

ilLMTracker::determineProgressStatus (   $a_obj_id,
$a_has_pred_incorrect_answers,
$a_has_pred_incorrect_not_unlocked_answers 
)
protected

Determine progress status of nodes.

Parameters
int$a_obj_idlm object id
Returns
int status

Definition at line 417 of file class.ilLMTracker.php.

References $c, COMPLETED, CURRENT, FAILED, getCurrentPage(), IN_PROGRESS, NOT_ATTEMPTED, and ilUtil\sortArray().

Referenced by loadLMTrackingData().

418  {
419  $status = ilLMTracker::NOT_ATTEMPTED;
420 
421  if (isset($this->tree_arr["nodes"][$a_obj_id])) {
422  $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_answers"] = $a_has_pred_incorrect_answers;
423  $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_not_unlocked_answers"] = $a_has_pred_incorrect_not_unlocked_answers;
424 
425  if (is_array($this->tree_arr["childs"][$a_obj_id])) {
426  // sort childs in correct order
427  $this->tree_arr["childs"][$a_obj_id] = ilUtil::sortArray($this->tree_arr["childs"][$a_obj_id], "lft", "asc", true);
428 
429  $cnt_completed = 0;
430  foreach ($this->tree_arr["childs"][$a_obj_id] as $c) {
431  // if child is not activated/displayed count child as implicitly completed
432  // rationale: everything that is visible for the learner determines the status
433  // see also bug #14642
434  if (!self::_isNodeVisible($c)) {
435  $cnt_completed++;
436  continue;
437  }
438  $c_stat = $this->determineProgressStatus(
439  $c["child"],
440  $a_has_pred_incorrect_answers,
441  $a_has_pred_incorrect_not_unlocked_answers
442  );
443  if ($status != ilLMTracker::FAILED) {
444  if ($c_stat == ilLMTracker::FAILED) {
445  $status = ilLMTracker::IN_PROGRESS;
446  } elseif ($c_stat == ilLMTracker::IN_PROGRESS) {
447  $status = ilLMTracker::IN_PROGRESS;
448  } elseif ($c_stat == ilLMTracker::COMPLETED || $c_stat == ilLMTracker::CURRENT) {
449  $status = ilLMTracker::IN_PROGRESS;
450  $cnt_completed++;
451  }
452  }
453  // if an item is failed or in progress or (not attempted and contains questions)
454  // the next item has predecessing incorrect answers
455  if ($this->tree_arr["nodes"][$c["child"]]["type"] == "pg") {
456  if ($c_stat == ilLMTracker::FAILED || $c_stat == ilLMTracker::IN_PROGRESS ||
457  ($c_stat == ilLMTracker::NOT_ATTEMPTED && is_array($this->page_questions[$c["child"]]) && count($this->page_questions[$c["child"]]) > 0)) {
458  $a_has_pred_incorrect_answers = true;
459  if (!$this->tree_arr["nodes"][$c["child"]]["unlocked"]) {
460  $a_has_pred_incorrect_not_unlocked_answers = true;
461  }
462  }
463  }
464  }
465  if ($cnt_completed == count($this->tree_arr["childs"][$a_obj_id])) {
466  $status = ilLMTracker::COMPLETED;
467  }
468  } elseif ($this->tree_arr["nodes"][$a_obj_id]["type"] == "pg") {
469  // check read event data
470  if (isset($this->re_arr[$a_obj_id]) && $this->re_arr[$a_obj_id]["read_count"] > 0) {
471  $status = ilLMTracker::COMPLETED;
472  } elseif ($a_obj_id == $this->getCurrentPage()) {
473  $status = ilLMTracker::CURRENT;
474  }
475 
476  $unlocked = false;
477  if (is_array($this->page_questions[$a_obj_id])) {
478  // check questions, if one is failed -> failed
479  $unlocked = true;
480  foreach ($this->page_questions[$a_obj_id] as $q_id) {
481  if (is_array($this->answer_status[$q_id])
482  && $this->answer_status[$q_id]["try"] > 0
483  && !$this->answer_status[$q_id]["passed"]) {
484  $status = ilLMTracker::FAILED;
485  if (!$this->answer_status[$q_id]["unlocked"]) {
486  $unlocked = false;
487  }
488  }
489  }
490 
491  // check questions, if one is not answered -> in progress
492  if ($status != ilLMTracker::FAILED) {
493  foreach ($this->page_questions[$a_obj_id] as $q_id) {
494  if (!is_array($this->answer_status[$q_id])
495  || $this->answer_status[$q_id]["try"] == 0) {
496  if ($status != ilLMTracker::NOT_ATTEMPTED) {
497  $status = ilLMTracker::IN_PROGRESS;
498  }
499  }
500  }
501  $unlocked = false;
502  }
503  }
504  $this->tree_arr["nodes"][$a_obj_id]["unlocked"] = $unlocked;
505  $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_answers"] = $a_has_pred_incorrect_answers;
506  $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_not_unlocked_answers"] = $a_has_pred_incorrect_not_unlocked_answers;
507  }
508  } else { // free pages (currently not called, since only walking through tree structure)
509  }
510  $this->tree_arr["nodes"][$a_obj_id]["status"] = $status;
511 
512  return $status;
513  }
static sortArray( $array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
getCurrentPage()
Get current page.
determineProgressStatus($a_obj_id, &$a_has_pred_incorrect_answers, &$a_has_pred_incorrect_not_unlocked_answers)
Determine progress status of nodes.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getAllQuestionsCorrect()

ilLMTracker::getAllQuestionsCorrect ( )

Have all questoins been answered correctly (and questions exist)?

Returns
bool true, if learning module contains any question and all questions (in the chapter structure) have been answered correctly

Definition at line 401 of file class.ilLMTracker.php.

References loadLMTrackingData().

402  {
403  $this->loadLMTrackingData();
404  if (count($this->all_questions) > 0 && !$this->has_incorrect_answers) {
405  return true;
406  }
407  return false;
408  }
loadLMTrackingData()
Load LM tracking data.
+ Here is the call graph for this function:

◆ getBlockedUsersInformation()

ilLMTracker::getBlockedUsersInformation ( )

Get blocked users information.

Parameters

Definition at line 574 of file class.ilLMTracker.php.

References $as, $db, $ilDB, $ilUser, $lng, $name, $plugin_admin, $user, ilObjUser\_lookupName(), ilLMObject\_lookupTitle(), ilPageQuestionProcessor\getAnswerStatus(), and ilLMPageObject\queryQuestionsOfLearningModule().

575  {
576  $ilDB = $this->db;
577  $lng = $this->lng;
578  $ilPluginAdmin = $this->plugin_admin;
580 
581  $blocked_users = array();
582 
583  // load question/pages information
584  $this->page_questions = array();
585  $this->all_questions = array();
586  $page_for_question = array();
587  include_once("./Modules/LearningModule/classes/class.ilLMPageObject.php");
588  $q = ilLMPageObject::queryQuestionsOfLearningModule($this->lm_obj_id, "", "", 0, 0);
589  foreach ($q["set"] as $quest) {
590  $this->page_questions[$quest["page_id"]][] = $quest["question_id"];
591  $this->all_questions[] = $quest["question_id"];
592  $page_for_question[$quest["question_id"]] = $quest["page_id"];
593  }
594  // get question information
595  include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionList.php");
596  $qlist = new ilAssQuestionList($ilDB, $lng, $ilPluginAdmin);
597  $qlist->setParentObjId(0);
598  $qlist->setJoinObjectData(false);
599  $qlist->addFieldFilter("question_id", $this->all_questions);
600  $qlist->load();
601  $qdata = $qlist->getQuestionDataArray();
602 
603  // load question answer information
604  include_once("./Services/COPage/classes/class.ilPageQuestionProcessor.php");
605  $this->answer_status = ilPageQuestionProcessor::getAnswerStatus($this->all_questions);
606  include_once("./Modules/LearningModule/classes/class.ilLMPageObject.php");
607  foreach ($this->answer_status as $as) {
608  if ($as["try"] >= $qdata[$as["qst_id"]]["nr_of_tries"] && $qdata[$as["qst_id"]]["nr_of_tries"] > 0 && !$as["passed"]) {
609  //var_dump($qdata[$as["qst_id"]]);
610  $name = ilObjUser::_lookupName($as["user_id"]);
611  $as["user_name"] = $name["lastname"] . ", " . $name["firstname"] . " [" . $name["login"] . "]";
612  $as["question_text"] = $qdata[$as["qst_id"]]["question_text"];
613  $as["page_id"] = $page_for_question[$as["qst_id"]];
614  $as["page_title"] = ilLMPageObject::_lookupTitle($as["page_id"]);
615  $blocked_users[] = $as;
616  }
617  }
618 
619  return $blocked_users;
620  }
static _lookupName($a_user_id)
lookup user name
static _lookupTitle($a_obj_id)
Lookup title.
static getAnswerStatus($a_q_id, $a_user_id=0)
Get statistics for question.
$as
static queryQuestionsOfLearningModule( $a_lm_id, $a_order_field, $a_order_dir, $a_offset, $a_limit)
Get questions of learning module.
$ilUser
Definition: imgupload.php:18
global $ilDB
+ Here is the call graph for this function:

◆ getCurrentPage()

ilLMTracker::getCurrentPage ( )

Get current page.

Returns
id current page id

Definition at line 325 of file class.ilLMTracker.php.

References $current_page_id.

Referenced by determineProgressStatus(), and loadLMTrackingData().

326  {
327  return $this->current_page_id;
328  }
+ Here is the caller graph for this function:

◆ getIconForLMObject()

ilLMTracker::getIconForLMObject (   $a_node,
  $a_highlighted_node = 0 
)

Get icon for lm object.

Parameters
array$a_nodenode array
int$a_highlighted_nodecurrent node id
Returns
string image path

Definition at line 523 of file class.ilLMTracker.php.

References COMPLETED, FAILED, ilUtil\getImagePath(), IN_PROGRESS, and loadLMTrackingData().

524  {
525  $this->loadLMTrackingData();
526  if ($a_node["child"] == $a_highlighted_node) {
527  return ilUtil::getImagePath('scorm/running.svg');
528  }
529  if (isset($this->tree_arr["nodes"][$a_node["child"]])) {
530  switch ($this->tree_arr["nodes"][$a_node["child"]]["status"]) {
532  return ilUtil::getImagePath('scorm/incomplete.svg');
533 
534  case ilLMTracker::FAILED:
535  return ilUtil::getImagePath('scorm/failed.svg');
536 
538  return ilUtil::getImagePath('scorm/completed.svg');
539  }
540  }
541  return ilUtil::getImagePath('scorm/not_attempted.svg');
542  }
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
loadLMTrackingData()
Load LM tracking data.
+ Here is the call graph for this function:

◆ getInstance()

static ilLMTracker::getInstance (   $a_ref_id,
  $a_user_id = 0 
)
static

Get instance.

Parameters

Definition at line 94 of file class.ilLMTracker.php.

References $DIC, and $ilUser.

Referenced by ilLMBlockedUsersTableGUI\__construct(), and ilLMPresentationGUI\getTracker().

95  {
96  global $DIC;
97 
98  $ilUser = $DIC->user();
99 
100  if ($a_user_id == 0) {
101  $a_user_id = $ilUser->getId();
102  }
103 
104  if (!isset(self::$instances[$a_ref_id][$a_user_id])) {
105  self::$instances[$a_ref_id][$a_user_id] = new ilLMTracker($a_ref_id, false, $a_user_id);
106  }
107  return self::$instances[$a_ref_id][$a_user_id];
108  }
Track access to ILIAS learning modules.
global $DIC
Definition: saml.php:7
$ilUser
Definition: imgupload.php:18
+ Here is the caller graph for this function:

◆ getInstanceByObjId()

static ilLMTracker::getInstanceByObjId (   $a_obj_id,
  $a_user_id = 0 
)
static

Get instance.

Parameters

Definition at line 116 of file class.ilLMTracker.php.

References $DIC, and $ilUser.

Referenced by ilLPStatusQuestions\_getCompleted(), and ilLPStatusQuestions\determineStatus().

117  {
118  global $DIC;
119 
120  $ilUser = $DIC->user();
121 
122  if ($a_user_id == 0) {
123  $a_user_id = $ilUser->getId();
124  }
125 
126  if (!isset(self::$instancesbyobj[$a_obj_id][$a_user_id])) {
127  self::$instancesbyobj[$a_obj_id][$a_user_id] = new ilLMTracker($a_obj_id, true, $a_user_id);
128  }
129  return self::$instancesbyobj[$a_obj_id][$a_user_id];
130  }
Track access to ILIAS learning modules.
global $DIC
Definition: saml.php:7
$ilUser
Definition: imgupload.php:18
+ Here is the caller graph for this function:

◆ hasPredIncorrectAnswers()

ilLMTracker::hasPredIncorrectAnswers (   $a_obj_id,
  $a_ignore_unlock = false 
)

Has predecessing incorrect answers.

Parameters
int$a_obj_id
Returns
bool true if incorrect/unsanswered questions exist in predecessing pages

Definition at line 550 of file class.ilLMTracker.php.

References $ret, and loadLMTrackingData().

551  {
552  $this->loadLMTrackingData();
553  $ret = false;
554  if (is_array($this->tree_arr["nodes"][$a_obj_id])) {
555  if ($a_ignore_unlock) {
556  $ret = $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_answers"];
557  } else {
558  $ret = $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_not_unlocked_answers"];
559  }
560  }
561  return $ret;
562  }
$ret
Definition: parser.php:6
loadLMTrackingData()
Load LM tracking data.
+ Here is the call graph for this function:

◆ loadLMTrackingData()

ilLMTracker::loadLMTrackingData ( )
protected

Load LM tracking data.

Loaded when needed.

Parameters

Definition at line 336 of file class.ilLMTracker.php.

References $db, $ilDB, $nodes, ilLMObject\_getAllLMObjectsOfLM(), determineProgressStatus(), ilPageQuestionProcessor\getAnswerStatus(), getCurrentPage(), and ilLMPageObject\queryQuestionsOfLearningModule().

Referenced by getAllQuestionsCorrect(), getIconForLMObject(), and hasPredIncorrectAnswers().

337  {
338  $ilDB = $this->db;
339 
340  // we must prevent loading tracking data multiple times during a request where possible
341  // please note that the dirty flag works only to a certain limit
342  // e.g. if questions are answered the flag is not set (yet)
343  // or if pages/chapter are added/deleted the flag is not set
344  if ($this->loaded_for_node === (int) $this->getCurrentPage() && !$this->dirty) {
345  return;
346  }
347 
348  $this->loaded_for_node = (int) $this->getCurrentPage();
349  $this->dirty = false;
350 
351  // load lm tree in array
352  $this->tree_arr = array();
353  $nodes = $this->lm_tree->getCompleteTree();
354  foreach ($nodes as $node) {
355  $this->tree_arr["childs"][$node["parent"]][] = $node;
356  $this->tree_arr["parent"][$node["child"]] = $node["parent"];
357  $this->tree_arr["nodes"][$node["child"]] = $node;
358  }
359 
360  // load all lm obj ids of learning module
361  include_once("./Modules/LearningModule/classes/class.ilLMObject.php");
362  $this->lm_obj_ids = ilLMObject::_getAllLMObjectsOfLM($this->lm_obj_id);
363 
364  // load read event data
365  $this->re_arr = array();
366  $set = $ilDB->query("SELECT * FROM lm_read_event " .
367  " WHERE " . $ilDB->in("obj_id", $this->lm_obj_ids, false, "integer") .
368  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
369  while ($rec = $ilDB->fetchAssoc($set)) {
370  $this->re_arr[$rec["obj_id"]] = $rec;
371  }
372 
373  // load question/pages information
374  $this->page_questions = array();
375  $this->all_questions = array();
376  include_once("./Modules/LearningModule/classes/class.ilLMPageObject.php");
377  $q = ilLMPageObject::queryQuestionsOfLearningModule($this->lm_obj_id, "", "", 0, 0);
378  foreach ($q["set"] as $quest) {
379  $this->page_questions[$quest["page_id"]][] = $quest["question_id"];
380  $this->all_questions[] = $quest["question_id"];
381  }
382 
383  // load question answer information
384  include_once("./Services/COPage/classes/class.ilPageQuestionProcessor.php");
385  $this->answer_status = ilPageQuestionProcessor::getAnswerStatus($this->all_questions, $this->user_id);
386 
387  $this->has_incorrect_answers = false;
388 
389  $has_pred_incorrect_answers = false;
390  $has_pred_incorrect_not_unlocked_answers = false;
391  $this->determineProgressStatus($this->lm_tree->readRootId(), $has_pred_incorrect_answers, $has_pred_incorrect_not_unlocked_answers);
392 
393  $this->has_incorrect_answers = $has_pred_incorrect_answers;
394  }
static _getAllLMObjectsOfLM($a_lm_id, $a_type="")
Get all objects of learning module.
getCurrentPage()
Get current page.
static getAnswerStatus($a_q_id, $a_user_id=0)
Get statistics for question.
static queryQuestionsOfLearningModule( $a_lm_id, $a_order_field, $a_order_dir, $a_offset, $a_limit)
Get questions of learning module.
determineProgressStatus($a_obj_id, &$a_has_pred_incorrect_answers, &$a_has_pred_incorrect_not_unlocked_answers)
Determine progress status of nodes.
global $ilDB
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setCurrentPage()

ilLMTracker::setCurrentPage (   $a_val)

Set current page.

Parameters
id$a_valcurrent page id

Definition at line 315 of file class.ilLMTracker.php.

316  {
317  $this->current_page_id = $a_val;
318  }

◆ trackAccess()

ilLMTracker::trackAccess (   $a_page_id,
  $user_id 
)

Track access to lm page.

Parameters
int$a_page_idpage id

Definition at line 141 of file class.ilLMTracker.php.

References ilChangeEvent\_recordReadEvent(), ilLearningProgress\_tracProgress(), ilLPStatusWrapper\_updateStatus(), trackLastPageAccess(), and trackPageAndChapterAccess().

142  {
143  if ($user_id == ANONYMOUS_USER_ID) {
144  ilChangeEvent::_recordReadEvent("lm", $this->lm_ref_id, $this->lm_obj_id, $user_id);
145  return;
146  }
147 
148  if ($this->lm_ref_id == 0) {
149  throw new ilLMPresentationException("ilLMTracker: No Ref Id given.");
150  }
151 
152  // track page and chapter access
153  $this->trackPageAndChapterAccess($a_page_id);
154 
155  // track last page access (must be done after calling trackPageAndChapterAccess())
156  $this->trackLastPageAccess($this->user_id, $this->lm_ref_id, $a_page_id);
157 
158  // #9483
159  // general learning module lp tracking
160  include_once("./Services/Tracking/classes/class.ilLearningProgress.php");
162  $this->user_id,
163  $this->lm_obj_id,
164  $this->lm_ref_id,
165  "lm"
166  );
167 
168  // obsolete?
169  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
170  ilLPStatusWrapper::_updateStatus($this->lm_obj_id, $this->user_id);
171 
172  // mark currently loaded data as dirty to force reload if necessary
173  $this->dirty = true;
174  }
static _recordReadEvent( $a_type, $a_ref_id, $obj_id, $usr_id, $isCatchupWriteEvents=true, $a_ext_rc=false, $a_ext_time=false)
Records a read event and catches up with write events.
trackLastPageAccess($usr_id, $lm_id, $obj_id)
Track last accessed page for a learning module.
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static _tracProgress($a_user_id, $a_obj_id, $a_ref_id, $a_obj_type='')
Base exception class for learning module presentation.
trackPageAndChapterAccess($a_page_id)
Track page and chapter access.
+ Here is the call graph for this function:

◆ trackLastPageAccess()

ilLMTracker::trackLastPageAccess (   $usr_id,
  $lm_id,
  $obj_id 
)

Track last accessed page for a learning module.

Parameters
int$usr_iduser id
int$lm_idlearning module id
int$obj_idpage id

Definition at line 183 of file class.ilLMTracker.php.

References $db, $title, and ilUtil\now().

Referenced by trackAccess().

184  {
185  $title = "";
186  $db = $this->db;
187  $db->replace(
188  "lo_access",
189  [
190  "usr_id" => ["integer", $usr_id],
191  "lm_id" => ["integer", $lm_id]
192  ],
193  [
194  "timestamp" => ["timestamp", ilUtil::now()],
195  "obj_id" => ["integer", $obj_id],
196  "lm_title" => ["text", $title]
197  ]
198  );
199  }
static now()
Return current timestamp in Y-m-d H:i:s format.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trackPageAndChapterAccess()

ilLMTracker::trackPageAndChapterAccess (   $a_page_id)
protected

Track page and chapter access.

Definition at line 205 of file class.ilLMTracker.php.

References $db, $ilDB, $res, $row, $time_diff, ilObjUserTracking\_getValidTimeSpan(), IL_CAL_DATETIME, and IL_CAL_UNIX.

Referenced by trackAccess().

206  {
207  $ilDB = $this->db;
208 
209  $now = time();
210 
211  //
212  // 1. Page access: current page
213  //
214  $set = $ilDB->query("SELECT obj_id FROM lm_read_event" .
215  " WHERE obj_id = " . $ilDB->quote($a_page_id, "integer") .
216  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
217  if (!$ilDB->fetchAssoc($set)) {
218  $fields = array(
219  "obj_id" => array("integer", $a_page_id),
220  "usr_id" => array("integer", $this->user_id)
221  );
222  // $ilDB->insert("lm_read_event", $fields);
223  $ilDB->replace("lm_read_event", $fields, array()); // #15144
224  }
225 
226  // update all parent chapters
227  $ilDB->manipulate("UPDATE lm_read_event SET" .
228  " read_count = read_count + 1 " .
229  " , last_access = " . $ilDB->quote($now, "integer") .
230  " WHERE obj_id = " . $ilDB->quote($a_page_id, "integer") .
231  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
232 
233 
234  //
235  // 2. Chapter access: based on last page accessed
236  //
237 
238  // get last accessed page
239  $set = $ilDB->query("SELECT * FROM lo_access WHERE " .
240  "usr_id = " . $ilDB->quote($this->user_id, "integer") . " AND " .
241  "lm_id = " . $ilDB->quote($this->lm_ref_id, "integer"));
242  $res = $ilDB->fetchAssoc($set);
243  if ($res["obj_id"]) {
244  include_once('Services/Tracking/classes/class.ilObjUserTracking.php');
245  $valid_timespan = ilObjUserTracking::_getValidTimeSpan();
246 
247  $pg_ts = new ilDateTime($res["timestamp"], IL_CAL_DATETIME);
248  $pg_ts = $pg_ts->get(IL_CAL_UNIX);
249  $pg_id = $res["obj_id"];
250  if (!$this->lm_tree->isInTree($pg_id)) {
251  return;
252  }
253 
254  $time_diff = $read_diff = 0;
255 
256  // spent_seconds or read_count ?
257  if (($now - $pg_ts) <= $valid_timespan) {
258  $time_diff = $now - $pg_ts;
259  } else {
260  $read_diff = 1;
261  }
262 
263  // find parent chapter(s) for that page
264  $parent_st_ids = array();
265  foreach ($this->lm_tree->getPathFull($pg_id) as $item) {
266  if ($item["type"] == "st") {
267  $parent_st_ids[] = $item["obj_id"];
268  }
269  }
270 
271  if ($parent_st_ids && ($time_diff || $read_diff)) {
272  // get existing chapter entries
273  $ex_st = array();
274  $set = $ilDB->query("SELECT obj_id FROM lm_read_event" .
275  " WHERE " . $ilDB->in("obj_id", $parent_st_ids, "", "integer") .
276  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
277  while ($row = $ilDB->fetchAssoc($set)) {
278  $ex_st[] = $row["obj_id"];
279  }
280 
281  // add missing chapter entries
282  $missing_st = array_diff($parent_st_ids, $ex_st);
283  if (sizeof($missing_st)) {
284  foreach ($missing_st as $st_id) {
285  $fields = array(
286  "obj_id" => array("integer", $st_id),
287  "usr_id" => array("integer", $this->user_id)
288  );
289  // $ilDB->insert("lm_read_event", $fields);
290  $ilDB->replace("lm_read_event", $fields, array()); // #15144
291  }
292  }
293 
294  // update all parent chapters
295  $ilDB->manipulate("UPDATE lm_read_event SET" .
296  " read_count = read_count + " . $ilDB->quote($read_diff, "integer") .
297  " , spent_seconds = spent_seconds + " . $ilDB->quote($time_diff, "integer") .
298  " , last_access = " . $ilDB->quote($now, "integer") .
299  " WHERE " . $ilDB->in("obj_id", $parent_st_ids, "", "integer") .
300  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
301  }
302  }
303  }
const IL_CAL_DATETIME
const IL_CAL_UNIX
$time_diff
Definition: langcheck.php:760
foreach($_POST as $key=> $value) $res
Date and time handling
$row
global $ilDB
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $all_questions

ilLMTracker::$all_questions = array()
protected

Definition at line 49 of file class.ilLMTracker.php.

◆ $answer_status

ilLMTracker::$answer_status = array()
protected

Definition at line 50 of file class.ilLMTracker.php.

◆ $current_page_id

ilLMTracker::$current_page_id = 0
protected

Definition at line 52 of file class.ilLMTracker.php.

Referenced by getCurrentPage().

◆ $db

ilLMTracker::$db
protected

◆ $dirty

ilLMTracker::$dirty = false
protected

Definition at line 47 of file class.ilLMTracker.php.

◆ $has_incorrect_answers

ilLMTracker::$has_incorrect_answers = false
protected

Definition at line 51 of file class.ilLMTracker.php.

◆ $instances

ilLMTracker::$instances = array()
static

Definition at line 54 of file class.ilLMTracker.php.

◆ $instancesbyobj

ilLMTracker::$instancesbyobj = array()
static

Definition at line 55 of file class.ilLMTracker.php.

◆ $lm_obj_id

ilLMTracker::$lm_obj_id
protected

Definition at line 41 of file class.ilLMTracker.php.

◆ $lm_obj_ids

ilLMTracker::$lm_obj_ids = array()
protected

Definition at line 43 of file class.ilLMTracker.php.

◆ $lm_ref_id

ilLMTracker::$lm_ref_id
protected

Definition at line 40 of file class.ilLMTracker.php.

◆ $lm_tree

ilLMTracker::$lm_tree
protected

Definition at line 42 of file class.ilLMTracker.php.

◆ $lng

ilLMTracker::$lng
protected

Definition at line 22 of file class.ilLMTracker.php.

Referenced by getBlockedUsersInformation().

◆ $loaded_for_node

ilLMTracker::$loaded_for_node = false
protected

Definition at line 46 of file class.ilLMTracker.php.

◆ $page_questions

ilLMTracker::$page_questions = array()
protected

Definition at line 48 of file class.ilLMTracker.php.

◆ $plugin_admin

ilLMTracker::$plugin_admin
protected

Definition at line 27 of file class.ilLMTracker.php.

Referenced by getBlockedUsersInformation().

◆ $re_arr

ilLMTracker::$re_arr = array()
protected

Definition at line 45 of file class.ilLMTracker.php.

◆ $tree_arr

ilLMTracker::$tree_arr = array()
protected

Definition at line 44 of file class.ilLMTracker.php.

◆ $user

ilLMTracker::$user
protected

Definition at line 32 of file class.ilLMTracker.php.

Referenced by getBlockedUsersInformation().

◆ COMPLETED

const ilLMTracker::COMPLETED = 2

Definition at line 36 of file class.ilLMTracker.php.

Referenced by determineProgressStatus(), and getIconForLMObject().

◆ CURRENT

const ilLMTracker::CURRENT = 99

Definition at line 38 of file class.ilLMTracker.php.

Referenced by determineProgressStatus().

◆ FAILED

const ilLMTracker::FAILED = 3

Definition at line 37 of file class.ilLMTracker.php.

Referenced by determineProgressStatus(), and getIconForLMObject().

◆ IN_PROGRESS

const ilLMTracker::IN_PROGRESS = 1

Definition at line 35 of file class.ilLMTracker.php.

Referenced by determineProgressStatus(), and getIconForLMObject().

◆ NOT_ATTEMPTED

const ilLMTracker::NOT_ATTEMPTED = 0

Definition at line 34 of file class.ilLMTracker.php.

Referenced by determineProgressStatus().


The documentation for this class was generated from the following file: