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))
231 $time_diff = $read_diff = 0;
234 if (($now-$pg_ts) <= $valid_timespan)
236 $time_diff = $now-$pg_ts;
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);
454 ($c_stat ==
ilLMTracker::NOT_ATTEMPTED && is_array($this->page_questions[$c[
"child"]]) && count($this->page_questions[$c[
"child"]]) > 0))
456 $a_has_pred_incorrect_answers =
true;
457 if (!$this->tree_arr[
"nodes"][$c[
"child"]][
"unlocked"])
459 $a_has_pred_incorrect_not_unlocked_answers =
true;
463 if ($cnt_completed == count($this->tree_arr[
"childs"][$a_obj_id]))
468 else if ($this->tree_arr[
"nodes"][$a_obj_id][
"type"] ==
"pg")
471 if (isset($this->re_arr[$a_obj_id]) && $this->re_arr[$a_obj_id][
"read_count"] > 0)
481 if (is_array($this->page_questions[$a_obj_id]))
485 foreach ($this->page_questions[$a_obj_id] as $q_id)
487 if (is_array($this->answer_status[$q_id])
488 && $this->answer_status[$q_id][
"try"] > 0
489 && !$this->answer_status[$q_id][
"passed"])
492 if (!$this->answer_status[$q_id][
"unlocked"])
502 foreach ($this->page_questions[$a_obj_id] as $q_id)
504 if (!is_array($this->answer_status[$q_id])
505 || $this->answer_status[$q_id][
"try"] == 0)
516 $this->tree_arr[
"nodes"][$a_obj_id][
"unlocked"] = $unlocked;
517 $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_answers"] = $a_has_pred_incorrect_answers;
518 $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_not_unlocked_answers"] = $a_has_pred_incorrect_not_unlocked_answers;
525 $this->tree_arr[
"nodes"][$a_obj_id][
"status"] = $status;
541 if ($a_node[
"child"] == $a_highlighted_node)
545 if (isset($this->tree_arr[
"nodes"][$a_node[
"child"]]))
547 switch ($this->tree_arr[
"nodes"][$a_node[
"child"]][
"status"])
572 if (is_array($this->tree_arr[
"nodes"][$a_obj_id]))
574 if ($a_ignore_unlock)
576 $ret = $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_answers"];
580 $ret = $this->tree_arr[
"nodes"][$a_obj_id][
"has_pred_incorrect_not_unlocked_answers"];
601 $blocked_users = array();
604 $this->page_questions = array();
605 $this->all_questions = array();
606 $page_for_question = array();
607 include_once(
"./Modules/LearningModule/classes/class.ilLMPageObject.php");
609 foreach ($q[
"set"] as $quest)
611 $this->page_questions[$quest[
"page_id"]][] = $quest[
"question_id"];
612 $this->all_questions[] = $quest[
"question_id"];
613 $page_for_question[$quest[
"question_id"]] = $quest[
"page_id"];
617 include_once(
"./Modules/TestQuestionPool/classes/class.ilAssQuestionList.php");
619 $qlist->addFieldFilter(
"question_id", $this->all_questions);
621 $qdata = $qlist->getQuestionDataArray();
624 include_once(
"./Services/COPage/classes/class.ilPageQuestionProcessor.php");
627 include_once(
"./Modules/LearningModule/classes/class.ilLMPageObject.php");
628 foreach ($this->answer_status as $as)
630 if ($as[
"try"] >= $qdata[$as[
"qst_id"]][
"nr_of_tries"] && $qdata[$as[
"qst_id"]][
"nr_of_tries"] > 0 && !$as[
"passed"])
634 $as[
"user_name"] = $name[
"lastname"].
", ".$name[
"firstname"].
" [".$name[
"login"].
"]";
635 $as[
"question_text"] = $qdata[$as[
"qst_id"]][
"question_text"];
636 $as[
"page_id"] = $page_for_question[$as[
"qst_id"]];
638 $blocked_users[] = $as;
642 return $blocked_users;
653 include_once(
"./Services/COPage/classes/class.ilPageObject.php");
655 if ($a_node[
"type"] !=
"pg")
662 $lm_set->get(
"time_scheduled_page_activation"));
667 if ($act_data[
"show_activation_info"] &&