68        if ($parent_obj_id == 
null) {
 
   69            $pset = 
$ilDB->query(
'SELECT r2.obj_id par_obj_id FROM object_reference r1 ' .
 
   70                'JOIN tree t ON t.child = r1.ref_id ' .
 
   71                'JOIN object_reference r2 ON r2.ref_id = t.parent ' .
 
   72                'WHERE r1.obj_id = ' . 
$ilDB->quote($obj_id, 
'integer'));
 
   74            while ($prec = 
$ilDB->fetchAssoc($pset)) {
 
   75                $nid = 
$ilDB->nextId(
"write_event");
 
   77                    'INSERT INTO write_event ' .
 
   78                    '(write_id, obj_id, parent_obj_id, usr_id, action, ts) VALUES ' .
 
   79                    '(%s, %s, %s, %s, %s, ' . 
$ilDB->now() . 
')',
 
   80                    $ilDB->quote($nid, 
'integer'),
 
   81                    $ilDB->quote($obj_id, 
'integer'),
 
   82                    $ilDB->quote($prec[
"par_obj_id"], 
'integer'),
 
   83                    $ilDB->quote($usr_id, 
'integer'),
 
   84                    $ilDB->quote($action, 
'text')
 
   90            $nid = 
$ilDB->nextId(
"write_event");
 
   92                'INSERT INTO write_event ' .
 
   93                '(write_id, obj_id, parent_obj_id, usr_id, action, ts) ' .
 
   94                'VALUES (%s,%s,%s,%s,%s,' . 
$ilDB->now() . 
')',
 
   95                $ilDB->quote($nid, 
'integer'),
 
   96                $ilDB->quote($obj_id, 
'integer'),
 
   97                $ilDB->quote($parent_obj_id, 
'integer'),
 
   98                $ilDB->quote($usr_id, 
'integer'),
 
   99                $ilDB->quote($action, 
'text')
 
  118        $isCatchupWriteEvents = 
true,
 
  125        $tree = 
$DIC[
'tree'];
 
  134        include_once(
'Services/Tracking/classes/class.ilObjUserTracking.php');
 
  138            'SELECT * FROM read_event ' .
 
  139            'WHERE obj_id = %s ' .
 
  141            $ilDB->quote($obj_id, 
'integer'),
 
  142            $ilDB->quote($usr_id, 
'integer')
 
  148        if ($a_ext_rc !== 
false) {
 
  149            $read_count = 
'read_count = ' . 
$ilDB->quote($a_ext_rc, 
"integer") . 
", ";
 
  150            $read_count_init = max(1, (
int) $a_ext_rc);
 
  151            $read_count_diff = max(1, (
int) $a_ext_rc) - $row->read_count;
 
  153            $read_count = 
'read_count = read_count + 1, ';
 
  154            $read_count_init = 1;
 
  155            $read_count_diff = 1;
 
  159            if ($a_ext_time !== 
false) {
 
  160                $time = (int) $a_ext_time;
 
  162                $time = 
$ilDB->quote((time() - $row->last_access) <= $validTimeSpan
 
  163                             ? $row->spent_seconds + time() - $row->last_access
 
  164                             : $row->spent_seconds, 
'integer');
 
  169                if ((time() - $row->last_access) <= $validTimeSpan) {
 
  171                    $read_count_init = 1;
 
  172                    $read_count_diff = 0;
 
  175            $time_diff = $time - (int) $row->spent_seconds;
 
  179                'UPDATE read_event SET ' .
 
  181                'spent_seconds = %s, ' .
 
  182                'last_access = %s ' .
 
  183                'WHERE obj_id = %s ' .
 
  186                $ilDB->quote(time(), 
'integer'),
 
  187                $ilDB->quote($obj_id, 
'integer'),
 
  188                $ilDB->quote($usr_id, 
'integer')
 
  194            if ($a_ext_time !== 
false) {
 
  195                $time = (int) $a_ext_time;
 
  200            $time_diff = $time - (int) $row->spent_seconds;
 
  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) {
 
  238        if (!in_array($a_type, array(
"cat", 
"root", 
"crs"))) {
 
  239            if ($tree->isInTree($a_ref_id)) {
 
  240                $path = $tree->getPathId($a_ref_id);
 
  242                foreach ($path as $p) {
 
  246                    if (($p != $a_ref_id) && (in_array($obj2_type, array(
"crs", 
"fold", 
"grp", 
"lso")))) {
 
  248                            'SELECT * FROM read_event ' .
 
  249                            'WHERE obj_id = %s ' .
 
  251                            $ilDB->quote($obj2_id, 
'integer'),
 
  252                            $ilDB->quote($usr_id, 
'integer')
 
  255                        if ($row2 = 
$ilDB->fetchAssoc($res2)) {
 
  259                                'UPDATE read_event SET ' .
 
  260                                'childs_read_count = childs_read_count + %s ,' .
 
  261                                'childs_spent_seconds = childs_spent_seconds + %s ' .
 
  262                                'WHERE obj_id = %s ' .
 
  264                                $ilDB->quote((
int) $read_count_diff, 
'integer'),
 
  265                                $ilDB->quote((
int) $time_diff, 
'integer'),
 
  266                                $ilDB->quote($obj2_id, 
'integer'),
 
  267                                $ilDB->quote($usr_id, 
'integer')
 
  294                                    'obj_id' => array(
'integer', $obj2_id),
 
  295                                    'usr_id' => array(
'integer', $usr_id)
 
  298                                    'read_count' => array(
'integer', 1),
 
  299                                    'spent_seconds' => array(
'integer', $time),
 
  300                                    'first_access' => array(
'timestamp', date(
"Y-m-d H:i:s")), 
 
  301                                    'last_access' => array(
'integer', time()),
 
  302                                    'childs_read_count' => array(
'integer', (
int) $read_count_diff),
 
  303                                    'childs_spent_seconds' => array(
'integer', (
int) $time_diff)
 
  307                            self::$has_accessed[$obj2_id][$usr_id] = 
true;
 
  322    public static function _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds = 
null, $a_child_read_count = 
null)
 
  329            (
int) $a_obj_id <= 0) { 
 
  336        $fields[
'log_id'] = array(
"integer", 
$ilDB->nextId(
'obj_stat_log'));
 
  337        $fields[
"obj_id"] = array(
"integer", $a_obj_id);
 
  339        $fields[
"tstamp"] = array(
"timestamp", $now);
 
  340        $fields[
"yyyy"] = array(
"integer", date(
"Y"));
 
  341        $fields[
"mm"] = array(
"integer", date(
"m"));
 
  342        $fields[
"dd"] = array(
"integer", date(
"d"));
 
  343        $fields[
"hh"] = array(
"integer", date(
"H"));
 
  344        if ($a_spent_seconds > 0) {
 
  345            $fields[
"spent_seconds"] = array(
"integer", $a_spent_seconds);
 
  347        if ($a_read_count > 0) {
 
  348            $fields[
"read_count"] = array(
"integer", $a_read_count);
 
  350        if ($a_childs_spent_seconds > 0) {
 
  351            $fields[
"childs_spent_seconds"] = array(
"integer", $a_childs_spent_seconds);
 
  353        if ($a_child_read_count > 0) {
 
  354            $fields[
"childs_read_count"] = array(
"integer", $a_child_read_count);
 
  356        $ilDB->insert(
"obj_stat_log", $fields);
 
  359        if (mt_rand(1, 100) == 1) {
 
  383        $set = 
$ilDB->query(
"SELECT COUNT(*) AS counter FROM obj_stat_log");
 
  384        $row = 
$ilDB->fetchAssoc($set);
 
  385        if ($row[
"counter"] >= $a_minimum) {
 
  386            $ilAtomQuery = 
$ilDB->buildAtomQuery();
 
  387            $ilAtomQuery->addTableLock(
'obj_stat_log');
 
  388            $ilAtomQuery->addTableLock(
'obj_stat_tmp');
 
  394                $set = 
$ilDB->query(
"SELECT COUNT(*) AS counter FROM obj_stat_log");
 
  395                $row = 
$ilDB->fetchAssoc($set);
 
  396                if ($row[
"counter"] >= $a_minimum) {
 
  398                    $ilDB->query(
"INSERT INTO obj_stat_tmp" .
 
  399                        " SELECT * FROM obj_stat_log" .
 
  400                        " WHERE tstamp < " . 
$ilDB->quote($a_now, 
"timestamp"));
 
  403                    $ilDB->query(
"DELETE FROM obj_stat_log" .
 
  404                        " WHERE tstamp < " . 
$ilDB->quote($a_now, 
"timestamp"));
 
  416                $ilAtomQuery = 
$ilDB->buildAtomQuery();
 
  417                $ilAtomQuery->addTableLock(
'obj_stat_tmp');
 
  418                $ilAtomQuery->addTableLock(
'obj_stat');
 
  420                $ilAtomQuery->addQueryCallable(
function (
ilDBInterface $ilDB) use ($a_now, $a_minimum) {
 
  423                    $sql = 
"SELECT obj_id, obj_type, yyyy, mm, dd, hh, SUM(read_count) AS read_count," .
 
  424                        " SUM(childs_read_count) AS childs_read_count, SUM(spent_seconds) AS spent_seconds," .
 
  425                        " SUM(childs_spent_seconds) AS childs_spent_seconds" .
 
  426                        " FROM obj_stat_tmp" .
 
  427                        " GROUP BY obj_id, obj_type, yyyy, mm, dd, hh";
 
  428                    $set = 
$ilDB->query($sql);
 
  429                    while ($row = 
$ilDB->fetchAssoc($set)) {
 
  431                        $where = array(
"obj_id" => array(
"integer", $row[
"obj_id"]),
 
  432                            "obj_type" => array(
"text", $row[
"obj_type"]),
 
  433                            "yyyy" => array(
"integer", $row[
"yyyy"]),
 
  434                            "mm" => array(
"integer", $row[
"mm"]),
 
  435                            "dd" => array(
"integer", $row[
"dd"]),
 
  436                            "hh" => array(
"integer", $row[
"hh"]));
 
  438                        $where_sql = array();
 
  439                        foreach ($where as $field => $def) {
 
  440                            $where_sql[] = $field . 
" = " . $ilDB->quote($def[1], $def[0]);
 
  442                        $where_sql = implode(
" AND ", $where_sql);
 
  445                        $check = 
$ilDB->query(
"SELECT read_count, childs_read_count, spent_seconds," .
 
  446                            "childs_spent_seconds" .
 
  448                            " WHERE " . $where_sql);
 
  449                        if (
$ilDB->numRows($check)) {
 
  450                            $old = $ilDB->fetchAssoc($check);
 
  453                            $fields = array(
"read_count" => array(
"integer", $old[
"read_count"] + $row[
"read_count"]),
 
  454                                "childs_read_count" => array(
"integer", $old[
"childs_read_count"] + $row[
"childs_read_count"]),
 
  455                                "spent_seconds" => array(
"integer", $old[
"spent_seconds"] + $row[
"spent_seconds"]),
 
  456                                "childs_spent_seconds" => array(
"integer", $old[
"childs_spent_seconds"] + $row[
"childs_spent_seconds"]));
 
  458                            $ilDB->update(
"obj_stat", $fields, $where);
 
  462                            $fields[
"read_count"] = array(
"integer", $row[
"read_count"]);
 
  463                            $fields[
"childs_read_count"] = array(
"integer", $row[
"childs_read_count"]);
 
  464                            $fields[
"spent_seconds"] = array(
"integer", $row[
"spent_seconds"]);
 
  465                            $fields[
"childs_spent_seconds"] = array(
"integer", $row[
"childs_spent_seconds"]);
 
  467                            $ilDB->insert(
"obj_stat", $fields);
 
  472                    $ilDB->query(
"DELETE FROM obj_stat_tmp");
 
  494        $query = 
"SELECT obj_id FROM catch_write_events " .
 
  495            "WHERE obj_id = " . 
$ilDB->quote($obj_id, 
'integer') . 
" " .
 
  496            "AND usr_id  = " . 
$ilDB->quote($usr_id, 
'integer');
 
  498        if (
$res->numRows()) {
 
  520            "catch_write_events",
 
  522                "obj_id" => array(
"integer", $obj_id),
 
  523                "usr_id" => array(
"integer", $usr_id)
 
  526                "ts" => array(
"timestamp", $ts))
 
  586            "FROM catch_write_events " .
 
  587            "WHERE obj_id=" . 
$ilDB->quote($obj_id, 
'integer') . 
" " .
 
  588            "AND usr_id=" . 
$ilDB->quote($usr_id, 
'integer');
 
  589        $r = 
$ilDB->query($q);
 
  592            $catchup = $row[
'ts'];
 
  595        if ($catchup == 
null) {
 
  597                'SELECT * FROM write_event ' .
 
  598                'WHERE obj_id = %s ' .
 
  599                'AND usr_id <> %s ' .
 
  601                $ilDB->quote($obj_id, 
'integer'),
 
  602                $ilDB->quote($usr_id, 
'integer')
 
  607                'SELECT * FROM write_event ' .
 
  608                'WHERE obj_id = %s ' .
 
  609                'AND usr_id <> %s ' .
 
  612                $ilDB->quote($obj_id, 
'integer'),
 
  613                $ilDB->quote($usr_id, 
'integer'),
 
  614                $ilDB->quote($catchup, 
'timestamp')
 
  641            "FROM catch_write_events " .
 
  642            "WHERE obj_id=" . 
$ilDB->quote($obj_id, 
'integer') . 
" " .
 
  643            "AND usr_id=" . 
$ilDB->quote($usr_id, 
'integer');
 
  644        $r = 
$ilDB->query($q);
 
  647            $catchup = $row[
'ts'];
 
  650        if ($catchup == 
null) {
 
  653                'SELECT * FROM write_event ' .
 
  654                'WHERE obj_id = %s ' .
 
  656                $ilDB->quote($obj_id, 
'integer'),
 
  657                $ilDB->quote($usr_id, 
'integer')
 
  663                'SELECT * FROM write_event ' .
 
  664                'WHERE obj_id = %s ' .
 
  665                'AND usr_id <> %s ' .
 
  667                $ilDB->quote($obj_id, 
'integer'),
 
  668                $ilDB->quote($usr_id, 
'integer'),
 
  669                $ilDB->quote($catchup, 
'timestamp')
 
  674        $numRows = 
$res->numRows();
 
  679            return ($catchup == 
null) ? 1 : 2;
 
  737        if ($usr_id == 
null) {
 
  739                'SELECT * FROM read_event ' .
 
  740                'WHERE obj_id = %s ' .
 
  741                'ORDER BY last_access DESC',
 
  742                $ilDB->quote($obj_id, 
'integer')
 
  747                'SELECT * FROM read_event ' .
 
  748                'WHERE obj_id = %s ' .
 
  750                'ORDER BY last_access DESC',
 
  751                $ilDB->quote($obj_id, 
'integer'),
 
  752                $ilDB->quote($usr_id, 
'integer')
 
  759            $events[$counter][
'obj_id'] = $row[
'obj_id'];
 
  760            $events[$counter][
'usr_id'] = $row[
'usr_id'];
 
  761            $events[$counter][
'last_access'] = $row[
'last_access'];
 
  762            $events[$counter][
'read_count'] = $row[
'read_count'];
 
  763            $events[$counter][
'spent_seconds'] = $row[
'spent_seconds'];
 
  764            $events[$counter][
'first_access'] = $row[
'first_access'];
 
  768        return $events ? $events : array();
 
  784            'SELECT DISTINCT(usr_id) usr FROM read_event ' .
 
  785            'WHERE obj_id = %s ',
 
  786            $ilDB->quote($a_obj_id, 
'integer')
 
  789        while ($row = 
$ilDB->fetchObject(
$res)) {
 
  790            $users[] = $row->usr;
 
  792        return $users ? $users : array();
 
  804        if (isset(self::$has_accessed[$a_obj_id][$a_usr_id])) {
 
  805            return self::$has_accessed[$a_obj_id][$a_usr_id];
 
  809            "SELECT usr_id FROM read_event WHERE " .
 
  810            "obj_id = " . 
$ilDB->quote($a_obj_id, 
"integer") . 
" AND " .
 
  811            "usr_id = " . 
$ilDB->quote($a_usr_id, 
"integer")
 
  813        if ($rec = 
$ilDB->fetchAssoc($set)) {
 
  814            return self::$has_accessed[$a_obj_id][$a_usr_id] = 
true;
 
  816        return self::$has_accessed[$a_obj_id][$a_usr_id] = 
false;
 
  827            return 'change event tracking is already active';
 
  839            $set = 
$ilDB->query(sprintf(
 
  840                'SELECT r1.obj_id,r2.obj_id p,d.owner,%s,d.create_date ' .
 
  841                'FROM object_data d ' .
 
  842                'LEFT JOIN write_event w ON d.obj_id = w.obj_id ' .
 
  843                'JOIN object_reference r1 ON d.obj_id=r1.obj_id ' .
 
  844                'JOIN tree t ON t.child=r1.ref_id ' .
 
  845                'JOIN object_reference r2 on r2.ref_id=t.parent ' .
 
  846                'WHERE w.obj_id IS NULL',
 
  847                $ilDB->quote(
'create', 
'text')
 
  849            while ($rec = 
$ilDB->fetchAssoc($set)) {
 
  850                $nid = 
$ilDB->nextId(
"write_event");
 
  851                $query = 
'INSERT INTO write_event ' .
 
  852                    '(write_id, obj_id,parent_obj_id,usr_id,action,ts) VALUES (' .
 
  853                    $ilDB->quote($nid, 
"integer") . 
"," .
 
  854                    $ilDB->quote($rec[
"obj_id"], 
"integer") . 
"," .
 
  855                    $ilDB->quote($rec[
"p"], 
"integer") . 
"," .
 
  856                    $ilDB->quote($rec[
"owner"], 
"integer") . 
"," .
 
  857                    $ilDB->quote(
"create", 
"text") . 
"," .
 
  858                    $ilDB->quote($rec[
"create_date"], 
"timestamp") .
 
  866            $ilSetting->set(
'enable_change_event_tracking', 
'1');
 
  882        $ilSetting->set(
'enable_change_event_tracking', 
'0');
 
  895        return $ilSetting->get(
'enable_change_event_tracking', 
'0') == 
'1';
 
  911            'DELETE FROM write_event WHERE obj_id = %s ',
 
  912            $ilDB->quote($a_obj_id, 
'integer')
 
  917            'DELETE FROM read_event WHERE obj_id = %s ',
 
  918            $ilDB->quote($a_obj_id, 
'integer')
 
  930        $ilDB->manipulate(
"DELETE FROM read_event" .
 
  931            " WHERE obj_id = " . 
$ilDB->quote($a_obj_id, 
"integer"));
 
  940        $ilDB->manipulate(
"DELETE FROM read_event" .
 
  941            " WHERE obj_id = " . 
$ilDB->quote($a_obj_id, 
"integer") .
 
  942            " AND " . 
$ilDB->in(
"usr_id", $a_user_ids, 
"", 
"integer"));
 
  953        $set = 
$ilDB->query(
"SELECT usr_id FROM read_event" .
 
  954            " WHERE obj_id = " . 
$ilDB->quote($a_obj_id, 
"integer"));
 
  955        while ($row = 
$ilDB->fetchAssoc($set)) {
 
  956            $res[] = $row[
"usr_id"];
 
  974            'UPDATE read_event SET first_access=%s, last_access = %s WHERE obj_id=%s AND usr_id=%s',
 
  975            array(
'timestamp',
'integer',
'integer',
'integer'),
 
  976            array($t_first_access,$i_last_access,$obj_id,$usr_id)
 
foreach($mandatory_scripts as $file) $timestamp
An exception for terminatinating execution or to throw for unit testing.
Class ilChangeEvent tracks change events on repository objects.
static _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds=null, $a_child_read_count=null)
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 _lookupChangeState($obj_id, $usr_id)
Returns the change state of the object for the specified user.
static _syncObjectStats($a_now=null, $a_minimum=20000)
Process object statistics log data.
static _catchupWriteEvents($obj_id, $usr_id, $timestamp=null)
Catches up with all write events which occured before the specified timestamp.
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 _getAllUserIds($a_obj_id)
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 ...
static lookupUsersInProgress($a_obj_id)
Lookup users in progress.
static _isActive()
Returns true, if change event tracking is active.
static _lookupUncaughtWriteEvents($obj_id, $usr_id)
Catches up with all write events which occured before the specified timestamp.
static _activate()
Activates change event tracking.
static _deactivate()
Deactivates change event tracking.
static hasAccessed($a_obj_id, $a_usr_id)
Has accessed.
static _deleteReadEventsForUsers($a_obj_id, array $a_user_ids)
static _recordWriteEvent($obj_id, $usr_id, $action, $parent_obj_id=null)
Records a write event.
static _delete($a_obj_id)
Delete object entries.
static _deleteReadEvents($a_obj_id)
static _enabledObjectStatistics()
check wether object statistics is enabled or not
static _getValidTimeSpan()
static _lookupObjId($a_id)
static _lookupType($a_id, $a_reference=false)
lookup object type
static now()
Return current timestamp in Y-m-d H:i:s format.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
foreach($_POST as $key=> $value) $res