ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 static private $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 {
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'));
72
73 while ($prec = $ilDB->fetchAssoc($pset))
74 {
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'));
84
85 $aff = $ilDB->manipulate($query);
86 }
87 }
88 else
89 {
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);
100
101 }
102 }
103
112 static function _recordReadEvent($a_type, $a_ref_id, $obj_id, $usr_id,
113 $isCatchupWriteEvents = true, $a_ext_rc = false, $a_ext_time = false)
114 {
115 global $ilDB, $tree;
116
117 /* read_event data is now used for several features, so we are always keeping track
118 if (!ilChangeEvent::_isActive())
119 {
120 return;
121 }
122 */
123
124 include_once('Services/Tracking/classes/class.ilObjUserTracking.php');
125 $validTimeSpan = ilObjUserTracking::_getValidTimeSpan();
126
127 $query = sprintf('SELECT * FROM read_event '.
128 'WHERE obj_id = %s '.
129 'AND usr_id = %s ',
130 $ilDB->quote($obj_id,'integer'),
131 $ilDB->quote($usr_id,'integer'));
132 $res = $ilDB->query($query);
133 $row = $ilDB->fetchObject($res);
134
135 // read counter
136 if ($a_ext_rc !== false)
137 {
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;
141 }
142 else
143 {
144 $read_count = 'read_count = read_count + 1, ';
145 $read_count_init = 1;
146 $read_count_diff = 1;
147 }
148
149 if ($row)
150 {
151
152 if ($a_ext_time !== false)
153 {
154 $time = (int) $a_ext_time;
155 }
156 else
157 {
158 $time = $ilDB->quote((time() - $row->last_access) <= $validTimeSpan
159 ? $row->spent_seconds + time() - $row->last_access
160 : $row->spent_seconds,'integer');
161
162 // if we are in the valid interval, we do not
163 // add anything to the read_count, since this is the
164 // same access for us
165 if ((time() - $row->last_access) <= $validTimeSpan)
166 {
167 $read_count = '';
168 $read_count_init = 1;
169 $read_count_diff = 0;
170 }
171 }
172 $time_diff = $time - (int) $row->spent_seconds;
173
174 // Update
175 $query = sprintf('UPDATE read_event SET '.
176 $read_count.
177 'spent_seconds = %s, '.
178 'last_access = %s '.
179 'WHERE obj_id = %s '.
180 'AND usr_id = %s ',
181 $time,
182 $ilDB->quote(time(),'integer'),
183 $ilDB->quote($obj_id,'integer'),
184 $ilDB->quote($usr_id,'integer'));
185 $aff = $ilDB->manipulate($query);
186
187 self::_recordObjStats($obj_id, $time_diff, $read_count_diff);
188 }
189 else
190 {
191 if ($a_ext_time !== false)
192 {
193 $time = (int) $a_ext_time;
194 }
195 else
196 {
197 $time = 0;
198 }
199
200 $time_diff = $time - (int) $row->spent_seconds;
201
202 /*
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'));
210 $ilDB->manipulate($query);
211 */
212
213 // #10407
214 $ilDB->replace('read_event',
215 array(
216 'obj_id' => array('integer', $obj_id),
217 'usr_id' => array('integer', $usr_id)
218 ),
219 array(
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")), // was $ilDB->now()
223 'last_access' => array('integer', time())
224 )
225 );
226
227 self::$has_accessed[$obj_id][$usr_id] = true;
228
229 self::_recordObjStats($obj_id, $time_diff, $read_count_diff);
230 }
231
232 if ($isCatchupWriteEvents)
233 {
234 ilChangeEvent::_catchupWriteEvents($obj_id, $usr_id);
235 }
236
237 // update parents (no categories or root)
238 if (!in_array($a_type, array("cat", "root", "crs")))
239 {
240 if ($tree->isInTree($a_ref_id))
241 {
242 $path = $tree->getPathId($a_ref_id);
243
244 foreach ($path as $p)
245 {
246 $obj2_id = ilObject::_lookupObjId($p);
247 $obj2_type = ilObject::_lookupType($obj2_id);
248//echo "<br>1-$obj2_type-$p-$obj2_id-";
249 if (($p != $a_ref_id) && (in_array($obj2_type, array("crs", "fold", "grp"))))
250 {
251 $query = sprintf('SELECT * FROM read_event '.
252 'WHERE obj_id = %s '.
253 'AND usr_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))
258 {
259//echo "<br>2";
260 // update read count and spent seconds
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 '.
265 'AND usr_id = %s ',
266 $ilDB->quote((int) $read_count_diff,'integer'),
267 $ilDB->quote((int) $time_diff,'integer'),
268 $ilDB->quote($obj2_id,'integer'),
269 $ilDB->quote($usr_id,'integer'));
270 $aff = $ilDB->manipulate($query);
271
272 self::_recordObjStats($obj2_id, null, null, (int)$time_diff, (int)$read_count_diff);
273 }
274 else
275 {
276//echo "<br>3";
277//$ilLog->write("insert read event for obj_id -".$obj2_id."-".$usr_id."-");
278 /*
279 $query = sprintf('INSERT INTO read_event (obj_id,usr_id,last_access,read_count,spent_seconds,first_access,'.
280 'childs_read_count, childs_spent_seconds) '.
281 'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().', %s, %s) ',
282 $ilDB->quote($obj2_id,'integer'),
283 $ilDB->quote($usr_id,'integer'),
284 $ilDB->quote(time(),'integer'),
285 $ilDB->quote(1,'integer'),
286 $ilDB->quote($time,'integer'),
287 $ilDB->quote((int) $read_count_diff,'integer'),
288 $ilDB->quote((int) $time_diff,'integer')
289 );
290 $aff = $ilDB->manipulate($query);
291 */
292
293 // #10407
294 $ilDB->replace('read_event',
295 array(
296 'obj_id' => array('integer', $obj2_id),
297 'usr_id' => array('integer', $usr_id)
298 ),
299 array(
300 'read_count' => array('integer', 1),
301 'spent_seconds' => array('integer', $time),
302 'first_access' => array('timestamp', date("Y-m-d H:i:s")), // was $ilDB->now()
303 'last_access' => array('integer', time()),
304 'childs_read_count' => array('integer', (int)$read_count_diff),
305 'childs_spent_seconds' => array('integer', (int)$time_diff)
306 )
307 );
308
309 self::$has_accessed[$obj2_id][$usr_id] = true;
310
311 self::_recordObjStats($obj2_id, $time, 1, (int)$time_diff, (int)$read_count_diff);
312 }
313 }
314 }
315 }
316 }
317
318 // @todo:
319 // - calculate diff of spent_seconds and read_count
320 // - use ref id to get parents of types grp, crs, fold
321 // - add diffs to childs_spent_seconds and childs_read_count
322 }
323
324 static function _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds = null, $a_child_read_count = null)
325 {
326 global $ilDB;
327
329 (int)$a_obj_id <= 0) // #12706
330 {
331 return;
332 }
333
334 $now = time();
335
336 $fields = array();
337 $fields['log_id'] = array("integer", $ilDB->nextId('obj_stat_log'));
338 $fields["obj_id"] = array("integer", $a_obj_id);
339 $fields["obj_type"] = array("text", ilObject::_lookupType($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)
346 {
347 $fields["spent_seconds"] = array("integer", $a_spent_seconds);
348 }
349 if($a_read_count > 0)
350 {
351 $fields["read_count"] = array("integer", $a_read_count);
352 }
353 if($a_childs_spent_seconds > 0)
354 {
355 $fields["childs_spent_seconds"] = array("integer", $a_childs_spent_seconds);
356 }
357 if($a_child_read_count > 0)
358 {
359 $fields["childs_read_count"] = array("integer", $a_child_read_count);
360 }
361 $ilDB->insert("obj_stat_log", $fields);
362
363 // 0.01% probability
364 if(mt_rand(1, 100) == 1)
365 {
367 }
368 }
369
376 static function _syncObjectStats($a_now = null, $a_minimum = 20000)
377 {
378 global $ilDB;
379
380 if(!$a_now)
381 {
382 $a_now = time();
383 }
384
385 set_time_limit(0);
386
387 // has source table enough entries?
388 $set = $ilDB->query("SELECT COUNT(*) AS counter FROM obj_stat_log");
389 $row = $ilDB->fetchAssoc($set);
390 if($row["counter"] >= $a_minimum)
391 {
392 $ilAtomQuery = $ilDB->buildAtomQuery();
393 $ilAtomQuery->addTableLock('obj_stat_log');
394 $ilAtomQuery->addTableLock('obj_stat_tmp');
395
396 $ilAtomQuery->addQueryCallable(function(ilDBInterface $ilDB) use($a_now, $a_minimum, &$ret){
397
398 // if other process was transferring, we had to wait for the lock and
399 // the source table should now have less than minimum/needed entries
400 $set = $ilDB->query("SELECT COUNT(*) AS counter FROM obj_stat_log");
401 $row = $ilDB->fetchAssoc($set);
402 if($row["counter"] >= $a_minimum)
403 {
404 // use only "full" seconds to have a clear cut
405 $ilDB->query("INSERT INTO obj_stat_tmp".
406 " SELECT * FROM obj_stat_log".
407 " WHERE tstamp < ".$ilDB->quote($a_now, "timestamp"));
408
409 // remove transferred entries from source table
410 $ilDB->query("DELETE FROM obj_stat_log".
411 " WHERE tstamp < ".$ilDB->quote($a_now, "timestamp"));
412
413 $ret = true;
414 }
415 else
416 {
417 $ret = false;
418 }
419 });
420
421 $ilAtomQuery->run();
422
423 //continue only if obj_stat_log counter >= $a_minimum
424 if($ret)
425 {
426 $ilAtomQuery = $ilDB->buildAtomQuery();
427 $ilAtomQuery->addTableLock('obj_stat_tmp');
428 $ilAtomQuery->addTableLock('obj_stat');
429
430 $ilAtomQuery->addQueryCallable(function(ilDBInterface $ilDB) use($a_now, $a_minimum){
431
432 // process log data (timestamp is not needed anymore)
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);
439 while($row = $ilDB->fetchAssoc($set))
440 {
441 // "primary key"
442 $where = array("obj_id" => array("integer", $row["obj_id"]),
443 "obj_type" => array("text", $row["obj_type"]),
444 "yyyy" => array("integer", $row["yyyy"]),
445 "mm" => array("integer", $row["mm"]),
446 "dd" => array("integer", $row["dd"]),
447 "hh" => array("integer", $row["hh"]));
448
449 $where_sql = array();
450 foreach($where as $field => $def)
451 {
452 $where_sql[] = $field." = ".$ilDB->quote($def[1], $def[0]);
453 }
454 $where_sql = implode(" AND ", $where_sql);
455
456 // existing entry?
457 $check = $ilDB->query("SELECT read_count, childs_read_count, spent_seconds,".
458 "childs_spent_seconds".
459 " FROM obj_stat".
460 " WHERE ".$where_sql);
461 if($ilDB->numRows($check))
462 {
463 $old = $ilDB->fetchAssoc($check);
464
465 // add existing values
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"]));
470
471 $ilDB->update("obj_stat", $fields, $where);
472 }
473 else
474 {
475 // new entry
476 $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"]);
481
482 $ilDB->insert("obj_stat", $fields);
483 }
484 }
485
486 // clean up transfer table
487 $ilDB->query("DELETE FROM obj_stat_tmp");
488
489 });
490
491 $ilAtomQuery->run();
492 }
493 }
494 }
495
504 static function _catchupWriteEvents($obj_id, $usr_id, $timestamp = null)
505 {
506 global $ilDB;
507
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');
511 $res = $ilDB->query($query);
512 if($res->numRows())
513 {
514 $ts = ($timestamp == null)
515 ? ilUtil::now()
516 : $timestamp;
517/* $query = "UPDATE catch_write_events ".
518 "SET ts = ".($timestamp == null ? $ilDB->now() : $ilDB->quote($timestamp, 'timestamp'))." ".
519 "WHERE usr_id = ".$ilDB->quote($usr_id ,'integer')." ".
520 "AND obj_id = ".$ilDB->quote($obj_id ,'integer');
521 $res = $ilDB->manipulate($query);*/
522 }
523 else
524 {
525 $ts = ilUtil::now();
526/* $query = "INSERT INTO catch_write_events (ts,obj_id,usr_id) ".
527 "VALUES( ".
528 $ilDB->now().", ".
529 $ilDB->quote($obj_id,'integer').", ".
530 $ilDB->quote($usr_id,'integer')." ".
531 ")";
532 $res = $ilDB->manipulate($query);*/
533 }
534
535 // alex, use replace due to bug #10406
536 $ilDB->replace("catch_write_events",
537 array(
538 "obj_id" => array("integer", $obj_id),
539 "usr_id" => array("integer", $usr_id)
540 ),
541 array(
542 "ts" => array("timestamp", $ts))
543 );
544 }
545
593 public static function _lookupUncaughtWriteEvents($obj_id, $usr_id)
594 {
595 global $ilDB;
596
597 $q = "SELECT 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);
602 $catchup = null;
603 while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
604 $catchup = $row['ts'];
605 }
606
607 if($catchup == null)
608 {
609 $query = sprintf('SELECT * FROM write_event '.
610 'WHERE obj_id = %s '.
611 'AND usr_id <> %s '.
612 'ORDER BY ts DESC',
613 $ilDB->quote($obj_id,'integer'),
614 $ilDB->quote($usr_id,'integer'));
615 $res = $ilDB->query($query);
616 }
617 else
618 {
619 $query = sprintf('SELECT * FROM write_event '.
620 'WHERE obj_id = %s '.
621 'AND usr_id <> %s '.
622 'AND ts >= %s '.
623 'ORDER BY ts DESC',
624 $ilDB->quote($obj_id,'integer'),
625 $ilDB->quote($usr_id,'integer'),
626 $ilDB->quote($catchup,'timestamp'));
627 $res = $ilDB->query($query);
628 }
629 $events = array();
630 while($row = $ilDB->fetchAssoc($res))
631 {
632 $events[] = $row;
633 }
634 return $events;
635 }
646 public static function _lookupChangeState($obj_id, $usr_id)
647 {
648 global $ilDB;
649
650 $q = "SELECT ts ".
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);
655 $catchup = null;
656 while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
657 $catchup = $row['ts'];
658 }
659
660 if($catchup == null)
661 {
662 $ilDB->setLimit(1);
663 $query = sprintf('SELECT * FROM write_event '.
664 'WHERE obj_id = %s '.
665 'AND usr_id <> %s ',
666 $ilDB->quote($obj_id,'integer'),
667 $ilDB->quote($usr_id,'integer'));
668 $res = $ilDB->query($query);
669 }
670 else
671 {
672 $ilDB->setLimit(1);
673 $query = sprintf('SELECT * FROM write_event '.
674 'WHERE obj_id = %s '.
675 'AND usr_id <> %s '.
676 'AND ts > %s ',
677 $ilDB->quote($obj_id,'integer'),
678 $ilDB->quote($usr_id,'integer'),
679 $ilDB->quote($catchup,'timestamp'));
680 $res = $ilDB->query($query);
681 }
682
683 $numRows = $res->numRows();
684 if ($numRows > 0)
685 {
686 $row = $ilDB->fetchAssoc($res);
687 // if we have write events, and user never catched one, report as new (1)
688 // if we have write events, and user catched an old write event, report as changed (2)
689 return ($catchup == null) ? 1 : 2;
690 }
691 else
692 {
693 return 0; // user catched all write events, report as unchanged (0)
694 }
695 }
696
741 public static function _lookupReadEvents($obj_id, $usr_id = null)
742 {
743 global $ilDB;
744
745 if ($usr_id == null)
746 {
747 $query = sprintf('SELECT * FROM read_event '.
748 'WHERE obj_id = %s '.
749 'ORDER BY last_access DESC',
750 $ilDB->quote($obj_id,'integer'));
751 $res = $ilDB->query($query);
752 }
753 else
754 {
755 $query = sprintf('SELECT * FROM read_event '.
756 'WHERE obj_id = %s '.
757 'AND usr_id = %s '.
758 'ORDER BY last_access DESC',
759 $ilDB->quote($obj_id,'integer'),
760 $ilDB->quote($usr_id,'integer'));
761 $res = $ilDB->query($query);
762 }
763
764 $counter = 0;
765 while ($row = $ilDB->fetchAssoc($res))
766 {
767 $events[$counter]['obj_id'] = $row['obj_id'];
768 $events[$counter]['usr_id'] = $row['usr_id'];
769 $events[$counter]['last_access'] = $row['last_access'];
770 $events[$counter]['read_count'] = $row['read_count'];
771 $events[$counter]['spent_seconds'] = $row['spent_seconds'];
772 $events[$counter]['first_access'] = $row['first_access'];
773
774 $counter++;
775
776 }
777 return $events ? $events : array();
778 }
779
786 public static function lookupUsersInProgress($a_obj_id)
787 {
788 global $ilDB;
789
790 $query = sprintf('SELECT DISTINCT(usr_id) usr FROM read_event '.
791 'WHERE obj_id = %s ',
792 $ilDB->quote($a_obj_id,'integer'));
793 $res = $ilDB->query($query);
794 while($row = $ilDB->fetchObject($res))
795 {
796 $users[] = $row->usr;
797 }
798 return $users ? $users : array();
799 }
800
804 static function hasAccessed($a_obj_id, $a_usr_id)
805 {
806 global $ilDB;
807
808 if (isset(self::$has_accessed[$a_obj_id][$a_usr_id]))
809 {
810 return self::$has_accessed[$a_obj_id][$a_usr_id];
811 }
812
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")
816 );
817 if ($rec = $ilDB->fetchAssoc($set))
818 {
819 return self::$has_accessed[$a_obj_id][$a_usr_id] = true;
820 }
821 return self::$has_accessed[$a_obj_id][$a_usr_id] = false;
822 }
823
829 public static function _activate() {
831 {
832 return 'change event tracking is already active';
833 }
834 else
835 {
836 global $ilDB;
837
838 // Insert initial data into table write_event
839 // We need to do this here, because we need
840 // to catch up write events that occured while the change event tracking was
841 // deactivated.
842
843 // IGNORE isn't supported in oracle
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))
853 {
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").
863 ')';
864 $res = $ilDB->query($query);
865 }
866
867 global $ilSetting;
868 $ilSetting->set('enable_change_event_tracking', '1');
869
870 return $res;
871 }
872 }
873
879 public static function _deactivate() {
880 global $ilSetting;
881 $ilSetting->set('enable_change_event_tracking', '0');
882 }
883
889 public static function _isActive() {
890 global $ilSetting;
891 return $ilSetting->get('enable_change_event_tracking', '0') == '1';
892 }
893
900 public static function _delete($a_obj_id)
901 {
902 global $ilDB;
903
904 $query = sprintf('DELETE FROM write_event WHERE obj_id = %s ',
905 $ilDB->quote($a_obj_id,'integer'));
906 $aff = $ilDB->manipulate($query);
907
908 $query = sprintf('DELETE FROM read_event WHERE obj_id = %s ',
909 $ilDB->quote($a_obj_id,'integer'));
910 $aff = $ilDB->manipulate($query);
911 return true;
912 }
913
914 public static function _deleteReadEvents($a_obj_id)
915 {
916 global $ilDB;
917
918 $ilDB->manipulate("DELETE FROM read_event".
919 " WHERE obj_id = ".$ilDB->quote($a_obj_id, "integer"));
920 }
921
922 public static function _deleteReadEventsForUsers($a_obj_id, array $a_user_ids)
923 {
924 global $ilDB;
925
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"));
929 }
930
931 public static function _getAllUserIds($a_obj_id)
932 {
933 global $ilDB;
934
935 $res = array();
936
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))
940 {
941 $res[] = $row["usr_id"];
942 }
943
944 return $res;
945 }
946
953 static function _updateAccessForScormOfflinePlayer($obj_id, $usr_id, $i_last_access, $t_first_access) {
954 global $ilDB;
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)
958 );
959 return $res;
960 }
961}
962
963?>
sprintf('%.4f', $callTime)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
$path
Definition: aliased.php:25
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 _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 _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 _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
$r
Definition: example_031.php:79
Interface ilDBInterface.
$time_diff
Definition: langcheck.php:760
$ret
Definition: parser.php:6
global $ilSetting
Definition: privfeed.php:17
global $ilDB
$a_type
Definition: workflow.php:93