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;
203 $query = sprintf(
'INSERT INTO read_event (obj_id,usr_id,last_access,read_count,spent_seconds,first_access) '.
204 'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().
') ',
205 $ilDB->quote($obj_id,
'integer'),
206 $ilDB->quote(
$usr_id,
'integer'),
207 $ilDB->quote(time(),
'integer'),
208 $ilDB->quote($read_count_init,
'integer'),
209 $ilDB->quote($time,
'integer'));
211 $aff = $ilDB->manipulate(
$query);
213 self::$has_accessed[$obj_id][
$usr_id] =
true;
218 if ($isCatchupWriteEvents)
224 if (!in_array($a_type, array(
"cat",
"root",
"crs")))
226 if ($tree->isInTree($a_ref_id))
228 $path = $tree->getPathId($a_ref_id);
230 foreach (
$path as $p)
235 if (($p != $a_ref_id) && (in_array($obj2_type, array(
"crs",
"fold",
"grp"))))
237 $query = sprintf(
'SELECT * FROM read_event '.
238 'WHERE obj_id = %s '.
240 $ilDB->quote($obj2_id,
'integer'),
241 $ilDB->quote(
$usr_id,
'integer'));
242 $res2 = $ilDB->query(
$query);
243 if ($row2 = $ilDB->fetchAssoc($res2))
247 $query = sprintf(
'UPDATE read_event SET '.
248 'childs_read_count = childs_read_count + %s ,'.
249 'childs_spent_seconds = childs_spent_seconds + %s '.
250 'WHERE obj_id = %s '.
252 $ilDB->quote((
int) $read_count_diff,
'integer'),
253 $ilDB->quote((
int) $time_diff,
'integer'),
254 $ilDB->quote($obj2_id,
'integer'),
255 $ilDB->quote(
$usr_id,
'integer'));
256 $aff = $ilDB->manipulate(
$query);
264 $query = sprintf(
'INSERT INTO read_event (obj_id,usr_id,last_access,read_count,spent_seconds,first_access,'.
265 'childs_read_count, childs_spent_seconds) '.
266 'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().
', %s, %s) ',
267 $ilDB->quote($obj2_id,
'integer'),
268 $ilDB->quote(
$usr_id,
'integer'),
269 $ilDB->quote(time(),
'integer'),
270 $ilDB->quote(1,
'integer'),
271 $ilDB->quote($time,
'integer'),
272 $ilDB->quote((
int) $read_count_diff,
'integer'),
273 $ilDB->quote((
int) $time_diff,
'integer')
275 $aff = $ilDB->manipulate(
$query);
277 self::$has_accessed[$obj2_id][
$usr_id] =
true;
292 function _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds = null, $a_child_read_count = null)
305 $fields[
"obj_id"] = array(
"integer", $a_obj_id);
307 $fields[
"tstamp"] = array(
"timestamp", $now);
308 $fields[
"yyyy"] = array(
"integer", date(
"Y"));
309 $fields[
"mm"] = array(
"integer", date(
"m"));
310 $fields[
"dd"] = array(
"integer", date(
"d"));
311 $fields[
"hh"] = array(
"integer", date(
"H"));
312 if($a_spent_seconds > 0)
314 $fields[
"spent_seconds"] = array(
"integer", $a_spent_seconds);
316 if($a_read_count > 0)
318 $fields[
"read_count"] = array(
"integer", $a_read_count);
320 if($a_childs_spent_seconds > 0)
322 $fields[
"childs_spent_seconds"] = array(
"integer", $a_childs_spent_seconds);
324 if($a_child_read_count > 0)
326 $fields[
"childs_read_count"] = array(
"integer", $a_child_read_count);
328 $ilDB->insert(
"obj_stat_log", $fields);
331 if(mt_rand(1, 100) == 1)
355 $set = $ilDB->query(
"SELECT COUNT(*) AS counter FROM obj_stat_log");
356 $row = $ilDB->fetchAssoc($set);
357 if(
$row[
"counter"] >= $a_minimum)
360 $ilDB->lockTables(array(array(
"name"=>
"obj_stat_log",
"type"=>
ilDB::LOCK_WRITE),
365 $set = $ilDB->query(
"SELECT COUNT(*) AS counter FROM obj_stat_log");
366 $row = $ilDB->fetchAssoc($set);
367 if(
$row[
"counter"] >= $a_minimum)
370 $ilDB->query(
"INSERT INTO obj_stat_tmp".
371 " SELECT * FROM obj_stat_log".
372 " WHERE tstamp < ".$ilDB->quote($a_now,
"timestamp"));
375 $ilDB->query(
"DELETE FROM obj_stat_log".
376 " WHERE tstamp < ".$ilDB->quote($a_now,
"timestamp"));
379 $ilDB->unlockTables();
382 $ilDB->lockTables(array(array(
"name"=>
"obj_stat_tmp",
"type"=>
ilDB::LOCK_WRITE),
386 $sql =
"SELECT obj_id, obj_type, yyyy, mm, dd, hh, SUM(read_count) AS read_count,".
387 " SUM(childs_read_count) AS childs_read_count, SUM(spent_seconds) AS spent_seconds,".
388 " SUM(childs_spent_seconds) AS childs_spent_seconds".
389 " FROM obj_stat_tmp".
390 " GROUP BY obj_id, obj_type, yyyy, mm, dd, hh";
391 $set = $ilDB->query($sql);
392 while(
$row = $ilDB->fetchAssoc($set))
395 $where = array(
"obj_id" => array(
"integer",
$row[
"obj_id"]),
396 "obj_type" => array(
"text",
$row[
"obj_type"]),
397 "yyyy" => array(
"integer",
$row[
"yyyy"]),
398 "mm" => array(
"integer",
$row[
"mm"]),
399 "dd" => array(
"integer",
$row[
"dd"]),
400 "hh" => array(
"integer",
$row[
"hh"]));
402 $where_sql = array();
403 foreach($where as $field => $def)
405 $where_sql[] = $field.
" = ".$ilDB->quote($def[1], $def[0]);
407 $where_sql = implode(
" AND ", $where_sql);
410 $check = $ilDB->query(
"SELECT read_count, childs_read_count, spent_seconds,".
411 "childs_spent_seconds".
413 " WHERE ".$where_sql);
414 if($ilDB->numRows($check))
416 $old = $ilDB->fetchAssoc($check);
419 $fields = array(
"read_count" => array(
"integer", $old[
"read_count"]+
$row[
"read_count"]),
420 "childs_read_count" => array(
"integer", $old[
"childs_read_count"]+
$row[
"childs_read_count"]),
421 "spent_seconds" => array(
"integer", $old[
"spent_seconds"]+
$row[
"spent_seconds"]),
422 "childs_spent_seconds" => array(
"integer", $old[
"childs_spent_seconds"]+
$row[
"childs_spent_seconds"]));
424 $ilDB->update(
"obj_stat", $fields, $where);
430 $fields[
"read_count"] = array(
"integer",
$row[
"read_count"]);
431 $fields[
"childs_read_count"] = array(
"integer",
$row[
"childs_read_count"]);
432 $fields[
"spent_seconds"] = array(
"integer",
$row[
"spent_seconds"]);
433 $fields[
"childs_spent_seconds"] = array(
"integer",
$row[
"childs_spent_seconds"]);
435 $ilDB->insert(
"obj_stat", $fields);
440 $ilDB->query(
"DELETE FROM obj_stat_tmp");
444 $ilDB->unlockTables();
460 $query =
"SELECT obj_id FROM catch_write_events ".
461 "WHERE obj_id = ".$ilDB->quote($obj_id ,
'integer').
" ".
462 "AND usr_id = ".$ilDB->quote(
$usr_id ,
'integer');
466 $query =
"UPDATE catch_write_events ".
467 "SET ts = ".($timestamp == null ? $ilDB->now() : $ilDB->quote(
$timestamp,
'timestamp')).
" ".
468 "WHERE usr_id = ".$ilDB->quote(
$usr_id ,
'integer').
" ".
469 "AND obj_id = ".$ilDB->quote($obj_id ,
'integer');
474 $query =
"INSERT INTO catch_write_events (ts,obj_id,usr_id) ".
477 $ilDB->quote($obj_id,
'integer').
", ".
478 $ilDB->quote(
$usr_id,
'integer').
" ".
555 "FROM catch_write_events ".
556 "WHERE obj_id=".$ilDB->quote($obj_id ,
'integer').
" ".
557 "AND usr_id=".$ilDB->quote(
$usr_id ,
'integer');
558 $r = $ilDB->query($q);
561 $catchup =
$row[
'ts'];
566 $query = sprintf(
'SELECT * FROM write_event '.
567 'WHERE obj_id = %s '.
570 $ilDB->quote($obj_id,
'integer'),
571 $ilDB->quote(
$usr_id,
'integer'));
576 $query = sprintf(
'SELECT * FROM write_event '.
577 'WHERE obj_id = %s '.
581 $ilDB->quote($obj_id,
'integer'),
582 $ilDB->quote(
$usr_id,
'integer'),
583 $ilDB->quote($catchup,
'timestamp'));
587 while(
$row = $ilDB->fetchAssoc(
$res))
608 "FROM catch_write_events ".
609 "WHERE obj_id=".$ilDB->quote($obj_id ,
'integer').
" ".
610 "AND usr_id=".$ilDB->quote(
$usr_id ,
'integer');
611 $r = $ilDB->query($q);
614 $catchup =
$row[
'ts'];
620 $query = sprintf(
'SELECT * FROM write_event '.
621 'WHERE obj_id = %s '.
623 $ilDB->quote($obj_id,
'integer'),
624 $ilDB->quote(
$usr_id,
'integer'));
630 $query = sprintf(
'SELECT * FROM write_event '.
631 'WHERE obj_id = %s '.
634 $ilDB->quote($obj_id,
'integer'),
635 $ilDB->quote(
$usr_id,
'integer'),
636 $ilDB->quote($catchup,
'timestamp'));
640 $numRows =
$res->numRows();
646 return ($catchup == null) ? 1 : 2;
673 "FROM catch_write_events ".
674 "WHERE obj_id=".$ilDB->quote($parent_obj_id).
" ".
675 "AND usr_id=".$ilDB->quote(
$usr_id);
676 $r = $ilDB->query($q);
679 $catchup =
$row[
'ts'];
685 $query = sprintf(
'SELECT * FROM write_event '.
686 'WHERE parent_obj_id = %s '.
688 $ilDB->quote($parent_obj_id,
'integer'),
689 $ilDB->quote(
$usr_id,
'integer'));
695 $query = sprintf(
'SELECT * FROM write_event '.
696 'WHERE parent_obj_id = %s '.
699 $ilDB->quote($parent_obj_id,
'integer'),
700 $ilDB->quote(
$usr_id,
'integer'),
701 $ilDB->quote($catchup,
'timestamp'));
704 $numRows =
$res->numRows();
710 return ($catchup == null) ? 1 : 2;
767 $query = sprintf(
'SELECT * FROM read_event '.
768 'WHERE obj_id = %s '.
769 'ORDER BY last_access DESC',
770 $ilDB->quote($obj_id,
'integer'));
775 $query = sprintf(
'SELECT * FROM read_event '.
776 'WHERE obj_id = %s '.
778 'ORDER BY last_access DESC',
779 $ilDB->quote($obj_id,
'integer'),
780 $ilDB->quote(
$usr_id,
'integer'));
785 while (
$row = $ilDB->fetchAssoc(
$res))
787 $events[$counter][
'obj_id'] =
$row[
'obj_id'];
788 $events[$counter][
'usr_id'] =
$row[
'usr_id'];
789 $events[$counter][
'last_access'] =
$row[
'last_access'];
790 $events[$counter][
'read_count'] =
$row[
'read_count'];
791 $events[$counter][
'spent_seconds'] =
$row[
'spent_seconds'];
792 $events[$counter][
'first_access'] =
$row[
'first_access'];
797 return $events ? $events : array();
810 $query = sprintf(
'SELECT DISTINCT(usr_id) usr FROM read_event '.
811 'WHERE obj_id = %s ',
812 $ilDB->quote($a_obj_id,
'integer'));
814 while(
$row = $ilDB->fetchObject($res))
816 $users[] =
$row->usr;
818 return $users ? $users : array();
828 if (isset(self::$has_accessed[$a_obj_id][$a_usr_id]))
830 return self::$has_accessed[$a_obj_id][$a_usr_id];
833 $set = $ilDB->query(
"SELECT usr_id FROM read_event WHERE ".
834 "obj_id = ".$ilDB->quote($a_obj_id,
"integer").
" AND ".
835 "usr_id = ".$ilDB->quote($a_usr_id,
"integer")
837 if ($rec = $ilDB->fetchAssoc($set))
839 return self::$has_accessed[$a_obj_id][$a_usr_id] =
true;
841 return self::$has_accessed[$a_obj_id][$a_usr_id] =
false;
852 return 'change event tracking is already active';
864 $set = $ilDB->query(sprintf(
'SELECT r1.obj_id,r2.obj_id p,d.owner,%s,d.create_date '.
865 'FROM object_data d '.
866 'LEFT JOIN write_event w ON d.obj_id = w.obj_id '.
867 'JOIN object_reference r1 ON d.obj_id=r1.obj_id '.
868 'JOIN tree t ON t.child=r1.ref_id '.
869 'JOIN object_reference r2 on r2.ref_id=t.parent '.
870 'WHERE w.obj_id IS NULL',
871 $ilDB->quote(
'create',
'text')));
872 while ($rec = $ilDB->fetchAssoc($set))
874 $nid = $ilDB->nextId(
"write_event");
875 $query =
'INSERT INTO write_event '.
876 '(write_id, obj_id,parent_obj_id,usr_id,action,ts) VALUES ('.
877 $ilDB->quote($nid,
"integer").
",".
878 $ilDB->quote($rec[
"obj_id"],
"integer").
",".
879 $ilDB->quote($rec[
"p"],
"integer").
",".
880 $ilDB->quote($rec[
"owner"],
"integer").
",".
881 $ilDB->quote(
"create",
"text").
",".
882 $ilDB->quote($rec[
"create_date"],
"timestamp").
887 if ($ilDB->isError(
$res) || $ilDB->isError(
$res->result))
889 return 'couldn\'t insert initial data into table "write_event": '.
890 (($ilDB->isError($r->result)) ? $r->result->getMessage() : $r->getMessage());
895 $ilias->setSetting(
'enable_change_event_tracking',
'1');
908 $ilias->setSetting(
'enable_change_event_tracking',
'0');
919 return $ilias->getSetting(
'enable_change_event_tracking',
'0') ==
'1';
933 $query = sprintf(
'DELETE FROM write_event WHERE obj_id = %s ',
934 $ilDB->quote($a_obj_id,
'integer'));
935 $aff = $ilDB->manipulate(
$query);
937 $query = sprintf(
'DELETE FROM read_event WHERE obj_id = %s ',
938 $ilDB->quote($a_obj_id,
'integer'));
939 $aff = $ilDB->manipulate(
$query);