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);
113 $isCatchupWriteEvents =
true, $a_ext_rc =
false, $a_ext_time =
false)
124 include_once(
'Services/Tracking/classes/class.ilObjUserTracking.php');
127 $query = sprintf(
'SELECT * FROM read_event '.
128 'WHERE obj_id = %s '.
130 $ilDB->quote($obj_id,
'integer'),
131 $ilDB->quote($usr_id,
'integer'));
133 $row = $ilDB->fetchObject($res);
136 if ($a_ext_rc !==
false)
138 $read_count =
'read_count = '.$ilDB->quote($a_ext_rc,
"integer").
", ";
139 $read_count_init = max(1, (
int) $a_ext_rc);
140 $read_count_diff = max(1, (
int) $a_ext_rc) -
$row->read_count;
144 $read_count =
'read_count = read_count + 1, ';
145 $read_count_init = 1;
146 $read_count_diff = 1;
152 if ($a_ext_time !==
false)
154 $time = (int) $a_ext_time;
158 $time = $ilDB->quote((
time() -
$row->last_access) <= $validTimeSpan
160 :
$row->spent_seconds,
'integer');
165 if ((
time() -
$row->last_access) <= $validTimeSpan)
168 $read_count_init = 1;
169 $read_count_diff = 0;
175 $query = sprintf(
'UPDATE read_event SET '.
177 'spent_seconds = %s, '.
179 'WHERE obj_id = %s '.
182 $ilDB->quote(
time(),
'integer'),
183 $ilDB->quote($obj_id,
'integer'),
184 $ilDB->quote($usr_id,
'integer'));
185 $aff = $ilDB->manipulate(
$query);
187 self::_recordObjStats($obj_id,
$time_diff, $read_count_diff);
191 if ($a_ext_time !==
false)
193 $time = (int) $a_ext_time;
214 $ilDB->replace(
'read_event',
216 'obj_id' =>
array(
'integer', $obj_id),
217 'usr_id' =>
array(
'integer', $usr_id)
220 'read_count' =>
array(
'integer', $read_count_init),
221 'spent_seconds' =>
array(
'integer', $time),
222 'first_access' =>
array(
'timestamp',
date(
"Y-m-d H:i:s")),
223 'last_access' =>
array(
'integer',
time())
227 self::$has_accessed[$obj_id][$usr_id] =
true;
229 self::_recordObjStats($obj_id,
$time_diff, $read_count_diff);
232 if ($isCatchupWriteEvents)
240 if ($tree->isInTree($a_ref_id))
242 $path = $tree->getPathId($a_ref_id);
244 foreach (
$path as $p)
249 if (($p != $a_ref_id) && (in_array($obj2_type,
array(
"crs",
"fold",
"grp"))))
251 $query = sprintf(
'SELECT * FROM read_event '.
252 'WHERE obj_id = %s '.
254 $ilDB->quote($obj2_id,
'integer'),
255 $ilDB->quote($usr_id,
'integer'));
256 $res2 = $ilDB->query(
$query);
257 if ($row2 = $ilDB->fetchAssoc($res2))
261 $query = sprintf(
'UPDATE read_event SET '.
262 'childs_read_count = childs_read_count + %s ,'.
263 'childs_spent_seconds = childs_spent_seconds + %s '.
264 'WHERE obj_id = %s '.
266 $ilDB->quote((
int) $read_count_diff,
'integer'),
268 $ilDB->quote($obj2_id,
'integer'),
269 $ilDB->quote($usr_id,
'integer'));
270 $aff = $ilDB->manipulate(
$query);
272 self::_recordObjStats($obj2_id, null, null, (
int)$time_diff, (
int)$read_count_diff);
294 $ilDB->replace(
'read_event',
296 'obj_id' =>
array(
'integer', $obj2_id),
297 'usr_id' =>
array(
'integer', $usr_id)
300 'read_count' =>
array(
'integer', 1),
301 'spent_seconds' =>
array(
'integer', $time),
302 'first_access' =>
array(
'timestamp',
date(
"Y-m-d H:i:s")),
303 'last_access' =>
array(
'integer',
time()),
304 'childs_read_count' =>
array(
'integer', (
int)$read_count_diff),
309 self::$has_accessed[$obj2_id][$usr_id] =
true;
311 self::_recordObjStats($obj2_id, $time, 1, (
int)$time_diff, (
int)$read_count_diff);
324 static function _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds = null, $a_child_read_count = null)
337 $fields[
'log_id'] =
array(
"integer", $ilDB->nextId(
'obj_stat_log'));
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)
366 self::_syncObjectStats($now);
388 $set = $ilDB->query(
"SELECT COUNT(*) AS counter FROM obj_stat_log");
389 $row = $ilDB->fetchAssoc($set);
390 if(
$row[
"counter"] >= $a_minimum)
392 $ilAtomQuery = $ilDB->buildAtomQuery();
393 $ilAtomQuery->addTableLock(
'obj_stat_log');
394 $ilAtomQuery->addTableLock(
'obj_stat_tmp');
396 $ilAtomQuery->addQueryCallable(
function(
ilDBInterface $ilDB) use($a_now, $a_minimum, &
$ret){
400 $set = $ilDB->
query(
"SELECT COUNT(*) AS counter FROM obj_stat_log");
402 if(
$row[
"counter"] >= $a_minimum)
405 $ilDB->
query(
"INSERT INTO obj_stat_tmp".
406 " SELECT * FROM obj_stat_log".
407 " WHERE tstamp < ".$ilDB->
quote($a_now,
"timestamp"));
410 $ilDB->
query(
"DELETE FROM obj_stat_log".
411 " WHERE tstamp < ".$ilDB->
quote($a_now,
"timestamp"));
427 $ilAtomQuery->addTableLock(
'obj_stat_tmp');
428 $ilAtomQuery->addTableLock(
'obj_stat');
430 $ilAtomQuery->addQueryCallable(
function(
ilDBInterface $ilDB) use($a_now, $a_minimum){
433 $sql =
"SELECT obj_id, obj_type, yyyy, mm, dd, hh, SUM(read_count) AS read_count,".
434 " SUM(childs_read_count) AS childs_read_count, SUM(spent_seconds) AS spent_seconds,".
435 " SUM(childs_spent_seconds) AS childs_spent_seconds".
436 " FROM obj_stat_tmp".
437 " GROUP BY obj_id, obj_type, yyyy, mm, dd, hh";
438 $set = $ilDB->
query($sql);
443 "obj_type" =>
array(
"text",
$row[
"obj_type"]),
444 "yyyy" =>
array(
"integer",
$row[
"yyyy"]),
449 $where_sql =
array();
450 foreach($where as $field => $def)
452 $where_sql[] = $field.
" = ".$ilDB->
quote($def[1], $def[0]);
454 $where_sql = implode(
" AND ", $where_sql);
457 $check = $ilDB->
query(
"SELECT read_count, childs_read_count, spent_seconds,".
458 "childs_spent_seconds".
460 " WHERE ".$where_sql);
466 $fields =
array(
"read_count" =>
array(
"integer",
$old[
"read_count"]+
$row[
"read_count"]),
467 "childs_read_count" =>
array(
"integer",
$old[
"childs_read_count"]+
$row[
"childs_read_count"]),
468 "spent_seconds" =>
array(
"integer",
$old[
"spent_seconds"]+
$row[
"spent_seconds"]),
469 "childs_spent_seconds" =>
array(
"integer",
$old[
"childs_spent_seconds"]+
$row[
"childs_spent_seconds"]));
471 $ilDB->
update(
"obj_stat", $fields, $where);
477 $fields[
"read_count"] =
array(
"integer",
$row[
"read_count"]);
478 $fields[
"childs_read_count"] =
array(
"integer",
$row[
"childs_read_count"]);
479 $fields[
"spent_seconds"] =
array(
"integer",
$row[
"spent_seconds"]);
480 $fields[
"childs_spent_seconds"] =
array(
"integer",
$row[
"childs_spent_seconds"]);
482 $ilDB->
insert(
"obj_stat", $fields);
487 $ilDB->
query(
"DELETE FROM obj_stat_tmp");
508 $query =
"SELECT obj_id FROM catch_write_events ".
509 "WHERE obj_id = ".$ilDB->quote($obj_id ,
'integer').
" ".
510 "AND usr_id = ".$ilDB->quote($usr_id ,
'integer');
536 $ilDB->replace(
"catch_write_events",
538 "obj_id" =>
array(
"integer", $obj_id),
539 "usr_id" =>
array(
"integer", $usr_id)
542 "ts" =>
array(
"timestamp", $ts))
598 "FROM catch_write_events ".
599 "WHERE obj_id=".$ilDB->quote($obj_id ,
'integer').
" ".
600 "AND usr_id=".$ilDB->quote($usr_id ,
'integer');
601 $r = $ilDB->query($q);
604 $catchup =
$row[
'ts'];
609 $query = sprintf(
'SELECT * FROM write_event '.
610 'WHERE obj_id = %s '.
613 $ilDB->quote($obj_id,
'integer'),
614 $ilDB->quote($usr_id,
'integer'));
619 $query = sprintf(
'SELECT * FROM write_event '.
620 'WHERE obj_id = %s '.
624 $ilDB->quote($obj_id,
'integer'),
625 $ilDB->quote($usr_id,
'integer'),
626 $ilDB->quote($catchup,
'timestamp'));
630 while(
$row = $ilDB->fetchAssoc(
$res))
651 "FROM catch_write_events ".
652 "WHERE obj_id=".$ilDB->quote($obj_id ,
'integer').
" ".
653 "AND usr_id=".$ilDB->quote($usr_id ,
'integer');
654 $r = $ilDB->query($q);
657 $catchup =
$row[
'ts'];
663 $query = sprintf(
'SELECT * FROM write_event '.
664 'WHERE obj_id = %s '.
666 $ilDB->quote($obj_id,
'integer'),
667 $ilDB->quote($usr_id,
'integer'));
673 $query = sprintf(
'SELECT * FROM write_event '.
674 'WHERE obj_id = %s '.
677 $ilDB->quote($obj_id,
'integer'),
678 $ilDB->quote($usr_id,
'integer'),
679 $ilDB->quote($catchup,
'timestamp'));
683 $numRows =
$res->numRows();
689 return ($catchup == null) ? 1 : 2;
747 $query = sprintf(
'SELECT * FROM read_event '.
748 'WHERE obj_id = %s '.
749 'ORDER BY last_access DESC',
750 $ilDB->quote($obj_id,
'integer'));
755 $query = sprintf(
'SELECT * FROM read_event '.
756 'WHERE obj_id = %s '.
758 'ORDER BY last_access DESC',
759 $ilDB->quote($obj_id,
'integer'),
760 $ilDB->quote($usr_id,
'integer'));
765 while (
$row = $ilDB->fetchAssoc(
$res))
771 $events[
$counter][
'spent_seconds'] =
$row[
'spent_seconds'];
772 $events[
$counter][
'first_access'] =
$row[
'first_access'];
777 return $events ? $events :
array();
790 $query = sprintf(
'SELECT DISTINCT(usr_id) usr FROM read_event '.
791 'WHERE obj_id = %s ',
792 $ilDB->quote($a_obj_id,
'integer'));
794 while(
$row = $ilDB->fetchObject($res))
796 $users[] =
$row->usr;
798 return $users ? $users :
array();
808 if (isset(self::$has_accessed[$a_obj_id][$a_usr_id]))
810 return self::$has_accessed[$a_obj_id][$a_usr_id];
813 $set = $ilDB->query(
"SELECT usr_id FROM read_event WHERE ".
814 "obj_id = ".$ilDB->quote($a_obj_id,
"integer").
" AND ".
815 "usr_id = ".$ilDB->quote($a_usr_id,
"integer")
817 if ($rec = $ilDB->fetchAssoc($set))
819 return self::$has_accessed[$a_obj_id][$a_usr_id] =
true;
821 return self::$has_accessed[$a_obj_id][$a_usr_id] =
false;
832 return 'change event tracking is already active';
844 $set = $ilDB->query(sprintf(
'SELECT r1.obj_id,r2.obj_id p,d.owner,%s,d.create_date '.
845 'FROM object_data d '.
846 'LEFT JOIN write_event w ON d.obj_id = w.obj_id '.
847 'JOIN object_reference r1 ON d.obj_id=r1.obj_id '.
848 'JOIN tree t ON t.child=r1.ref_id '.
849 'JOIN object_reference r2 on r2.ref_id=t.parent '.
850 'WHERE w.obj_id IS NULL',
851 $ilDB->quote(
'create',
'text')));
852 while ($rec = $ilDB->fetchAssoc($set))
854 $nid = $ilDB->nextId(
"write_event");
855 $query =
'INSERT INTO write_event '.
856 '(write_id, obj_id,parent_obj_id,usr_id,action,ts) VALUES ('.
857 $ilDB->quote($nid,
"integer").
",".
858 $ilDB->quote($rec[
"obj_id"],
"integer").
",".
859 $ilDB->quote($rec[
"p"],
"integer").
",".
860 $ilDB->quote($rec[
"owner"],
"integer").
",".
861 $ilDB->quote(
"create",
"text").
",".
862 $ilDB->quote($rec[
"create_date"],
"timestamp").
868 $ilSetting->set(
'enable_change_event_tracking',
'1');
881 $ilSetting->set(
'enable_change_event_tracking',
'0');
891 return $ilSetting->get(
'enable_change_event_tracking',
'0') ==
'1';
904 $query = sprintf(
'DELETE FROM write_event WHERE obj_id = %s ',
905 $ilDB->quote($a_obj_id,
'integer'));
906 $aff = $ilDB->manipulate(
$query);
908 $query = sprintf(
'DELETE FROM read_event WHERE obj_id = %s ',
909 $ilDB->quote($a_obj_id,
'integer'));
910 $aff = $ilDB->manipulate(
$query);
918 $ilDB->manipulate(
"DELETE FROM read_event".
919 " WHERE obj_id = ".$ilDB->quote($a_obj_id,
"integer"));
926 $ilDB->manipulate(
"DELETE FROM read_event".
927 " WHERE obj_id = ".$ilDB->quote($a_obj_id,
"integer").
928 " AND ".$ilDB->in(
"usr_id", $a_user_ids,
"",
"integer"));
937 $set = $ilDB->query(
"SELECT usr_id FROM read_event".
938 " WHERE obj_id = ".$ilDB->quote($a_obj_id,
"integer"));
939 while(
$row = $ilDB->fetchAssoc($set))
955 $res = $ilDB->queryF(
'UPDATE read_event SET first_access=%s, last_access = %s WHERE obj_id=%s AND usr_id=%s',
956 array(
'timestamp',
'integer',
'integer',
'integer'),
957 array($t_first_access,$i_last_access,$obj_id,$usr_id)
static hasAccessed($a_obj_id, $a_usr_id)
Has accessed.
static _activate()
Activates change event tracking.
static _enabledObjectStatistics()
check wether object statistics is enabled or not
static _recordWriteEvent($obj_id, $usr_id, $action, $parent_obj_id=null)
Records a write event.
static _deleteReadEvents($a_obj_id)
static _getAllUserIds($a_obj_id)
static now()
Return current timestamp in Y-m-d H:i:s format.
update($table_name, $values, $where)
static _catchupWriteEvents($obj_id, $usr_id, $timestamp=null)
Catches up with all write events which occured before the specified timestamp.
static _delete($a_obj_id)
Delete object entries.
static _updateAccessForScormOfflinePlayer($obj_id, $usr_id, $i_last_access, $t_first_access)
_updateAccessForScormOfflinePlayer needed to synchronize last_access and first_access when learning m...
static _lookupObjId($a_id)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
static _recordReadEvent($a_type, $a_ref_id, $obj_id, $usr_id, $isCatchupWriteEvents=true, $a_ext_rc=false, $a_ext_time=false)
Records a read event and catches up with write events.
static _lookupReadEvents($obj_id, $usr_id=null)
Reads all read events which occured on the object which happened after the last time the user caught ...
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
foreach($mandatory_scripts as $file) $timestamp
static _lookupUncaughtWriteEvents($obj_id, $usr_id)
Catches up with all write events which occured before the specified timestamp.
Class ilChangeEvent tracks change events on repository objects.
static _deleteReadEventsForUsers($a_obj_id, array $a_user_ids)
static _isActive()
Returns true, if change event tracking is active.
static _deactivate()
Deactivates change event tracking.
static _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds=null, $a_child_read_count=null)
insert($table_name, $values)
fetchAssoc($query_result)
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
static _syncObjectStats($a_now=null, $a_minimum=20000)
Process object statistics log data.
static _getValidTimeSpan()
static _lookupChangeState($obj_id, $usr_id)
Returns the change state of the object for the specified user.
static lookupUsersInProgress($a_obj_id)
Lookup users in progress.