66 if ($parent_obj_id == null)
68 $pset = $ilDB->query(
'SELECT r2.obj_id par_obj_id FROM object_reference r1 '.
69 'JOIN tree t ON t.child = r1.ref_id '.
70 'JOIN object_reference r2 ON r2.ref_id = t.parent '.
71 'WHERE r1.obj_id = '.$ilDB->quote($obj_id,
'integer'));
73 while ($prec = $ilDB->fetchAssoc($pset))
75 $nid = $ilDB->nextId(
"write_event");
76 $query = sprintf(
'INSERT INTO write_event '.
77 '(write_id, obj_id, parent_obj_id, usr_id, action, ts) VALUES '.
78 '(%s, %s, %s, %s, %s, '.$ilDB->now().
')',
79 $ilDB->quote($nid,
'integer'),
80 $ilDB->quote($obj_id,
'integer'),
81 $ilDB->quote($prec[
"par_obj_id"],
'integer'),
82 $ilDB->quote($usr_id,
'integer'),
83 $ilDB->quote($action,
'text'));
85 $aff = $ilDB->manipulate(
$query);
90 $nid = $ilDB->nextId(
"write_event");
91 $query = sprintf(
'INSERT INTO write_event '.
92 '(write_id, obj_id, parent_obj_id, usr_id, action, ts) '.
93 'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().
')',
94 $ilDB->quote($nid,
'integer'),
95 $ilDB->quote($obj_id,
'integer'),
96 $ilDB->quote($parent_obj_id,
'integer'),
97 $ilDB->quote($usr_id,
'integer'),
98 $ilDB->quote($action,
'text'));
99 $aff = $ilDB->manipulate(
$query);
114 $isCatchupWriteEvents =
true, $a_ext_rc =
false, $a_ext_time =
false)
125 include_once(
'Services/Tracking/classes/class.ilObjUserTracking.php');
128 $query = sprintf(
'SELECT * FROM read_event '.
129 'WHERE obj_id = %s '.
131 $ilDB->quote($obj_id,
'integer'),
132 $ilDB->quote($usr_id,
'integer'));
134 $row = $ilDB->fetchObject($res);
137 if ($a_ext_rc !==
false)
139 $read_count =
'read_count = '.$ilDB->quote($a_ext_rc,
"integer").
", ";
140 $read_count_init = max(1, (
int) $a_ext_rc);
141 $read_count_diff = max(1, (
int) $a_ext_rc) -
$row->read_count;
145 $read_count =
'read_count = read_count + 1, ';
146 $read_count_init = 1;
147 $read_count_diff = 1;
153 if ($a_ext_time !==
false)
155 $time = (int) $a_ext_time;
159 $time = $ilDB->quote((time() -
$row->last_access) <= $validTimeSpan
160 ?
$row->spent_seconds + time() -
$row->last_access
161 :
$row->spent_seconds,
'integer');
166 if ((time() -
$row->last_access) <= $validTimeSpan)
169 $read_count_init = 1;
170 $read_count_diff = 0;
173 $time_diff = $time - (int)
$row->spent_seconds;
176 $query = sprintf(
'UPDATE read_event SET '.
178 'spent_seconds = %s, '.
180 'WHERE obj_id = %s '.
183 $ilDB->quote(time(),
'integer'),
184 $ilDB->quote($obj_id,
'integer'),
185 $ilDB->quote($usr_id,
'integer'));
186 $aff = $ilDB->manipulate(
$query);
192 if ($a_ext_time !==
false)
194 $time = (int) $a_ext_time;
201 $time_diff = $time - (int)
$row->spent_seconds;
215 $ilDB->replace(
'read_event',
217 'obj_id' => array(
'integer', $obj_id),
218 'usr_id' => array(
'integer', $usr_id)
221 'read_count' => array(
'integer', $read_count_init),
222 'spent_seconds' => array(
'integer', $time),
223 'first_access' => array(
'timestamp', date(
"Y-m-d H:i:s")),
224 'last_access' => array(
'integer', time())
228 self::$has_accessed[$obj_id][$usr_id] =
true;
233 if ($isCatchupWriteEvents)
239 if (!in_array($a_type, array(
"cat",
"root",
"crs")))
241 if ($tree->isInTree($a_ref_id))
243 $path = $tree->getPathId($a_ref_id);
245 foreach (
$path as $p)
250 if (($p != $a_ref_id) && (in_array($obj2_type, array(
"crs",
"fold",
"grp"))))
252 $query = sprintf(
'SELECT * FROM read_event '.
253 'WHERE obj_id = %s '.
255 $ilDB->quote($obj2_id,
'integer'),
256 $ilDB->quote($usr_id,
'integer'));
257 $res2 = $ilDB->query(
$query);
258 if ($row2 = $ilDB->fetchAssoc($res2))
262 $query = sprintf(
'UPDATE read_event SET '.
263 'childs_read_count = childs_read_count + %s ,'.
264 'childs_spent_seconds = childs_spent_seconds + %s '.
265 'WHERE obj_id = %s '.
267 $ilDB->quote((
int) $read_count_diff,
'integer'),
268 $ilDB->quote((
int) $time_diff,
'integer'),
269 $ilDB->quote($obj2_id,
'integer'),
270 $ilDB->quote($usr_id,
'integer'));
271 $aff = $ilDB->manipulate(
$query);
295 $ilDB->replace(
'read_event',
297 'obj_id' => array(
'integer', $obj2_id),
298 'usr_id' => array(
'integer', $usr_id)
301 'read_count' => array(
'integer', 1),
302 'spent_seconds' => array(
'integer', $time),
303 'first_access' => array(
'timestamp', date(
"Y-m-d H:i:s")),
304 'last_access' => array(
'integer', time()),
305 'childs_read_count' => array(
'integer', (
int)$read_count_diff),
306 'childs_spent_seconds' => array(
'integer', (
int)$time_diff)
310 self::$has_accessed[$obj2_id][$usr_id] =
true;
325 function _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds = null, $a_child_read_count = null)
338 $fields[
"obj_id"] = array(
"integer", $a_obj_id);
340 $fields[
"tstamp"] = array(
"timestamp", $now);
341 $fields[
"yyyy"] = array(
"integer", date(
"Y"));
342 $fields[
"mm"] = array(
"integer", date(
"m"));
343 $fields[
"dd"] = array(
"integer", date(
"d"));
344 $fields[
"hh"] = array(
"integer", date(
"H"));
345 if($a_spent_seconds > 0)
347 $fields[
"spent_seconds"] = array(
"integer", $a_spent_seconds);
349 if($a_read_count > 0)
351 $fields[
"read_count"] = array(
"integer", $a_read_count);
353 if($a_childs_spent_seconds > 0)
355 $fields[
"childs_spent_seconds"] = array(
"integer", $a_childs_spent_seconds);
357 if($a_child_read_count > 0)
359 $fields[
"childs_read_count"] = array(
"integer", $a_child_read_count);
361 $ilDB->insert(
"obj_stat_log", $fields);
364 if(mt_rand(1, 100) == 1)
388 $set = $ilDB->query(
"SELECT COUNT(*) AS counter FROM obj_stat_log");
389 $row = $ilDB->fetchAssoc($set);
390 if(
$row[
"counter"] >= $a_minimum)
393 $ilDB->lockTables(array(array(
"name"=>
"obj_stat_log",
"type"=>
ilDB::LOCK_WRITE),
398 $set = $ilDB->query(
"SELECT COUNT(*) AS counter FROM obj_stat_log");
399 $row = $ilDB->fetchAssoc($set);
400 if(
$row[
"counter"] >= $a_minimum)
403 $ilDB->query(
"INSERT INTO obj_stat_tmp".
404 " SELECT * FROM obj_stat_log".
405 " WHERE tstamp < ".$ilDB->quote($a_now,
"timestamp"));
408 $ilDB->query(
"DELETE FROM obj_stat_log".
409 " WHERE tstamp < ".$ilDB->quote($a_now,
"timestamp"));
412 $ilDB->unlockTables();
415 $ilDB->lockTables(array(array(
"name"=>
"obj_stat_tmp",
"type"=>
ilDB::LOCK_WRITE),
419 $sql =
"SELECT obj_id, obj_type, yyyy, mm, dd, hh, SUM(read_count) AS read_count,".
420 " SUM(childs_read_count) AS childs_read_count, SUM(spent_seconds) AS spent_seconds,".
421 " SUM(childs_spent_seconds) AS childs_spent_seconds".
422 " FROM obj_stat_tmp".
423 " GROUP BY obj_id, obj_type, yyyy, mm, dd, hh";
424 $set = $ilDB->query($sql);
425 while(
$row = $ilDB->fetchAssoc($set))
428 $where = array(
"obj_id" => array(
"integer",
$row[
"obj_id"]),
429 "obj_type" => array(
"text",
$row[
"obj_type"]),
430 "yyyy" => array(
"integer",
$row[
"yyyy"]),
431 "mm" => array(
"integer",
$row[
"mm"]),
432 "dd" => array(
"integer",
$row[
"dd"]),
433 "hh" => array(
"integer",
$row[
"hh"]));
435 $where_sql = array();
436 foreach($where as $field => $def)
438 $where_sql[] = $field.
" = ".$ilDB->quote($def[1], $def[0]);
440 $where_sql = implode(
" AND ", $where_sql);
443 $check = $ilDB->query(
"SELECT read_count, childs_read_count, spent_seconds,".
444 "childs_spent_seconds".
446 " WHERE ".$where_sql);
447 if($ilDB->numRows($check))
449 $old = $ilDB->fetchAssoc($check);
452 $fields = array(
"read_count" => array(
"integer", $old[
"read_count"]+
$row[
"read_count"]),
453 "childs_read_count" => array(
"integer", $old[
"childs_read_count"]+
$row[
"childs_read_count"]),
454 "spent_seconds" => array(
"integer", $old[
"spent_seconds"]+
$row[
"spent_seconds"]),
455 "childs_spent_seconds" => array(
"integer", $old[
"childs_spent_seconds"]+
$row[
"childs_spent_seconds"]));
457 $ilDB->update(
"obj_stat", $fields, $where);
463 $fields[
"read_count"] = array(
"integer",
$row[
"read_count"]);
464 $fields[
"childs_read_count"] = array(
"integer",
$row[
"childs_read_count"]);
465 $fields[
"spent_seconds"] = array(
"integer",
$row[
"spent_seconds"]);
466 $fields[
"childs_spent_seconds"] = array(
"integer",
$row[
"childs_spent_seconds"]);
468 $ilDB->insert(
"obj_stat", $fields);
473 $ilDB->query(
"DELETE FROM obj_stat_tmp");
477 $ilDB->unlockTables();
493 $query =
"SELECT obj_id FROM catch_write_events ".
494 "WHERE obj_id = ".$ilDB->quote($obj_id ,
'integer').
" ".
495 "AND usr_id = ".$ilDB->quote($usr_id ,
'integer');
521 $ilDB->replace(
"catch_write_events",
523 "obj_id" => array(
"integer", $obj_id),
524 "usr_id" => array(
"integer", $usr_id)
527 "ts" => array(
"timestamp", $ts))
583 "FROM catch_write_events ".
584 "WHERE obj_id=".$ilDB->quote($obj_id ,
'integer').
" ".
585 "AND usr_id=".$ilDB->quote($usr_id ,
'integer');
586 $r = $ilDB->query($q);
589 $catchup =
$row[
'ts'];
594 $query = sprintf(
'SELECT * FROM write_event '.
595 'WHERE obj_id = %s '.
598 $ilDB->quote($obj_id,
'integer'),
599 $ilDB->quote($usr_id,
'integer'));
604 $query = sprintf(
'SELECT * FROM write_event '.
605 'WHERE obj_id = %s '.
609 $ilDB->quote($obj_id,
'integer'),
610 $ilDB->quote($usr_id,
'integer'),
611 $ilDB->quote($catchup,
'timestamp'));
615 while(
$row = $ilDB->fetchAssoc(
$res))
636 "FROM catch_write_events ".
637 "WHERE obj_id=".$ilDB->quote($obj_id ,
'integer').
" ".
638 "AND usr_id=".$ilDB->quote($usr_id ,
'integer');
639 $r = $ilDB->query($q);
642 $catchup =
$row[
'ts'];
648 $query = sprintf(
'SELECT * FROM write_event '.
649 'WHERE obj_id = %s '.
651 $ilDB->quote($obj_id,
'integer'),
652 $ilDB->quote($usr_id,
'integer'));
658 $query = sprintf(
'SELECT * FROM write_event '.
659 'WHERE obj_id = %s '.
662 $ilDB->quote($obj_id,
'integer'),
663 $ilDB->quote($usr_id,
'integer'),
664 $ilDB->quote($catchup,
'timestamp'));
668 $numRows =
$res->numRows();
674 return ($catchup == null) ? 1 : 2;
701 "FROM catch_write_events ".
702 "WHERE obj_id=".$ilDB->quote($parent_obj_id).
" ".
703 "AND usr_id=".$ilDB->quote($usr_id);
704 $r = $ilDB->query($q);
707 $catchup =
$row[
'ts'];
713 $query = sprintf(
'SELECT * FROM write_event '.
714 'WHERE parent_obj_id = %s '.
716 $ilDB->quote($parent_obj_id,
'integer'),
717 $ilDB->quote($usr_id,
'integer'));
723 $query = sprintf(
'SELECT * FROM write_event '.
724 'WHERE parent_obj_id = %s '.
727 $ilDB->quote($parent_obj_id,
'integer'),
728 $ilDB->quote($usr_id,
'integer'),
729 $ilDB->quote($catchup,
'timestamp'));
732 $numRows =
$res->numRows();
738 return ($catchup == null) ? 1 : 2;
795 $query = sprintf(
'SELECT * FROM read_event '.
796 'WHERE obj_id = %s '.
797 'ORDER BY last_access DESC',
798 $ilDB->quote($obj_id,
'integer'));
803 $query = sprintf(
'SELECT * FROM read_event '.
804 'WHERE obj_id = %s '.
806 'ORDER BY last_access DESC',
807 $ilDB->quote($obj_id,
'integer'),
808 $ilDB->quote($usr_id,
'integer'));
813 while (
$row = $ilDB->fetchAssoc(
$res))
815 $events[$counter][
'obj_id'] =
$row[
'obj_id'];
816 $events[$counter][
'usr_id'] =
$row[
'usr_id'];
817 $events[$counter][
'last_access'] =
$row[
'last_access'];
818 $events[$counter][
'read_count'] =
$row[
'read_count'];
819 $events[$counter][
'spent_seconds'] =
$row[
'spent_seconds'];
820 $events[$counter][
'first_access'] =
$row[
'first_access'];
825 return $events ? $events : array();
838 $query = sprintf(
'SELECT DISTINCT(usr_id) usr FROM read_event '.
839 'WHERE obj_id = %s ',
840 $ilDB->quote($a_obj_id,
'integer'));
842 while(
$row = $ilDB->fetchObject($res))
844 $users[] =
$row->usr;
846 return $users ? $users : array();
856 if (isset(self::$has_accessed[$a_obj_id][$a_usr_id]))
858 return self::$has_accessed[$a_obj_id][$a_usr_id];
861 $set = $ilDB->query(
"SELECT usr_id FROM read_event WHERE ".
862 "obj_id = ".$ilDB->quote($a_obj_id,
"integer").
" AND ".
863 "usr_id = ".$ilDB->quote($a_usr_id,
"integer")
865 if ($rec = $ilDB->fetchAssoc($set))
867 return self::$has_accessed[$a_obj_id][$a_usr_id] =
true;
869 return self::$has_accessed[$a_obj_id][$a_usr_id] =
false;
880 return 'change event tracking is already active';
892 $set = $ilDB->query(sprintf(
'SELECT r1.obj_id,r2.obj_id p,d.owner,%s,d.create_date '.
893 'FROM object_data d '.
894 'LEFT JOIN write_event w ON d.obj_id = w.obj_id '.
895 'JOIN object_reference r1 ON d.obj_id=r1.obj_id '.
896 'JOIN tree t ON t.child=r1.ref_id '.
897 'JOIN object_reference r2 on r2.ref_id=t.parent '.
898 'WHERE w.obj_id IS NULL',
899 $ilDB->quote(
'create',
'text')));
900 while ($rec = $ilDB->fetchAssoc($set))
902 $nid = $ilDB->nextId(
"write_event");
903 $query =
'INSERT INTO write_event '.
904 '(write_id, obj_id,parent_obj_id,usr_id,action,ts) VALUES ('.
905 $ilDB->quote($nid,
"integer").
",".
906 $ilDB->quote($rec[
"obj_id"],
"integer").
",".
907 $ilDB->quote($rec[
"p"],
"integer").
",".
908 $ilDB->quote($rec[
"owner"],
"integer").
",".
909 $ilDB->quote(
"create",
"text").
",".
910 $ilDB->quote($rec[
"create_date"],
"timestamp").
915 if ($ilDB->isError(
$res) || $ilDB->isError(
$res->result))
917 return 'couldn\'t insert initial data into table "write_event": '.
918 (($ilDB->isError($r->result)) ? $r->result->getMessage() : $r->getMessage());
923 $ilias->setSetting(
'enable_change_event_tracking',
'1');
936 $ilias->setSetting(
'enable_change_event_tracking',
'0');
947 return $ilias->getSetting(
'enable_change_event_tracking',
'0') ==
'1';
961 $query = sprintf(
'DELETE FROM write_event WHERE obj_id = %s ',
962 $ilDB->quote($a_obj_id,
'integer'));
963 $aff = $ilDB->manipulate(
$query);
965 $query = sprintf(
'DELETE FROM read_event WHERE obj_id = %s ',
966 $ilDB->quote($a_obj_id,
'integer'));
967 $aff = $ilDB->manipulate(
$query);
975 $ilDB->manipulate(
"DELETE FROM read_event".
976 " WHERE obj_id = ".$ilDB->quote($a_obj_id,
"integer"));
983 $ilDB->manipulate(
"DELETE FROM read_event".
984 " WHERE obj_id = ".$ilDB->quote($a_obj_id,
"integer").
985 " AND ".$ilDB->in(
"usr_id", $a_user_ids,
"",
"integer"));
994 $set = $ilDB->query(
"SELECT usr_id FROM read_event".
995 " WHERE obj_id = ".$ilDB->quote($a_obj_id,
"integer"));
996 while(
$row = $ilDB->fetchAssoc($set))
1012 $res = $ilDB->queryF(
'UPDATE read_event SET first_access=%s, last_access = %s WHERE obj_id=%s AND usr_id=%s',
1013 array(
'timestamp',
'integer',
'integer',
'integer'),
1014 array($t_first_access,$i_last_access,$obj_id,$usr_id)