46 private function __construct($a_id, $a_by_obj_id =
false, $a_user_id)
48 $this->user_id = $a_user_id;
53 $this->lm_obj_id = $a_id;
57 $this->lm_ref_id = $a_id;
61 include_once(
"./Modules/LearningModule/classes/class.ilLMTree.php");
77 $a_user_id = $ilUser->getId();
80 if (!isset(self::$instances[$a_ref_id][$a_user_id]))
82 self::$instances[$a_ref_id][$a_user_id] =
new ilLMTracker($a_ref_id,
false, $a_user_id);
84 return self::$instances[$a_ref_id][$a_user_id];
99 $a_user_id = $ilUser->getId();
102 if (!isset(self::$instancesbyobj[$a_obj_id][$a_user_id]))
104 self::$instancesbyobj[$a_obj_id][$a_user_id] =
new ilLMTracker($a_obj_id,
true, $a_user_id);
106 return self::$instancesbyobj[$a_obj_id][$a_user_id];
120 if ($this->lm_ref_id == 0)
122 die(
"ilLMTracker: No Ref Id given.");
133 include_once(
"./Services/Tracking/classes/class.ilLearningProgress.php");
135 $this->lm_ref_id,
"lm");
138 include_once(
"./Services/Tracking/classes/class.ilLPStatusWrapper.php");
157 $q =
"DELETE FROM lo_access ".
158 "WHERE usr_id = ".$ilDB->quote((
int) $usr_id,
"integer").
" ".
159 "AND lm_id = ".$ilDB->quote((
int) $lm_id,
"integer");
160 $ilDB->manipulate($q);
164 $q =
"INSERT INTO lo_access ".
165 "(timestamp,usr_id,lm_id,obj_id,lm_title) ".
167 "(".$ilDB->now().
",".
168 $ilDB->quote((
int) $usr_id,
"integer").
",".
169 $ilDB->quote((
int) $lm_id,
"integer").
",".
170 $ilDB->quote((
int) $obj_id,
"integer").
",".
171 $ilDB->quote(
$title,
"text").
")";
172 $ilDB->manipulate($q);
188 $set = $ilDB->query(
"SELECT obj_id FROM lm_read_event".
189 " WHERE obj_id = ".$ilDB->quote($a_page_id,
"integer").
190 " AND usr_id = ".$ilDB->quote($this->user_id,
"integer"));
191 if (!$ilDB->fetchAssoc($set))
194 "obj_id" =>
array(
"integer", $a_page_id),
195 "usr_id" =>
array(
"integer", $this->user_id)
198 $ilDB->replace(
"lm_read_event", $fields,
array());
202 $ilDB->manipulate(
"UPDATE lm_read_event SET".
203 " read_count = read_count + 1 ".
204 " , last_access = ".$ilDB->quote($now,
"integer").
205 " WHERE obj_id = ".$ilDB->quote($a_page_id,
"integer").
206 " AND usr_id = ".$ilDB->quote($this->user_id,
"integer"));
214 $set = $ilDB->query(
"SELECT * FROM lo_access WHERE ".
215 "usr_id = ".$ilDB->quote($this->user_id,
"integer").
" AND ".
216 "lm_id = ".$ilDB->quote($this->lm_ref_id,
"integer"));
217 $res = $ilDB->fetchAssoc($set);
220 include_once(
'Services/Tracking/classes/class.ilObjUserTracking.php');
225 $pg_id =
$res[
"obj_id"];
226 if(!$this->lm_tree->isInTree($pg_id))
234 if (($now-$pg_ts) <= $valid_timespan)
244 $parent_st_ids =
array();
245 foreach($this->lm_tree->getPathFull($pg_id) as $item)
247 if($item[
"type"] ==
"st")
249 $parent_st_ids[] = $item[
"obj_id"];
253 if($parent_st_ids && (
$time_diff || $read_diff))
257 $set = $ilDB->query(
"SELECT obj_id FROM lm_read_event".
258 " WHERE ".$ilDB->in(
"obj_id", $parent_st_ids,
"",
"integer").
259 " AND usr_id = ".$ilDB->quote($this->user_id,
"integer"));
260 while(
$row = $ilDB->fetchAssoc($set))
262 $ex_st[] =
$row[
"obj_id"];
266 $missing_st = array_diff($parent_st_ids, $ex_st);
267 if(
sizeof($missing_st))
269 foreach($missing_st as $st_id)
272 "obj_id" =>
array(
"integer", $st_id),
273 "usr_id" =>
array(
"integer", $this->user_id)
276 $ilDB->replace(
"lm_read_event", $fields,
array());
281 $ilDB->manipulate(
"UPDATE lm_read_event SET".
282 " read_count = read_count + ".$ilDB->quote($read_diff,
"integer").
283 " , spent_seconds = spent_seconds + ".$ilDB->quote(
$time_diff,
"integer").
284 " , last_access = ".$ilDB->quote($now,
"integer").
285 " WHERE ".$ilDB->in(
"obj_id", $parent_st_ids,
"",
"integer").
286 " AND usr_id = ".$ilDB->quote($this->user_id,
"integer"));
303 $this->current_page_id = $a_val;
330 if ($this->loaded_for_node === (
int) $this->
getCurrentPage() && !$this->dirty)
336 $this->dirty =
false;
339 $this->tree_arr =
array();
340 $nodes = $this->lm_tree->getSubTree($this->lm_tree->getNodeData($this->lm_tree->readRootId()));
341 foreach ($nodes as $node)
343 $this->tree_arr[
"childs"][$node[
"parent"]][] = $node;
344 $this->tree_arr[
"parent"][$node[
"child"]] = $node[
"parent"];
345 $this->tree_arr[
"nodes"][$node[
"child"]] = $node;
349 include_once(
"./Modules/LearningModule/classes/class.ilLMObject.php");
353 $this->re_arr =
array();
354 $set = $ilDB->query(
"SELECT * FROM lm_read_event ".
355 " WHERE ".$ilDB->in(
"obj_id", $this->lm_obj_ids,
false,
"integer").
356 " AND usr_id = ".$ilDB->quote($this->user_id,
"integer"));
357 while ($rec = $ilDB->fetchAssoc($set))
359 $this->re_arr[$rec[
"obj_id"]] = $rec;
363 $this->page_questions =
array();
364 $this->all_questions =
array();
365 include_once(
"./Modules/LearningModule/classes/class.ilLMPageObject.php");
367 foreach ($q[
"set"] as $quest)
369 $this->page_questions[$quest[
"page_id"]][] = $quest[
"question_id"];
370 $this->all_questions[] = $quest[
"question_id"];
374 include_once(
"./Services/COPage/classes/class.ilPageQuestionProcessor.php");
377 $this->has_incorrect_answers =
false;
379 $has_pred_incorrect_answers =
false;
380 $has_pred_incorrect_not_unlocked_answers =
false;
381 $this->
determineProgressStatus($this->lm_tree->readRootId(), $has_pred_incorrect_answers, $has_pred_incorrect_not_unlocked_answers);
383 $this->has_incorrect_answers = $has_pred_incorrect_answers;
394 if (count($this->all_questions) > 0 && !$this->has_incorrect_answers)
408 protected function determineProgressStatus($a_obj_id, &$a_has_pred_incorrect_answers, &$a_has_pred_incorrect_not_unlocked_answers)
412 if (isset($this->tree_arr[
"nodes"][$a_obj_id]))
414 $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_answers"] = $a_has_pred_incorrect_answers;
415 $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_not_unlocked_answers"] = $a_has_pred_incorrect_not_unlocked_answers;
417 if (is_array($this->tree_arr[
"childs"][$a_obj_id]))
420 $this->tree_arr[
"childs"][$a_obj_id] =
ilUtil::sortArray($this->tree_arr[
"childs"][$a_obj_id],
"lft",
"asc",
true);
423 foreach ($this->tree_arr[
"childs"][$a_obj_id] as $c)
428 if (!self::_isNodeVisible($c))
434 $a_has_pred_incorrect_not_unlocked_answers);
453 if ($this->tree_arr[
"nodes"][$c[
"child"]][
"type"] ==
"pg")
456 ($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"])
461 $a_has_pred_incorrect_not_unlocked_answers =
true;
466 if ($cnt_completed == count($this->tree_arr[
"childs"][$a_obj_id]))
471 else if ($this->tree_arr[
"nodes"][$a_obj_id][
"type"] ==
"pg")
474 if (isset($this->re_arr[$a_obj_id]) && $this->re_arr[$a_obj_id][
"read_count"] > 0)
484 if (is_array($this->page_questions[$a_obj_id]))
488 foreach ($this->page_questions[$a_obj_id] as $q_id)
490 if (is_array($this->answer_status[$q_id])
491 && $this->answer_status[$q_id][
"try"] > 0
492 && !$this->answer_status[$q_id][
"passed"])
495 if (!$this->answer_status[$q_id][
"unlocked"])
505 foreach ($this->page_questions[$a_obj_id] as $q_id)
507 if (!is_array($this->answer_status[$q_id])
508 || $this->answer_status[$q_id][
"try"] == 0)
519 $this->tree_arr[
"nodes"][$a_obj_id][
"unlocked"] = $unlocked;
520 $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_answers"] = $a_has_pred_incorrect_answers;
521 $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_not_unlocked_answers"] = $a_has_pred_incorrect_not_unlocked_answers;
528 $this->tree_arr[
"nodes"][$a_obj_id][
"status"] = $status;
544 if ($a_node[
"child"] == $a_highlighted_node)
548 if (isset($this->tree_arr[
"nodes"][$a_node[
"child"]]))
550 switch ($this->tree_arr[
"nodes"][$a_node[
"child"]][
"status"])
575 if (is_array($this->tree_arr[
"nodes"][$a_obj_id]))
577 if ($a_ignore_unlock)
579 $ret = $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_answers"];
583 $ret = $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_not_unlocked_answers"];
603 $blocked_users =
array();
606 $this->page_questions =
array();
607 $this->all_questions =
array();
608 $page_for_question =
array();
609 include_once(
"./Modules/LearningModule/classes/class.ilLMPageObject.php");
611 foreach ($q[
"set"] as $quest)
613 $this->page_questions[$quest[
"page_id"]][] = $quest[
"question_id"];
614 $this->all_questions[] = $quest[
"question_id"];
615 $page_for_question[$quest[
"question_id"]] = $quest[
"page_id"];
618 include_once(
"./Modules/TestQuestionPool/classes/class.ilAssQuestionList.php");
620 $qlist->setParentObjId(0);
621 $qlist->setJoinObjectData(
false);
622 $qlist->addFieldFilter(
"question_id", $this->all_questions);
624 $qdata = $qlist->getQuestionDataArray();
627 include_once(
"./Services/COPage/classes/class.ilPageQuestionProcessor.php");
629 include_once(
"./Modules/LearningModule/classes/class.ilLMPageObject.php");
630 foreach ($this->answer_status as $as)
632 if ($as[
"try"] >= $qdata[$as[
"qst_id"]][
"nr_of_tries"] && $qdata[$as[
"qst_id"]][
"nr_of_tries"] > 0 && !$as[
"passed"])
636 $as[
"user_name"] = $name[
"lastname"].
", ".$name[
"firstname"].
" [".$name[
"login"].
"]";
637 $as[
"question_text"] = $qdata[$as[
"qst_id"]][
"question_text"];
638 $as[
"page_id"] = $page_for_question[$as[
"qst_id"]];
640 $blocked_users[] = $as;
644 return $blocked_users;
655 include_once(
"./Services/COPage/classes/class.ilPageObject.php");
657 if ($a_node[
"type"] !=
"pg")
664 $lm_set->get(
"time_scheduled_page_activation"));
669 if ($act_data[
"show_activation_info"] &&
static _lookupName($a_user_id)
lookup user name
Track access to ILIAS learning modules.
hasPredIncorrectAnswers($a_obj_id, $a_ignore_unlock=false)
Has predecessing incorrect answers.
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.
getBlockedUsersInformation()
Get blocked users information.
setCurrentPage($a_val)
Set current page.
static _getAllLMObjectsOfLM($a_lm_id, $a_type="")
Get all objects of learning module.
static _tracProgress($a_user_id, $a_obj_id, $a_ref_id, $a_obj_type='')
static queryQuestionsOfLearningModule($a_lm_id, $a_order_field, $a_order_dir, $a_offset, $a_limit)
Get questions of learning module.
getIconForLMObject($a_node, $a_highlighted_node=0)
Get icon for lm object.
static _lookupTitle($a_obj_id)
Lookup title.
static sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static getInstanceByObjId($a_obj_id, $a_user_id=0)
Get instance.
static now()
Return current timestamp in Y-m-d H:i:s format.
getCurrentPage()
Get current page.
trackPageAndChapterAccess($a_page_id)
Track page and chapter access.
static getAnswerStatus($a_q_id, $a_user_id=0)
Get statistics for question.
getAllQuestionsCorrect()
Have all questoins been answered correctly (and questions exist)?
static _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation=false, $a_lang="-")
lookup activation status
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static _lookupObjId($a_id)
static getInstance($a_tree_id)
Get Instance.
determineProgressStatus($a_obj_id, &$a_has_pred_incorrect_answers, &$a_has_pred_incorrect_not_unlocked_answers)
Determine progress status of nodes.
Create styles array
The data for the language used.
trackAccess($a_page_id)
Track access to lm page.
static getInstance($a_ref_id, $a_user_id=0)
Get instance.
static _lookupActivationData($a_id, $a_parent_type, $a_lang="-")
Lookup activation data.
__construct($a_id, $a_by_obj_id=false, $a_user_id)
Constructor.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
static _isNodeVisible($a_node)
Is node visible for the learner.
loadLMTrackingData()
Load LM tracking data.
static _getValidTimeSpan()