ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
ilLMTracker Class Reference

This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Learning e.V. More...

+ Collaboration diagram for ilLMTracker:

Public Member Functions

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

Static Public Member Functions

static getInstance (int $a_ref_id, int $a_user_id=0)
 
static getInstanceByObjId (int $a_obj_id, int $a_user_id=0)
 
static _isNodeVisible (array $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 array $instances = array()
 
static array $instancesbyobj = array()
 

Protected Member Functions

 trackPageAndChapterAccess (int $a_page_id)
 
 loadLMTrackingData ()
 Load LM tracking data. More...
 
 determineProgressStatus (int $a_obj_id, bool &$a_has_pred_incorrect_answers, bool &$a_has_pred_incorrect_not_unlocked_answers)
 Determine progress status of nodes. More...
 

Protected Attributes

int $user_id
 
ilDBInterface $db
 
ilLanguage $lng
 
Refinery $refinery
 
ilComponentRepository $component_repository
 
ilObjUser $user
 
int $lm_ref_id
 
int $lm_obj_id
 
ilLMTree $lm_tree
 
array $lm_obj_ids = array()
 
array $tree_arr = array()
 
array $re_arr = array()
 
bool $loaded_for_node = false
 
bool $dirty = false
 
array $page_questions = array()
 
array $all_questions = array()
 
array $answer_status = array()
 
bool $has_incorrect_answers = false
 
int $current_page_id = 0
 

Private Member Functions

 __construct (int $a_id, bool $a_by_obj_id=false, int $a_user_id=0)
 

Detailed Description

This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Learning e.V.

ILIAS is licensed with the GPL-3.0, see https://www.gnu.org/licenses/gpl-3.0.en.html You should have received a copy of said license along with the source code, too.

If this is not the case or you just want to try ILIAS, you'll find us at: https://www.ilias.de https://github.com/ILIAS-eLearning Track access to ILIAS learning modules

Author
Alexander Killing killi.nosp@m.ng@l.nosp@m.eifos.nosp@m..de

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

Constructor & Destructor Documentation

◆ __construct()

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

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

References $DIC, ilObject\_lookupObjId(), ilLMTree\getInstance(), ILIAS\Repository\lng(), ILIAS\Repository\refinery(), and ILIAS\Repository\user().

61  {
62  global $DIC;
63 
64  $this->db = $DIC->database();
65  $this->lng = $DIC->language();
66  $this->user = $DIC->user();
67  $this->user_id = $a_user_id;
68  $this->refinery = $DIC['refinery'];
69  $this->component_repository = $DIC['component.repository'];
70 
71  if ($a_by_obj_id) {
72  $this->lm_ref_id = 0;
73  $this->lm_obj_id = $a_id;
74  } else {
75  $this->lm_ref_id = $a_id;
76  $this->lm_obj_id = ilObject::_lookupObjId($a_id);
77  }
78 
79  $this->lm_tree = ilLMTree::getInstance($this->lm_obj_id);
80  }
static getInstance(int $a_tree_id)
static _lookupObjId(int $ref_id)
global $DIC
Definition: feed.php:28
+ Here is the call graph for this function:

Member Function Documentation

◆ _isNodeVisible()

static ilLMTracker::_isNodeVisible ( array  $a_node)
static

Is node visible for the learner.

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

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

585  : bool {
586  if ($a_node["type"] != "pg") {
587  return true;
588  }
589 
590  $lm_set = new ilSetting("lm");
591  $active = ilPageObject::_lookupActive(
592  $a_node["child"],
593  "lm",
594  (bool) $lm_set->get("time_scheduled_page_activation")
595  );
596 
597  if (!$active) {
598  $act_data = ilPageObject::_lookupActivationData((int) $a_node["child"], "lm");
599  if ($act_data["show_activation_info"] &&
600  (ilUtil::now() < $act_data["activation_start"])) {
601  return true;
602  } else {
603  return false;
604  }
605  } else {
606  return true;
607  }
608  }
static _lookupActive(int $a_id, string $a_parent_type, bool $a_check_scheduled_activation=false, string $a_lang="-")
lookup activation status
static _lookupActivationData(int $a_id, string $a_parent_type, string $a_lang="-")
Lookup activation data.
static now()
Return current timestamp in Y-m-d H:i:s format.
$lm_set
+ Here is the call graph for this function:

◆ determineProgressStatus()

ilLMTracker::determineProgressStatus ( int  $a_obj_id,
bool &  $a_has_pred_incorrect_answers,
bool &  $a_has_pred_incorrect_not_unlocked_answers 
)
protected

Determine progress status of nodes.

Parameters
int$a_obj_idlm object id

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

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

Referenced by loadLMTrackingData().

385  : int {
386  $status = ilLMTracker::NOT_ATTEMPTED;
387 
388  if (isset($this->tree_arr["nodes"][$a_obj_id])) {
389  $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_answers"] = $a_has_pred_incorrect_answers;
390  $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_not_unlocked_answers"] = $a_has_pred_incorrect_not_unlocked_answers;
391 
392  if (isset($this->tree_arr["childs"][$a_obj_id])) {
393  // sort childs in correct order
394  $this->tree_arr["childs"][$a_obj_id] = ilArrayUtil::sortArray(
395  $this->tree_arr["childs"][$a_obj_id],
396  "lft",
397  "asc",
398  true
399  );
400 
401  $cnt_completed = 0;
402  foreach ($this->tree_arr["childs"][$a_obj_id] as $c) {
403  // if child is not activated/displayed count child as implicitly completed
404  // rationale: everything that is visible for the learner determines the status
405  // see also bug #14642
406  if (!self::_isNodeVisible($c)) {
407  $cnt_completed++;
408  continue;
409  }
410  $c_stat = $this->determineProgressStatus(
411  $c["child"],
412  $a_has_pred_incorrect_answers,
413  $a_has_pred_incorrect_not_unlocked_answers
414  );
415  if ($status != ilLMTracker::FAILED) {
416  if ($c_stat == ilLMTracker::FAILED) {
417  $status = ilLMTracker::IN_PROGRESS;
418  } elseif ($c_stat == ilLMTracker::IN_PROGRESS) {
419  $status = ilLMTracker::IN_PROGRESS;
420  } elseif ($c_stat == ilLMTracker::COMPLETED || $c_stat == ilLMTracker::CURRENT) {
421  $status = ilLMTracker::IN_PROGRESS;
422  $cnt_completed++;
423  }
424  }
425  // if an item is failed or in progress or (not attempted and contains questions)
426  // the next item has predecessing incorrect answers
427  if ($this->tree_arr["nodes"][$c["child"]]["type"] == "pg") {
428  if ($c_stat == ilLMTracker::FAILED || $c_stat == ilLMTracker::IN_PROGRESS ||
429  ($c_stat == ilLMTracker::NOT_ATTEMPTED && isset($this->page_questions[$c["child"]]) && count($this->page_questions[$c["child"]]) > 0)) {
430  $a_has_pred_incorrect_answers = true;
431  if (!$this->tree_arr["nodes"][$c["child"]]["unlocked"]) {
432  $a_has_pred_incorrect_not_unlocked_answers = true;
433  }
434  }
435  }
436  }
437  if ($cnt_completed == count($this->tree_arr["childs"][$a_obj_id])) {
438  $status = ilLMTracker::COMPLETED;
439  }
440  } elseif ($this->tree_arr["nodes"][$a_obj_id]["type"] == "pg") {
441  // check read event data
442  if (isset($this->re_arr[$a_obj_id]) && $this->re_arr[$a_obj_id]["read_count"] > 0) {
443  $status = ilLMTracker::COMPLETED;
444  } elseif ($a_obj_id == $this->getCurrentPage()) {
445  $status = ilLMTracker::CURRENT;
446  }
447 
448  $unlocked = false;
449  if (isset($this->page_questions[$a_obj_id])) {
450  // check questions, if one is failed -> failed
451  $unlocked = true;
452  foreach ($this->page_questions[$a_obj_id] as $q_id) {
453  if (isset($this->answer_status[$q_id])
454  && $this->answer_status[$q_id]["try"] > 0
455  && !$this->answer_status[$q_id]["passed"]) {
456  $status = ilLMTracker::FAILED;
457  if (!$this->answer_status[$q_id]["unlocked"]) {
458  $unlocked = false;
459  }
460  }
461  }
462 
463  // check questions, if one is not answered -> in progress
464  if ($status != ilLMTracker::FAILED) {
465  foreach ($this->page_questions[$a_obj_id] as $q_id) {
466  if (!isset($this->answer_status[$q_id])
467  || $this->answer_status[$q_id]["try"] == 0) {
468  if ($status != ilLMTracker::NOT_ATTEMPTED) {
469  $status = ilLMTracker::IN_PROGRESS;
470  }
471  }
472  }
473  $unlocked = false;
474  }
475  }
476  $this->tree_arr["nodes"][$a_obj_id]["unlocked"] = $unlocked;
477  $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_answers"] = $a_has_pred_incorrect_answers;
478  $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_not_unlocked_answers"] = $a_has_pred_incorrect_not_unlocked_answers;
479  }
480  } /*else { // free pages (currently not called, since only walking through tree structure)
481  }*/
482  $this->tree_arr["nodes"][$a_obj_id]["status"] = $status;
483 
484  return $status;
485  }
$c
Definition: cli.php:38
determineProgressStatus(int $a_obj_id, bool &$a_has_pred_incorrect_answers, bool &$a_has_pred_incorrect_not_unlocked_answers)
Determine progress status of nodes.
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getAllQuestionsCorrect()

ilLMTracker::getAllQuestionsCorrect ( )

Have all questions 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 367 of file class.ilLMTracker.php.

References loadLMTrackingData().

367  : bool
368  {
369  $this->loadLMTrackingData();
370  if (count($this->all_questions) > 0 && !$this->has_incorrect_answers) {
371  return true;
372  }
373  return false;
374  }
loadLMTrackingData()
Load LM tracking data.
+ Here is the call graph for this function:

◆ getBlockedUsersInformation()

ilLMTracker::getBlockedUsersInformation ( )

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

References $component_repository, $db, $ilDB, $lng, $name, $refinery, ilObjUser\_lookupName(), ilLMObject\_lookupTitle(), ilPageQuestionProcessor\getAnswerStatus(), and ilLMPageObject\queryQuestionsOfLearningModule().

536  : array
537  {
538  $ilDB = $this->db;
539  $lng = $this->lng;
542 
543  $blocked_users = array();
544 
545  // load question/pages information
546  $this->page_questions = array();
547  $this->all_questions = array();
548  $page_for_question = array();
549  $q = ilLMPageObject::queryQuestionsOfLearningModule($this->lm_obj_id, "", "", 0, 0);
550  foreach ($q["set"] as $quest) {
551  $this->page_questions[$quest["page_id"]][] = $quest["question_id"];
552  $this->all_questions[] = $quest["question_id"];
553  $page_for_question[$quest["question_id"]] = $quest["page_id"];
554  }
555  // get question information
557  $qlist->setParentObjId(0);
558  $qlist->setJoinObjectData(false);
559  $qlist->addFieldFilter("question_id", $this->all_questions);
560  $qlist->load();
561  $qdata = $qlist->getQuestionDataArray();
562 
563  // load question answer information
564  $this->answer_status = ilPageQuestionProcessor::getAnswerStatus($this->all_questions);
565  foreach ($this->answer_status as $as) {
566  if ($as["try"] >= $qdata[$as["qst_id"]]["nr_of_tries"] && $qdata[$as["qst_id"]]["nr_of_tries"] > 0 && !$as["passed"]) {
567  //var_dump($qdata[$as["qst_id"]]);
568  $name = ilObjUser::_lookupName($as["user_id"]);
569  $as["user_name"] = $name["lastname"] . ", " . $name["firstname"] . " [" . $name["login"] . "]";
570  $as["question_text"] = $qdata[$as["qst_id"]]["question_text"];
571  $as["page_id"] = $page_for_question[$as["qst_id"]];
572  $as["page_title"] = ilLMPageObject::_lookupTitle($as["page_id"]);
573  $blocked_users[] = $as;
574  }
575  }
576 
577  return $blocked_users;
578  }
static queryQuestionsOfLearningModule(int $a_lm_id, string $a_order_field, string $a_order_dir, int $a_offset, int $a_limit)
Get questions of learning module.
static _lookupName(int $a_user_id)
lookup user name
static getAnswerStatus( $a_q_id, int $a_user_id=0)
ilDBInterface $db
static _lookupTitle(int $a_obj_id)
if($format !==null) $name
Definition: metadata.php:247
ilLanguage $lng
ilComponentRepository $component_repository
Refinery $refinery
+ Here is the call graph for this function:

◆ getCurrentPage()

ilLMTracker::getCurrentPage ( )

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

References $current_page_id.

Referenced by determineProgressStatus(), and loadLMTrackingData().

298  : int
299  {
300  return $this->current_page_id;
301  }
+ Here is the caller graph for this function:

◆ getIconForLMObject()

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

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

References COMPLETED, FAILED, ilLPStatusIcons\getInstance(), ilLPStatusIcons\ICON_VARIANT_SHORT, IN_PROGRESS, and loadLMTrackingData().

490  : string {
491  $this->loadLMTrackingData();
493 
494  if ($a_node["child"] == $a_highlighted_node) {
495  return $icons->getImagePathRunning();
496  }
497  if (isset($this->tree_arr["nodes"][$a_node["child"]])) {
498  switch ($this->tree_arr["nodes"][$a_node["child"]]["status"]) {
500  return $icons->getImagePathInProgress();
501 
502  case ilLMTracker::FAILED:
503  return $icons->getImagePathFailed();
504 
506  return $icons->getImagePathCompleted();
507  }
508  }
509  return $icons->getImagePathNotAttempted();
510  }
static getInstance(int $variant=ilLPStatusIcons::ICON_VARIANT_DEFAULT, ?\ILIAS\UI\Renderer $renderer=null, ?\ILIAS\UI\Factory $factory=null)
loadLMTrackingData()
Load LM tracking data.
+ Here is the call graph for this function:

◆ getInstance()

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

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

References $DIC, and $ilUser.

Referenced by ilLMBlockedUsersTableGUI\__construct().

85  : self {
86  global $DIC;
87 
88  $ilUser = $DIC->user();
89 
90  if ($a_user_id == 0) {
91  $a_user_id = $ilUser->getId();
92  }
93 
94  if (!isset(self::$instances[$a_ref_id][$a_user_id])) {
95  self::$instances[$a_ref_id][$a_user_id] = new ilLMTracker($a_ref_id, false, $a_user_id);
96  }
97  return self::$instances[$a_ref_id][$a_user_id];
98  }
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $DIC
Definition: feed.php:28
$ilUser
Definition: imgupload.php:34
+ Here is the caller graph for this function:

◆ getInstanceByObjId()

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

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

References $DIC, and $ilUser.

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

103  : self {
104  global $DIC;
105 
106  $ilUser = $DIC->user();
107 
108  if ($a_user_id == 0) {
109  $a_user_id = $ilUser->getId();
110  }
111 
112  if (!isset(self::$instancesbyobj[$a_obj_id][$a_user_id])) {
113  self::$instancesbyobj[$a_obj_id][$a_user_id] = new ilLMTracker($a_obj_id, true, $a_user_id);
114  }
115  return self::$instancesbyobj[$a_obj_id][$a_user_id];
116  }
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $DIC
Definition: feed.php:28
$ilUser
Definition: imgupload.php:34
+ Here is the caller graph for this function:

◆ hasPredIncorrectAnswers()

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

Has predecessing incorrect answers.

Returns
bool true if incorrect/unsanswered questions exist in predecessing pages

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

References loadLMTrackingData().

Referenced by ilLMPresentationGUI\filterNonAccessibleNode().

519  {
520  $this->loadLMTrackingData();
521  $ret = false;
522  if (isset($this->tree_arr["nodes"][$a_obj_id])) {
523  if ($a_ignore_unlock) {
524  $ret = $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_answers"] ?? false;
525  } else {
526  $ret = $this->tree_arr["nodes"][$a_obj_id]["has_pred_incorrect_not_unlocked_answers"] ?? false;
527  }
528  }
529  return $ret;
530  }
loadLMTrackingData()
Load LM tracking data.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ loadLMTrackingData()

ilLMTracker::loadLMTrackingData ( )
protected

Load LM tracking data.

Loaded when needed.

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

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

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

306  : void
307  {
308  $ilDB = $this->db;
309 
310  // we must prevent loading tracking data multiple times during a request where possible
311  // please note that the dirty flag works only to a certain limit
312  // e.g. if questions are answered the flag is not set (yet)
313  // or if pages/chapter are added/deleted the flag is not set
314  if ((int) $this->loaded_for_node === $this->getCurrentPage() && $this->getCurrentPage() > 0 && !$this->dirty) {
315  return;
316  }
317 
318  $this->loaded_for_node = $this->getCurrentPage();
319  $this->dirty = false;
320 
321  // load lm tree in array
322  $this->tree_arr = array();
323  $nodes = $this->lm_tree->getCompleteTree();
324  foreach ($nodes as $node) {
325  $this->tree_arr["childs"][$node["parent"]][] = $node;
326  $this->tree_arr["parent"][$node["child"]] = $node["parent"];
327  $this->tree_arr["nodes"][$node["child"]] = $node;
328  }
329 
330  // load all lm obj ids of learning module
331  $this->lm_obj_ids = ilLMObject::_getAllLMObjectsOfLM($this->lm_obj_id);
332 
333  // load read event data
334  $this->re_arr = array();
335  $set = $ilDB->query("SELECT * FROM lm_read_event " .
336  " WHERE " . $ilDB->in("obj_id", $this->lm_obj_ids, false, "integer") .
337  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
338  while ($rec = $ilDB->fetchAssoc($set)) {
339  $this->re_arr[$rec["obj_id"]] = $rec;
340  }
341 
342  // load question/pages information
343  $this->page_questions = array();
344  $this->all_questions = array();
345  $q = ilLMPageObject::queryQuestionsOfLearningModule($this->lm_obj_id, "", "", 0, 0);
346  foreach ($q["set"] as $quest) {
347  $this->page_questions[$quest["page_id"]][] = $quest["question_id"];
348  $this->all_questions[] = $quest["question_id"];
349  }
350 
351  // load question answer information
352  $this->answer_status = ilPageQuestionProcessor::getAnswerStatus($this->all_questions, $this->user_id);
353 
354  $this->has_incorrect_answers = false;
355 
356  $has_pred_incorrect_answers = false;
357  $has_pred_incorrect_not_unlocked_answers = false;
358  $this->determineProgressStatus($this->lm_tree->readRootId(), $has_pred_incorrect_answers, $has_pred_incorrect_not_unlocked_answers);
359 
360  $this->has_incorrect_answers = $has_pred_incorrect_answers;
361  }
static queryQuestionsOfLearningModule(int $a_lm_id, string $a_order_field, string $a_order_dir, int $a_offset, int $a_limit)
Get questions of learning module.
static getAnswerStatus( $a_q_id, int $a_user_id=0)
ilDBInterface $db
determineProgressStatus(int $a_obj_id, bool &$a_has_pred_incorrect_answers, bool &$a_has_pred_incorrect_not_unlocked_answers)
Determine progress status of nodes.
static _getAllLMObjectsOfLM(int $a_lm_id, string $a_type="")
Get all objects of learning module.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setCurrentPage()

ilLMTracker::setCurrentPage ( int  $a_val)

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

294  : void {
295  $this->current_page_id = $a_val;
296  }

◆ trackAccess()

ilLMTracker::trackAccess ( int  $a_page_id,
int  $user_id 
)

Track access to lm page.

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

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

128  : void {
129  if ($user_id == ANONYMOUS_USER_ID) {
130  ilChangeEvent::_recordReadEvent("lm", $this->lm_ref_id, $this->lm_obj_id, $user_id);
131  return;
132  }
133 
134  if ($this->lm_ref_id == 0) {
135  throw new ilLMPresentationException("ilLMTracker: No Ref Id given.");
136  }
137 
138  // track page and chapter access
139  $this->trackPageAndChapterAccess($a_page_id);
140 
141  // track last page access (must be done after calling trackPageAndChapterAccess())
142  $this->trackLastPageAccess($this->user_id, $this->lm_ref_id, $a_page_id);
143 
144  // #9483
145  // general learning module lp tracking
147  $this->user_id,
148  $this->lm_obj_id,
149  $this->lm_ref_id,
150  "lm"
151  );
152 
153  // obsolete?
154  ilLPStatusWrapper::_updateStatus($this->lm_obj_id, $this->user_id);
155 
156  // mark currently loaded data as dirty to force reload if necessary
157  $this->dirty = true;
158  }
const ANONYMOUS_USER_ID
Definition: constants.php:27
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _tracProgress(int $a_user_id, int $a_obj_id, int $a_ref_id, string $a_obj_type='')
trackLastPageAccess(int $usr_id, int $lm_id, int $obj_id)
Track last accessed page for a learning module.
trackPageAndChapterAccess(int $a_page_id)
static _recordReadEvent(string $a_type, int $a_ref_id, int $obj_id, int $usr_id, bool $isCatchupWriteEvents=true, $a_ext_rc=null, $a_ext_time=null)
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
+ Here is the call graph for this function:

◆ trackLastPageAccess()

ilLMTracker::trackLastPageAccess ( int  $usr_id,
int  $lm_id,
int  $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 166 of file class.ilLMTracker.php.

References $db, ilUtil\now(), and ilDBInterface\replace().

Referenced by trackAccess().

170  : void {
171  $title = "";
172  $db = $this->db;
173  $db->replace(
174  "lo_access",
175  [
176  "usr_id" => ["integer", $usr_id],
177  "lm_id" => ["integer", $lm_id]
178  ],
179  [
180  "timestamp" => ["timestamp", ilUtil::now()],
181  "obj_id" => ["integer", $obj_id],
182  "lm_title" => ["text", $title]
183  ]
184  );
185  }
static now()
Return current timestamp in Y-m-d H:i:s format.
ilDBInterface $db
replace(string $table, array $primary_keys, array $other_columns)
Replace into method.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trackPageAndChapterAccess()

ilLMTracker::trackPageAndChapterAccess ( int  $a_page_id)
protected

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

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

Referenced by trackAccess().

189  : void {
190  $ilDB = $this->db;
191 
192  $now = time();
193 
194  //
195  // 1. Page access: current page
196  //
197  $set = $ilDB->query("SELECT obj_id FROM lm_read_event" .
198  " WHERE obj_id = " . $ilDB->quote($a_page_id, "integer") .
199  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
200  if (!$ilDB->fetchAssoc($set)) {
201  $fields = array(
202  "obj_id" => array("integer", $a_page_id),
203  "usr_id" => array("integer", $this->user_id)
204  );
205  // $ilDB->insert("lm_read_event", $fields);
206  $ilDB->replace("lm_read_event", $fields, array()); // #15144
207  }
208 
209  // update all parent chapters
210  $ilDB->manipulate("UPDATE lm_read_event SET" .
211  " read_count = read_count + 1 " .
212  " , last_access = " . $ilDB->quote($now, "integer") .
213  " WHERE obj_id = " . $ilDB->quote($a_page_id, "integer") .
214  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
215 
216 
217  //
218  // 2. Chapter access: based on last page accessed
219  //
220 
221  // get last accessed page
222  $set = $ilDB->query("SELECT * FROM lo_access WHERE " .
223  "usr_id = " . $ilDB->quote($this->user_id, "integer") . " AND " .
224  "lm_id = " . $ilDB->quote($this->lm_ref_id, "integer"));
225  $res = $ilDB->fetchAssoc($set);
226  if (isset($res["obj_id"])) {
227  $valid_timespan = ilObjUserTracking::_getValidTimeSpan();
228 
229  $pg_ts = new ilDateTime($res["timestamp"], IL_CAL_DATETIME);
230  $pg_ts = $pg_ts->get(IL_CAL_UNIX);
231  $pg_id = $res["obj_id"];
232  if (!$this->lm_tree->isInTree($pg_id)) {
233  return;
234  }
235 
236  $time_diff = $read_diff = 0;
237 
238  // spent_seconds or read_count ?
239  if (($now - $pg_ts) <= $valid_timespan) {
240  $time_diff = $now - $pg_ts;
241  } else {
242  $read_diff = 1;
243  }
244 
245  // find parent chapter(s) for that page
246  $parent_st_ids = array();
247  foreach ($this->lm_tree->getPathFull($pg_id) as $item) {
248  if ($item["type"] == "st") {
249  $parent_st_ids[] = $item["obj_id"];
250  }
251  }
252 
253  if ($parent_st_ids && ($time_diff || $read_diff)) {
254  // get existing chapter entries
255  $ex_st = array();
256  $set = $ilDB->query("SELECT obj_id FROM lm_read_event" .
257  " WHERE " . $ilDB->in("obj_id", $parent_st_ids, "", "integer") .
258  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
259  while ($row = $ilDB->fetchAssoc($set)) {
260  $ex_st[] = $row["obj_id"];
261  }
262 
263  // add missing chapter entries
264  $missing_st = array_diff($parent_st_ids, $ex_st);
265  if (sizeof($missing_st)) {
266  foreach ($missing_st as $st_id) {
267  $fields = array(
268  "obj_id" => array("integer", $st_id),
269  "usr_id" => array("integer", $this->user_id)
270  );
271  // $ilDB->insert("lm_read_event", $fields);
272  $ilDB->replace("lm_read_event", $fields, array()); // #15144
273  }
274  }
275 
276  // update all parent chapters
277  $ilDB->manipulate("UPDATE lm_read_event SET" .
278  " read_count = read_count + " . $ilDB->quote($read_diff, "integer") .
279  " , spent_seconds = spent_seconds + " . $ilDB->quote($time_diff, "integer") .
280  " , last_access = " . $ilDB->quote($now, "integer") .
281  " WHERE " . $ilDB->in("obj_id", $parent_st_ids, "", "integer") .
282  " AND usr_id = " . $ilDB->quote($this->user_id, "integer"));
283  }
284  }
285  }
$res
Definition: ltiservices.php:69
const IL_CAL_DATETIME
const IL_CAL_UNIX
ilDBInterface $db
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $all_questions

array ilLMTracker::$all_questions = array()
protected

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

◆ $answer_status

array ilLMTracker::$answer_status = array()
protected

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

◆ $component_repository

ilComponentRepository ilLMTracker::$component_repository
protected

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

Referenced by getBlockedUsersInformation().

◆ $current_page_id

int ilLMTracker::$current_page_id = 0
protected

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

Referenced by getCurrentPage().

◆ $db

◆ $dirty

bool ilLMTracker::$dirty = false
protected

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

◆ $has_incorrect_answers

bool ilLMTracker::$has_incorrect_answers = false
protected

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

◆ $instances

array ilLMTracker::$instances = array()
static

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

◆ $instancesbyobj

array ilLMTracker::$instancesbyobj = array()
static

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

◆ $lm_obj_id

int ilLMTracker::$lm_obj_id
protected

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

◆ $lm_obj_ids

array ilLMTracker::$lm_obj_ids = array()
protected

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

◆ $lm_ref_id

int ilLMTracker::$lm_ref_id
protected

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

◆ $lm_tree

ilLMTree ilLMTracker::$lm_tree
protected

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

◆ $lng

ilLanguage ilLMTracker::$lng
protected

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

Referenced by getBlockedUsersInformation().

◆ $loaded_for_node

bool ilLMTracker::$loaded_for_node = false
protected

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

◆ $page_questions

array ilLMTracker::$page_questions = array()
protected

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

◆ $re_arr

array ilLMTracker::$re_arr = array()
protected

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

◆ $refinery

Refinery ilLMTracker::$refinery
protected

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

Referenced by getBlockedUsersInformation().

◆ $tree_arr

array ilLMTracker::$tree_arr = array()
protected

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

◆ $user

ilObjUser ilLMTracker::$user
protected

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

◆ $user_id

int ilLMTracker::$user_id
protected

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

◆ COMPLETED

const ilLMTracker::COMPLETED = 2

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

Referenced by determineProgressStatus(), and getIconForLMObject().

◆ CURRENT

const ilLMTracker::CURRENT = 99

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

Referenced by determineProgressStatus().

◆ FAILED

const ilLMTracker::FAILED = 3

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

Referenced by determineProgressStatus(), and getIconForLMObject().

◆ IN_PROGRESS

const ilLMTracker::IN_PROGRESS = 1

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

Referenced by determineProgressStatus(), and getIconForLMObject().

◆ NOT_ATTEMPTED

const ilLMTracker::NOT_ATTEMPTED = 0

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

Referenced by determineProgressStatus().


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