ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilChangeEvent.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4
37{
38 private static $has_accessed = array();
39
55 public static function _recordWriteEvent($obj_id, $usr_id, $action, $parent_obj_id = null)
56 {
57 global $ilDB;
58
59 /* see _recordReadEvent
60 if (!ilChangeEvent::_isActive())
61 {
62 return;
63 }
64 */
65
66 if ($parent_obj_id == null) {
67 $pset = $ilDB->query('SELECT r2.obj_id par_obj_id FROM object_reference r1 ' .
68 'JOIN tree t ON t.child = r1.ref_id ' .
69 'JOIN object_reference r2 ON r2.ref_id = t.parent ' .
70 'WHERE r1.obj_id = ' . $ilDB->quote($obj_id, 'integer'));
71
72 while ($prec = $ilDB->fetchAssoc($pset)) {
73 $nid = $ilDB->nextId("write_event");
75 'INSERT INTO write_event ' .
76 '(write_id, obj_id, parent_obj_id, usr_id, action, ts) VALUES ' .
77 '(%s, %s, %s, %s, %s, ' . $ilDB->now() . ')',
78 $ilDB->quote($nid, 'integer'),
79 $ilDB->quote($obj_id, 'integer'),
80 $ilDB->quote($prec["par_obj_id"], 'integer'),
81 $ilDB->quote($usr_id, 'integer'),
82 $ilDB->quote($action, 'text')
83 );
84
85 $aff = $ilDB->manipulate($query);
86 }
87 } else {
88 $nid = $ilDB->nextId("write_event");
90 'INSERT INTO write_event ' .
91 '(write_id, obj_id, parent_obj_id, usr_id, action, ts) ' .
92 'VALUES (%s,%s,%s,%s,%s,' . $ilDB->now() . ')',
93 $ilDB->quote($nid, 'integer'),
94 $ilDB->quote($obj_id, 'integer'),
95 $ilDB->quote($parent_obj_id, 'integer'),
96 $ilDB->quote($usr_id, 'integer'),
97 $ilDB->quote($action, 'text')
98 );
99 $aff = $ilDB->manipulate($query);
100 }
101 }
102
111 public static function _recordReadEvent(
112 $a_type,
113 $a_ref_id,
114 $obj_id,
115 $usr_id,
116 $isCatchupWriteEvents = true,
117 $a_ext_rc = false,
118 $a_ext_time = false
119 ) {
120 global $ilDB, $tree;
121
122 /* read_event data is now used for several features, so we are always keeping track
123 if (!ilChangeEvent::_isActive())
124 {
125 return;
126 }
127 */
128
129 include_once('Services/Tracking/classes/class.ilObjUserTracking.php');
130 $validTimeSpan = ilObjUserTracking::_getValidTimeSpan();
131
132 $query = sprintf(
133 'SELECT * FROM read_event ' .
134 'WHERE obj_id = %s ' .
135 'AND usr_id = %s ',
136 $ilDB->quote($obj_id, 'integer'),
137 $ilDB->quote($usr_id, 'integer')
138 );
139 $res = $ilDB->query($query);
140 $row = $ilDB->fetchObject($res);
141
142 // read counter
143 if ($a_ext_rc !== false) {
144 $read_count = 'read_count = ' . $ilDB->quote($a_ext_rc, "integer") . ", ";
145 $read_count_init = max(1, (int) $a_ext_rc);
146 $read_count_diff = max(1, (int) $a_ext_rc) - $row->read_count;
147 } else {
148 $read_count = 'read_count = read_count + 1, ';
149 $read_count_init = 1;
150 $read_count_diff = 1;
151 }
152
153 if ($row) {
154 if ($a_ext_time !== false) {
155 $time = (int) $a_ext_time;
156 } else {
157 $time = $ilDB->quote((time() - $row->last_access) <= $validTimeSpan
158 ? $row->spent_seconds + time() - $row->last_access
159 : $row->spent_seconds, 'integer');
160
161 // if we are in the valid interval, we do not
162 // add anything to the read_count, since this is the
163 // same access for us
164 if ((time() - $row->last_access) <= $validTimeSpan) {
165 $read_count = '';
166 $read_count_init = 1;
167 $read_count_diff = 0;
168 }
169 }
170 $time_diff = $time - (int) $row->spent_seconds;
171
172 // Update
173 $query = sprintf(
174 'UPDATE read_event SET ' .
175 $read_count .
176 'spent_seconds = %s, ' .
177 'last_access = %s ' .
178 'WHERE obj_id = %s ' .
179 'AND usr_id = %s ',
180 $time,
181 $ilDB->quote(time(), 'integer'),
182 $ilDB->quote($obj_id, 'integer'),
183 $ilDB->quote($usr_id, 'integer')
184 );
185 $aff = $ilDB->manipulate($query);
186
187 self::_recordObjStats($obj_id, $time_diff, $read_count_diff);
188 } else {
189 if ($a_ext_time !== false) {
190 $time = (int) $a_ext_time;
191 } else {
192 $time = 0;
193 }
194
195 $time_diff = $time - (int) $row->spent_seconds;
196
197 /*
198 $query = sprintf('INSERT INTO read_event (obj_id,usr_id,last_access,read_count,spent_seconds,first_access) '.
199 'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().') ',
200 $ilDB->quote($obj_id,'integer'),
201 $ilDB->quote($usr_id,'integer'),
202 $ilDB->quote(time(),'integer'),
203 $ilDB->quote($read_count_init,'integer'),
204 $ilDB->quote($time,'integer'));
205 $ilDB->manipulate($query);
206 */
207
208 // #10407
209 $ilDB->replace(
210 'read_event',
211 array(
212 'obj_id' => array('integer', $obj_id),
213 'usr_id' => array('integer', $usr_id)
214 ),
215 array(
216 'read_count' => array('integer', $read_count_init),
217 'spent_seconds' => array('integer', $time),
218 'first_access' => array('timestamp', date("Y-m-d H:i:s")), // was $ilDB->now()
219 'last_access' => array('integer', time())
220 )
221 );
222
223 self::$has_accessed[$obj_id][$usr_id] = true;
224
225 self::_recordObjStats($obj_id, $time_diff, $read_count_diff);
226 }
227
228 if ($isCatchupWriteEvents) {
229 ilChangeEvent::_catchupWriteEvents($obj_id, $usr_id);
230 }
231
232 // update parents (no categories or root)
233 if (!in_array($a_type, array("cat", "root", "crs"))) {
234 if ($tree->isInTree($a_ref_id)) {
235 $path = $tree->getPathId($a_ref_id);
236
237 foreach ($path as $p) {
238 $obj2_id = ilObject::_lookupObjId($p);
239 $obj2_type = ilObject::_lookupType($obj2_id);
240 //echo "<br>1-$obj2_type-$p-$obj2_id-";
241 if (($p != $a_ref_id) && (in_array($obj2_type, array("crs", "fold", "grp")))) {
242 $query = sprintf(
243 'SELECT * FROM read_event ' .
244 'WHERE obj_id = %s ' .
245 'AND usr_id = %s ',
246 $ilDB->quote($obj2_id, 'integer'),
247 $ilDB->quote($usr_id, 'integer')
248 );
249 $res2 = $ilDB->query($query);
250 if ($row2 = $ilDB->fetchAssoc($res2)) {
251 //echo "<br>2";
252 // update read count and spent seconds
253 $query = sprintf(
254 'UPDATE read_event SET ' .
255 'childs_read_count = childs_read_count + %s ,' .
256 'childs_spent_seconds = childs_spent_seconds + %s ' .
257 'WHERE obj_id = %s ' .
258 'AND usr_id = %s ',
259 $ilDB->quote((int) $read_count_diff, 'integer'),
260 $ilDB->quote((int) $time_diff, 'integer'),
261 $ilDB->quote($obj2_id, 'integer'),
262 $ilDB->quote($usr_id, 'integer')
263 );
264 $aff = $ilDB->manipulate($query);
265
266 self::_recordObjStats($obj2_id, null, null, (int) $time_diff, (int) $read_count_diff);
267 } else {
268 //echo "<br>3";
269 //$ilLog->write("insert read event for obj_id -".$obj2_id."-".$usr_id."-");
270 /*
271 $query = sprintf('INSERT INTO read_event (obj_id,usr_id,last_access,read_count,spent_seconds,first_access,'.
272 'childs_read_count, childs_spent_seconds) '.
273 'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().', %s, %s) ',
274 $ilDB->quote($obj2_id,'integer'),
275 $ilDB->quote($usr_id,'integer'),
276 $ilDB->quote(time(),'integer'),
277 $ilDB->quote(1,'integer'),
278 $ilDB->quote($time,'integer'),
279 $ilDB->quote((int) $read_count_diff,'integer'),
280 $ilDB->quote((int) $time_diff,'integer')
281 );
282 $aff = $ilDB->manipulate($query);
283 */
284
285 // #10407
286 $ilDB->replace(
287 'read_event',
288 array(
289 'obj_id' => array('integer', $obj2_id),
290 'usr_id' => array('integer', $usr_id)
291 ),
292 array(
293 'read_count' => array('integer', 1),
294 'spent_seconds' => array('integer', $time),
295 'first_access' => array('timestamp', date("Y-m-d H:i:s")), // was $ilDB->now()
296 'last_access' => array('integer', time()),
297 'childs_read_count' => array('integer', (int) $read_count_diff),
298 'childs_spent_seconds' => array('integer', (int) $time_diff)
299 )
300 );
301
302 self::$has_accessed[$obj2_id][$usr_id] = true;
303
304 self::_recordObjStats($obj2_id, $time, 1, (int) $time_diff, (int) $read_count_diff);
305 }
306 }
307 }
308 }
309 }
310
311 // @todo:
312 // - calculate diff of spent_seconds and read_count
313 // - use ref id to get parents of types grp, crs, fold
314 // - add diffs to childs_spent_seconds and childs_read_count
315 }
316
317 public static function _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds = null, $a_child_read_count = null)
318 {
319 global $ilDB;
320
322 (int) $a_obj_id <= 0) { // #12706
323 return;
324 }
325
326 $now = time();
327
328 $fields = array();
329 $fields['log_id'] = array("integer", $ilDB->nextId('obj_stat_log'));
330 $fields["obj_id"] = array("integer", $a_obj_id);
331 $fields["obj_type"] = array("text", ilObject::_lookupType($a_obj_id));
332 $fields["tstamp"] = array("timestamp", $now);
333 $fields["yyyy"] = array("integer", date("Y"));
334 $fields["mm"] = array("integer", date("m"));
335 $fields["dd"] = array("integer", date("d"));
336 $fields["hh"] = array("integer", date("H"));
337 if ($a_spent_seconds > 0) {
338 $fields["spent_seconds"] = array("integer", $a_spent_seconds);
339 }
340 if ($a_read_count > 0) {
341 $fields["read_count"] = array("integer", $a_read_count);
342 }
343 if ($a_childs_spent_seconds > 0) {
344 $fields["childs_spent_seconds"] = array("integer", $a_childs_spent_seconds);
345 }
346 if ($a_child_read_count > 0) {
347 $fields["childs_read_count"] = array("integer", $a_child_read_count);
348 }
349 $ilDB->insert("obj_stat_log", $fields);
350
351 // 0.01% probability
352 if (mt_rand(1, 100) == 1) {
354 }
355 }
356
363 public static function _syncObjectStats($a_now = null, $a_minimum = 20000)
364 {
365 global $ilDB;
366
367 if (!$a_now) {
368 $a_now = time();
369 }
370
371 set_time_limit(0);
372
373 // has source table enough entries?
374 $set = $ilDB->query("SELECT COUNT(*) AS counter FROM obj_stat_log");
375 $row = $ilDB->fetchAssoc($set);
376 if ($row["counter"] >= $a_minimum) {
377 $ilAtomQuery = $ilDB->buildAtomQuery();
378 $ilAtomQuery->addTableLock('obj_stat_log');
379 $ilAtomQuery->addTableLock('obj_stat_tmp');
380
381 $ilAtomQuery->addQueryCallable(function (ilDBInterface $ilDB) use ($a_now, $a_minimum, &$ret) {
382
383 // if other process was transferring, we had to wait for the lock and
384 // the source table should now have less than minimum/needed entries
385 $set = $ilDB->query("SELECT COUNT(*) AS counter FROM obj_stat_log");
386 $row = $ilDB->fetchAssoc($set);
387 if ($row["counter"] >= $a_minimum) {
388 // use only "full" seconds to have a clear cut
389 $ilDB->query("INSERT INTO obj_stat_tmp" .
390 " SELECT * FROM obj_stat_log" .
391 " WHERE tstamp < " . $ilDB->quote($a_now, "timestamp"));
392
393 // remove transferred entries from source table
394 $ilDB->query("DELETE FROM obj_stat_log" .
395 " WHERE tstamp < " . $ilDB->quote($a_now, "timestamp"));
396
397 $ret = true;
398 } else {
399 $ret = false;
400 }
401 });
402
403 $ilAtomQuery->run();
404
405 //continue only if obj_stat_log counter >= $a_minimum
406 if ($ret) {
407 $ilAtomQuery = $ilDB->buildAtomQuery();
408 $ilAtomQuery->addTableLock('obj_stat_tmp');
409 $ilAtomQuery->addTableLock('obj_stat');
410
411 $ilAtomQuery->addQueryCallable(function (ilDBInterface $ilDB) use ($a_now, $a_minimum) {
412
413 // process log data (timestamp is not needed anymore)
414 $sql = "SELECT obj_id, obj_type, yyyy, mm, dd, hh, SUM(read_count) AS read_count," .
415 " SUM(childs_read_count) AS childs_read_count, SUM(spent_seconds) AS spent_seconds," .
416 " SUM(childs_spent_seconds) AS childs_spent_seconds" .
417 " FROM obj_stat_tmp" .
418 " GROUP BY obj_id, obj_type, yyyy, mm, dd, hh";
419 $set = $ilDB->query($sql);
420 while ($row = $ilDB->fetchAssoc($set)) {
421 // "primary key"
422 $where = array("obj_id" => array("integer", $row["obj_id"]),
423 "obj_type" => array("text", $row["obj_type"]),
424 "yyyy" => array("integer", $row["yyyy"]),
425 "mm" => array("integer", $row["mm"]),
426 "dd" => array("integer", $row["dd"]),
427 "hh" => array("integer", $row["hh"]));
428
429 $where_sql = array();
430 foreach ($where as $field => $def) {
431 $where_sql[] = $field . " = " . $ilDB->quote($def[1], $def[0]);
432 }
433 $where_sql = implode(" AND ", $where_sql);
434
435 // existing entry?
436 $check = $ilDB->query("SELECT read_count, childs_read_count, spent_seconds," .
437 "childs_spent_seconds" .
438 " FROM obj_stat" .
439 " WHERE " . $where_sql);
440 if ($ilDB->numRows($check)) {
441 $old = $ilDB->fetchAssoc($check);
442
443 // add existing values
444 $fields = array("read_count" => array("integer", $old["read_count"]+$row["read_count"]),
445 "childs_read_count" => array("integer", $old["childs_read_count"]+$row["childs_read_count"]),
446 "spent_seconds" => array("integer", $old["spent_seconds"]+$row["spent_seconds"]),
447 "childs_spent_seconds" => array("integer", $old["childs_spent_seconds"]+$row["childs_spent_seconds"]));
448
449 $ilDB->update("obj_stat", $fields, $where);
450 } else {
451 // new entry
452 $fields = $where;
453 $fields["read_count"] = array("integer", $row["read_count"]);
454 $fields["childs_read_count"] = array("integer", $row["childs_read_count"]);
455 $fields["spent_seconds"] = array("integer", $row["spent_seconds"]);
456 $fields["childs_spent_seconds"] = array("integer", $row["childs_spent_seconds"]);
457
458 $ilDB->insert("obj_stat", $fields);
459 }
460 }
461
462 // clean up transfer table
463 $ilDB->query("DELETE FROM obj_stat_tmp");
464 });
465
466 $ilAtomQuery->run();
467 }
468 }
469 }
470
479 public static function _catchupWriteEvents($obj_id, $usr_id, $timestamp = null)
480 {
481 global $ilDB;
482
483 $query = "SELECT obj_id FROM catch_write_events " .
484 "WHERE obj_id = " . $ilDB->quote($obj_id, 'integer') . " " .
485 "AND usr_id = " . $ilDB->quote($usr_id, 'integer');
486 $res = $ilDB->query($query);
487 if ($res->numRows()) {
488 $ts = ($timestamp == null)
489 ? ilUtil::now()
490 : $timestamp;
491 /* $query = "UPDATE catch_write_events ".
492 "SET ts = ".($timestamp == null ? $ilDB->now() : $ilDB->quote($timestamp, 'timestamp'))." ".
493 "WHERE usr_id = ".$ilDB->quote($usr_id ,'integer')." ".
494 "AND obj_id = ".$ilDB->quote($obj_id ,'integer');
495 $res = $ilDB->manipulate($query);*/
496 } else {
497 $ts = ilUtil::now();
498 /* $query = "INSERT INTO catch_write_events (ts,obj_id,usr_id) ".
499 "VALUES( ".
500 $ilDB->now().", ".
501 $ilDB->quote($obj_id,'integer').", ".
502 $ilDB->quote($usr_id,'integer')." ".
503 ")";
504 $res = $ilDB->manipulate($query);*/
505 }
506
507 // alex, use replace due to bug #10406
508 $ilDB->replace(
509 "catch_write_events",
510 array(
511 "obj_id" => array("integer", $obj_id),
512 "usr_id" => array("integer", $usr_id)
513 ),
514 array(
515 "ts" => array("timestamp", $ts))
516 );
517 }
518
566 public static function _lookupUncaughtWriteEvents($obj_id, $usr_id)
567 {
568 global $ilDB;
569
570 $q = "SELECT ts " .
571 "FROM catch_write_events " .
572 "WHERE obj_id=" . $ilDB->quote($obj_id, 'integer') . " " .
573 "AND usr_id=" . $ilDB->quote($usr_id, 'integer');
574 $r = $ilDB->query($q);
575 $catchup = null;
576 while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
577 $catchup = $row['ts'];
578 }
579
580 if ($catchup == null) {
581 $query = sprintf(
582 'SELECT * FROM write_event ' .
583 'WHERE obj_id = %s ' .
584 'AND usr_id <> %s ' .
585 'ORDER BY ts DESC',
586 $ilDB->quote($obj_id, 'integer'),
587 $ilDB->quote($usr_id, 'integer')
588 );
589 $res = $ilDB->query($query);
590 } else {
591 $query = sprintf(
592 'SELECT * FROM write_event ' .
593 'WHERE obj_id = %s ' .
594 'AND usr_id <> %s ' .
595 'AND ts >= %s ' .
596 'ORDER BY ts DESC',
597 $ilDB->quote($obj_id, 'integer'),
598 $ilDB->quote($usr_id, 'integer'),
599 $ilDB->quote($catchup, 'timestamp')
600 );
601 $res = $ilDB->query($query);
602 }
603 $events = array();
604 while ($row = $ilDB->fetchAssoc($res)) {
605 $events[] = $row;
606 }
607 return $events;
608 }
619 public static function _lookupChangeState($obj_id, $usr_id)
620 {
621 global $ilDB;
622
623 $q = "SELECT ts " .
624 "FROM catch_write_events " .
625 "WHERE obj_id=" . $ilDB->quote($obj_id, 'integer') . " " .
626 "AND usr_id=" . $ilDB->quote($usr_id, 'integer');
627 $r = $ilDB->query($q);
628 $catchup = null;
629 while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
630 $catchup = $row['ts'];
631 }
632
633 if ($catchup == null) {
634 $ilDB->setLimit(1);
635 $query = sprintf(
636 'SELECT * FROM write_event ' .
637 'WHERE obj_id = %s ' .
638 'AND usr_id <> %s ',
639 $ilDB->quote($obj_id, 'integer'),
640 $ilDB->quote($usr_id, 'integer')
641 );
642 $res = $ilDB->query($query);
643 } else {
644 $ilDB->setLimit(1);
645 $query = sprintf(
646 'SELECT * FROM write_event ' .
647 'WHERE obj_id = %s ' .
648 'AND usr_id <> %s ' .
649 'AND ts > %s ',
650 $ilDB->quote($obj_id, 'integer'),
651 $ilDB->quote($usr_id, 'integer'),
652 $ilDB->quote($catchup, 'timestamp')
653 );
654 $res = $ilDB->query($query);
655 }
656
657 $numRows = $res->numRows();
658 if ($numRows > 0) {
659 $row = $ilDB->fetchAssoc($res);
660 // if we have write events, and user never catched one, report as new (1)
661 // if we have write events, and user catched an old write event, report as changed (2)
662 return ($catchup == null) ? 1 : 2;
663 } else {
664 return 0; // user catched all write events, report as unchanged (0)
665 }
666 }
667
712 public static function _lookupReadEvents($obj_id, $usr_id = null)
713 {
714 global $ilDB;
715
716 if ($usr_id == null) {
717 $query = sprintf(
718 'SELECT * FROM read_event ' .
719 'WHERE obj_id = %s ' .
720 'ORDER BY last_access DESC',
721 $ilDB->quote($obj_id, 'integer')
722 );
723 $res = $ilDB->query($query);
724 } else {
725 $query = sprintf(
726 'SELECT * FROM read_event ' .
727 'WHERE obj_id = %s ' .
728 'AND usr_id = %s ' .
729 'ORDER BY last_access DESC',
730 $ilDB->quote($obj_id, 'integer'),
731 $ilDB->quote($usr_id, 'integer')
732 );
733 $res = $ilDB->query($query);
734 }
735
736 $counter = 0;
737 while ($row = $ilDB->fetchAssoc($res)) {
738 $events[$counter]['obj_id'] = $row['obj_id'];
739 $events[$counter]['usr_id'] = $row['usr_id'];
740 $events[$counter]['last_access'] = $row['last_access'];
741 $events[$counter]['read_count'] = $row['read_count'];
742 $events[$counter]['spent_seconds'] = $row['spent_seconds'];
743 $events[$counter]['first_access'] = $row['first_access'];
744
745 $counter++;
746 }
747 return $events ? $events : array();
748 }
749
756 public static function lookupUsersInProgress($a_obj_id)
757 {
758 global $ilDB;
759
760 $query = sprintf(
761 'SELECT DISTINCT(usr_id) usr FROM read_event ' .
762 'WHERE obj_id = %s ',
763 $ilDB->quote($a_obj_id, 'integer')
764 );
765 $res = $ilDB->query($query);
766 while ($row = $ilDB->fetchObject($res)) {
767 $users[] = $row->usr;
768 }
769 return $users ? $users : array();
770 }
771
775 public static function hasAccessed($a_obj_id, $a_usr_id)
776 {
777 global $ilDB;
778
779 if (isset(self::$has_accessed[$a_obj_id][$a_usr_id])) {
780 return self::$has_accessed[$a_obj_id][$a_usr_id];
781 }
782
783 $set = $ilDB->query(
784 "SELECT usr_id FROM read_event WHERE " .
785 "obj_id = " . $ilDB->quote($a_obj_id, "integer") . " AND " .
786 "usr_id = " . $ilDB->quote($a_usr_id, "integer")
787 );
788 if ($rec = $ilDB->fetchAssoc($set)) {
789 return self::$has_accessed[$a_obj_id][$a_usr_id] = true;
790 }
791 return self::$has_accessed[$a_obj_id][$a_usr_id] = false;
792 }
793
799 public static function _activate()
800 {
802 return 'change event tracking is already active';
803 } else {
804 global $ilDB;
805
806 // Insert initial data into table write_event
807 // We need to do this here, because we need
808 // to catch up write events that occured while the change event tracking was
809 // deactivated.
810
811 // IGNORE isn't supported in oracle
812 $set = $ilDB->query(sprintf(
813 'SELECT r1.obj_id,r2.obj_id p,d.owner,%s,d.create_date ' .
814 'FROM object_data d ' .
815 'LEFT JOIN write_event w ON d.obj_id = w.obj_id ' .
816 'JOIN object_reference r1 ON d.obj_id=r1.obj_id ' .
817 'JOIN tree t ON t.child=r1.ref_id ' .
818 'JOIN object_reference r2 on r2.ref_id=t.parent ' .
819 'WHERE w.obj_id IS NULL',
820 $ilDB->quote('create', 'text')
821 ));
822 while ($rec = $ilDB->fetchAssoc($set)) {
823 $nid = $ilDB->nextId("write_event");
824 $query = 'INSERT INTO write_event ' .
825 '(write_id, obj_id,parent_obj_id,usr_id,action,ts) VALUES (' .
826 $ilDB->quote($nid, "integer") . "," .
827 $ilDB->quote($rec["obj_id"], "integer") . "," .
828 $ilDB->quote($rec["p"], "integer") . "," .
829 $ilDB->quote($rec["owner"], "integer") . "," .
830 $ilDB->quote("create", "text") . "," .
831 $ilDB->quote($rec["create_date"], "timestamp") .
832 ')';
833 $res = $ilDB->query($query);
834 }
835
836 global $ilSetting;
837 $ilSetting->set('enable_change_event_tracking', '1');
838
839 return $res;
840 }
841 }
842
848 public static function _deactivate()
849 {
850 global $ilSetting;
851 $ilSetting->set('enable_change_event_tracking', '0');
852 }
853
859 public static function _isActive()
860 {
861 global $ilSetting;
862 return $ilSetting->get('enable_change_event_tracking', '0') == '1';
863 }
864
871 public static function _delete($a_obj_id)
872 {
873 global $ilDB;
874
875 $query = sprintf(
876 'DELETE FROM write_event WHERE obj_id = %s ',
877 $ilDB->quote($a_obj_id, 'integer')
878 );
879 $aff = $ilDB->manipulate($query);
880
881 $query = sprintf(
882 'DELETE FROM read_event WHERE obj_id = %s ',
883 $ilDB->quote($a_obj_id, 'integer')
884 );
885 $aff = $ilDB->manipulate($query);
886 return true;
887 }
888
889 public static function _deleteReadEvents($a_obj_id)
890 {
891 global $ilDB;
892
893 $ilDB->manipulate("DELETE FROM read_event" .
894 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer"));
895 }
896
897 public static function _deleteReadEventsForUsers($a_obj_id, array $a_user_ids)
898 {
899 global $ilDB;
900
901 $ilDB->manipulate("DELETE FROM read_event" .
902 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer") .
903 " AND " . $ilDB->in("usr_id", $a_user_ids, "", "integer"));
904 }
905
906 public static function _getAllUserIds($a_obj_id)
907 {
908 global $ilDB;
909
910 $res = array();
911
912 $set = $ilDB->query("SELECT usr_id FROM read_event" .
913 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer"));
914 while ($row = $ilDB->fetchAssoc($set)) {
915 $res[] = $row["usr_id"];
916 }
917
918 return $res;
919 }
920
927 public static function _updateAccessForScormOfflinePlayer($obj_id, $usr_id, $i_last_access, $t_first_access)
928 {
929 global $ilDB;
930 $res = $ilDB->queryF(
931 'UPDATE read_event SET first_access=%s, last_access = %s WHERE obj_id=%s AND usr_id=%s',
932 array('timestamp','integer','integer','integer'),
933 array($t_first_access,$i_last_access,$obj_id,$usr_id)
934 );
935 return $res;
936 }
937}
sprintf('%.4f', $callTime)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
$users
Definition: authpage.php:44
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
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 _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.
$counter
$action
$r
Definition: example_031.php:79
Interface ilDBInterface.
$time
Definition: cron.php:21
$ret
Definition: parser.php:6
global $ilSetting
Definition: privfeed.php:17
$query
foreach($_POST as $key=> $value) $res
global $ilDB
$a_type
Definition: workflow.php:92