ILIAS  release_7 Revision v7.30-3-g800a261c036
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 $DIC;
58
59 $ilDB = $DIC['ilDB'];
60
61 /* see _recordReadEvent
62 if (!ilChangeEvent::_isActive())
63 {
64 return;
65 }
66 */
67
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'));
73
74 while ($prec = $ilDB->fetchAssoc($pset)) {
75 $nid = $ilDB->nextId("write_event");
76 $query = sprintf(
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')
85 );
86
87 $aff = $ilDB->manipulate($query);
88 }
89 } else {
90 $nid = $ilDB->nextId("write_event");
91 $query = sprintf(
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')
100 );
101 $aff = $ilDB->manipulate($query);
102 }
103 }
104
113 public static function _recordReadEvent(
114 $a_type,
115 $a_ref_id,
116 $obj_id,
117 $usr_id,
118 $isCatchupWriteEvents = true,
119 $a_ext_rc = false,
120 $a_ext_time = false
121 ) {
122 global $DIC;
123
124 $ilDB = $DIC['ilDB'];
125 $tree = $DIC['tree'];
126
127 /* read_event data is now used for several features, so we are always keeping track
128 if (!ilChangeEvent::_isActive())
129 {
130 return;
131 }
132 */
133
134 include_once('Services/Tracking/classes/class.ilObjUserTracking.php');
135 $validTimeSpan = ilObjUserTracking::_getValidTimeSpan();
136
137 $query = sprintf(
138 'SELECT * FROM read_event ' .
139 'WHERE obj_id = %s ' .
140 'AND usr_id = %s ',
141 $ilDB->quote($obj_id, 'integer'),
142 $ilDB->quote($usr_id, 'integer')
143 );
144 $res = $ilDB->query($query);
145 $row = $ilDB->fetchObject($res);
146
147 // read counter
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;
152 } else {
153 $read_count = 'read_count = read_count + 1, ';
154 $read_count_init = 1;
155 $read_count_diff = 1;
156 }
157
158 if ($row) {
159 if ($a_ext_time !== false) {
160 $time = (int) $a_ext_time;
161 } else {
162 $time = $ilDB->quote((time() - $row->last_access) <= $validTimeSpan
163 ? $row->spent_seconds + time() - $row->last_access
164 : $row->spent_seconds, 'integer');
165
166 // if we are in the valid interval, we do not
167 // add anything to the read_count, since this is the
168 // same access for us
169 if ((time() - $row->last_access) <= $validTimeSpan) {
170 $read_count = '';
171 $read_count_init = 1;
172 $read_count_diff = 0;
173 }
174 }
175 $time_diff = $time - (int) $row->spent_seconds;
176
177 // Update
178 $query = sprintf(
179 'UPDATE read_event SET ' .
180 $read_count .
181 'spent_seconds = %s, ' .
182 'last_access = %s ' .
183 'WHERE obj_id = %s ' .
184 'AND usr_id = %s ',
185 $time,
186 $ilDB->quote(time(), 'integer'),
187 $ilDB->quote($obj_id, 'integer'),
188 $ilDB->quote($usr_id, 'integer')
189 );
190 $aff = $ilDB->manipulate($query);
191
192 self::_recordObjStats($obj_id, $time_diff, $read_count_diff);
193 } else {
194 if ($a_ext_time !== false) {
195 $time = (int) $a_ext_time;
196 } else {
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(
215 'read_event',
216 array(
217 'obj_id' => array('integer', $obj_id),
218 'usr_id' => array('integer', $usr_id)
219 ),
220 array(
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")), // was $ilDB->now()
224 'last_access' => array('integer', time())
225 )
226 );
227
228 self::$has_accessed[$obj_id][$usr_id] = true;
229
230 self::_recordObjStats($obj_id, $time_diff, $read_count_diff);
231 }
232
233 if ($isCatchupWriteEvents) {
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 if ($tree->isInTree($a_ref_id)) {
240 $path = $tree->getPathId($a_ref_id);
241
242 foreach ($path as $p) {
243 $obj2_id = ilObject::_lookupObjId($p);
244 $obj2_type = ilObject::_lookupType($obj2_id);
245 //echo "<br>1-$obj2_type-$p-$obj2_id-";
246 if (($p != $a_ref_id) && (in_array($obj2_type, array("crs", "fold", "grp", "lso")))) {
247 $query = sprintf(
248 'SELECT * FROM read_event ' .
249 'WHERE obj_id = %s ' .
250 'AND usr_id = %s ',
251 $ilDB->quote($obj2_id, 'integer'),
252 $ilDB->quote($usr_id, 'integer')
253 );
254 $res2 = $ilDB->query($query);
255 if ($row2 = $ilDB->fetchAssoc($res2)) {
256 //echo "<br>2";
257 // update read count and spent seconds
258 $query = sprintf(
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 ' .
263 'AND usr_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')
268 );
269 $aff = $ilDB->manipulate($query);
270
271 self::_recordObjStats($obj2_id, null, null, (int) $time_diff, (int) $read_count_diff);
272 } else {
273 //echo "<br>3";
274 //$ilLog->write("insert read event for obj_id -".$obj2_id."-".$usr_id."-");
275 /*
276 $query = sprintf('INSERT INTO read_event (obj_id,usr_id,last_access,read_count,spent_seconds,first_access,'.
277 'childs_read_count, childs_spent_seconds) '.
278 'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().', %s, %s) ',
279 $ilDB->quote($obj2_id,'integer'),
280 $ilDB->quote($usr_id,'integer'),
281 $ilDB->quote(time(),'integer'),
282 $ilDB->quote(1,'integer'),
283 $ilDB->quote($time,'integer'),
284 $ilDB->quote((int) $read_count_diff,'integer'),
285 $ilDB->quote((int) $time_diff,'integer')
286 );
287 $aff = $ilDB->manipulate($query);
288 */
289
290 // #10407
291 $ilDB->replace(
292 'read_event',
293 array(
294 'obj_id' => array('integer', $obj2_id),
295 'usr_id' => array('integer', $usr_id)
296 ),
297 array(
298 'read_count' => array('integer', 1),
299 'spent_seconds' => array('integer', $time),
300 'first_access' => array('timestamp', date("Y-m-d H:i:s")), // was $ilDB->now()
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)
304 )
305 );
306
307 self::$has_accessed[$obj2_id][$usr_id] = true;
308
309 self::_recordObjStats($obj2_id, $time, 1, (int) $time_diff, (int) $read_count_diff);
310 }
311 }
312 }
313 }
314 }
315
316 // @todo:
317 // - calculate diff of spent_seconds and read_count
318 // - use ref id to get parents of types grp, crs, fold
319 // - add diffs to childs_spent_seconds and childs_read_count
320 }
321
322 public static function _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds = null, $a_child_read_count = null)
323 {
324 global $DIC;
325
326 $ilDB = $DIC['ilDB'];
327
329 (int) $a_obj_id <= 0) { // #12706
330 return;
331 }
332
333 $now = time();
334
335 $fields = array();
336 $fields['log_id'] = array("integer", $ilDB->nextId('obj_stat_log'));
337 $fields["obj_id"] = array("integer", $a_obj_id);
338 $fields["obj_type"] = array("text", ilObject::_lookupType($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);
346 }
347 if ($a_read_count > 0) {
348 $fields["read_count"] = array("integer", $a_read_count);
349 }
350 if ($a_childs_spent_seconds > 0) {
351 $fields["childs_spent_seconds"] = array("integer", $a_childs_spent_seconds);
352 }
353 if ($a_child_read_count > 0) {
354 $fields["childs_read_count"] = array("integer", $a_child_read_count);
355 }
356 $ilDB->insert("obj_stat_log", $fields);
357
358 // 0.01% probability
359 if (mt_rand(1, 100) == 1) {
361 }
362 }
363
370 public static function _syncObjectStats($a_now = null, $a_minimum = 20000)
371 {
372 global $DIC;
373
374 $ilDB = $DIC['ilDB'];
375
376 if (!$a_now) {
377 $a_now = time();
378 }
379
380 set_time_limit(0);
381
382 // has source table enough entries?
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');
389
390 $ilAtomQuery->addQueryCallable(function (ilDBInterface $ilDB) use ($a_now, $a_minimum, &$ret) {
391
392 // if other process was transferring, we had to wait for the lock and
393 // the source table should now have less than minimum/needed entries
394 $set = $ilDB->query("SELECT COUNT(*) AS counter FROM obj_stat_log");
395 $row = $ilDB->fetchAssoc($set);
396 if ($row["counter"] >= $a_minimum) {
397 // use only "full" seconds to have a clear cut
398 $ilDB->query("INSERT INTO obj_stat_tmp" .
399 " SELECT * FROM obj_stat_log" .
400 " WHERE tstamp < " . $ilDB->quote($a_now, "timestamp"));
401
402 // remove transferred entries from source table
403 $ilDB->query("DELETE FROM obj_stat_log" .
404 " WHERE tstamp < " . $ilDB->quote($a_now, "timestamp"));
405
406 $ret = true;
407 } else {
408 $ret = false;
409 }
410 });
411
412 $ilAtomQuery->run();
413
414 //continue only if obj_stat_log counter >= $a_minimum
415 if ($ret) {
416 $ilAtomQuery = $ilDB->buildAtomQuery();
417 $ilAtomQuery->addTableLock('obj_stat_tmp');
418 $ilAtomQuery->addTableLock('obj_stat');
419
420 $ilAtomQuery->addQueryCallable(function (ilDBInterface $ilDB) use ($a_now, $a_minimum) {
421
422 // process log data (timestamp is not needed anymore)
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)) {
430 // "primary key"
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"]));
437
438 $where_sql = array();
439 foreach ($where as $field => $def) {
440 $where_sql[] = $field . " = " . $ilDB->quote($def[1], $def[0]);
441 }
442 $where_sql = implode(" AND ", $where_sql);
443
444 // existing entry?
445 $check = $ilDB->query("SELECT read_count, childs_read_count, spent_seconds," .
446 "childs_spent_seconds" .
447 " FROM obj_stat" .
448 " WHERE " . $where_sql);
449 if ($ilDB->numRows($check)) {
450 $old = $ilDB->fetchAssoc($check);
451
452 // add existing values
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"]));
457
458 $ilDB->update("obj_stat", $fields, $where);
459 } else {
460 // new entry
461 $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"]);
466
467 $ilDB->insert("obj_stat", $fields);
468 }
469 }
470
471 // clean up transfer table
472 $ilDB->query("DELETE FROM obj_stat_tmp");
473 });
474
475 $ilAtomQuery->run();
476 }
477 }
478 }
479
488 public static function _catchupWriteEvents($obj_id, $usr_id, $timestamp = null)
489 {
490 global $DIC;
491
492 $ilDB = $DIC['ilDB'];
493
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');
497 $res = $ilDB->query($query);
498 if ($res->numRows()) {
499 $ts = ($timestamp == null)
500 ? ilUtil::now()
501 : $timestamp;
502 /* $query = "UPDATE catch_write_events ".
503 "SET ts = ".($timestamp == null ? $ilDB->now() : $ilDB->quote($timestamp, 'timestamp'))." ".
504 "WHERE usr_id = ".$ilDB->quote($usr_id ,'integer')." ".
505 "AND obj_id = ".$ilDB->quote($obj_id ,'integer');
506 $res = $ilDB->manipulate($query);*/
507 } else {
508 $ts = ilUtil::now();
509 /* $query = "INSERT INTO catch_write_events (ts,obj_id,usr_id) ".
510 "VALUES( ".
511 $ilDB->now().", ".
512 $ilDB->quote($obj_id,'integer').", ".
513 $ilDB->quote($usr_id,'integer')." ".
514 ")";
515 $res = $ilDB->manipulate($query);*/
516 }
517
518 // alex, use replace due to bug #10406
519 $ilDB->replace(
520 "catch_write_events",
521 array(
522 "obj_id" => array("integer", $obj_id),
523 "usr_id" => array("integer", $usr_id)
524 ),
525 array(
526 "ts" => array("timestamp", $ts))
527 );
528 }
529
579 public static function _lookupUncaughtWriteEvents($obj_id, $usr_id)
580 {
581 global $DIC;
582
583 $ilDB = $DIC['ilDB'];
584
585 $q = "SELECT 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);
590 $catchup = null;
591 while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
592 $catchup = $row['ts'];
593 }
594
595 if ($catchup == null) {
596 $query = sprintf(
597 'SELECT * FROM write_event ' .
598 'WHERE obj_id = %s ' .
599 'AND usr_id <> %s ' .
600 'ORDER BY ts DESC',
601 $ilDB->quote($obj_id, 'integer'),
602 $ilDB->quote($usr_id, 'integer')
603 );
604 $res = $ilDB->query($query);
605 } else {
606 $query = sprintf(
607 'SELECT * FROM write_event ' .
608 'WHERE obj_id = %s ' .
609 'AND usr_id <> %s ' .
610 'AND ts >= %s ' .
611 'ORDER BY ts DESC',
612 $ilDB->quote($obj_id, 'integer'),
613 $ilDB->quote($usr_id, 'integer'),
614 $ilDB->quote($catchup, 'timestamp')
615 );
616 $res = $ilDB->query($query);
617 }
618 $events = array();
619 while ($row = $ilDB->fetchAssoc($res)) {
620 $events[] = $row;
621 }
622 return $events;
623 }
634 public static function _lookupChangeState($obj_id, $usr_id)
635 {
636 global $DIC;
637
638 $ilDB = $DIC['ilDB'];
639
640 $q = "SELECT ts " .
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);
645 $catchup = null;
646 while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
647 $catchup = $row['ts'];
648 }
649
650 if ($catchup == null) {
651 $ilDB->setLimit(1);
652 $query = sprintf(
653 'SELECT * FROM write_event ' .
654 'WHERE obj_id = %s ' .
655 'AND usr_id <> %s ',
656 $ilDB->quote($obj_id, 'integer'),
657 $ilDB->quote($usr_id, 'integer')
658 );
659 $res = $ilDB->query($query);
660 } else {
661 $ilDB->setLimit(1);
662 $query = sprintf(
663 'SELECT * FROM write_event ' .
664 'WHERE obj_id = %s ' .
665 'AND usr_id <> %s ' .
666 'AND ts > %s ',
667 $ilDB->quote($obj_id, 'integer'),
668 $ilDB->quote($usr_id, 'integer'),
669 $ilDB->quote($catchup, 'timestamp')
670 );
671 $res = $ilDB->query($query);
672 }
673
674 $numRows = $res->numRows();
675 if ($numRows > 0) {
676 $row = $ilDB->fetchAssoc($res);
677 // if we have write events, and user never catched one, report as new (1)
678 // if we have write events, and user catched an old write event, report as changed (2)
679 return ($catchup == null) ? 1 : 2;
680 } else {
681 return 0; // user catched all write events, report as unchanged (0)
682 }
683 }
684
731 public static function _lookupReadEvents($obj_id, $usr_id = null)
732 {
733 global $DIC;
734
735 $ilDB = $DIC['ilDB'];
736
737 if ($usr_id == null) {
738 $query = sprintf(
739 'SELECT * FROM read_event ' .
740 'WHERE obj_id = %s ' .
741 'ORDER BY last_access DESC',
742 $ilDB->quote($obj_id, 'integer')
743 );
744 $res = $ilDB->query($query);
745 } else {
746 $query = sprintf(
747 'SELECT * FROM read_event ' .
748 'WHERE obj_id = %s ' .
749 'AND usr_id = %s ' .
750 'ORDER BY last_access DESC',
751 $ilDB->quote($obj_id, 'integer'),
752 $ilDB->quote($usr_id, 'integer')
753 );
754 $res = $ilDB->query($query);
755 }
756
757 $counter = 0;
758 while ($row = $ilDB->fetchAssoc($res)) {
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'];
765
766 $counter++;
767 }
768 return $events ? $events : array();
769 }
770
777 public static function lookupUsersInProgress($a_obj_id)
778 {
779 global $DIC;
780
781 $ilDB = $DIC['ilDB'];
782
783 $query = sprintf(
784 'SELECT DISTINCT(usr_id) usr FROM read_event ' .
785 'WHERE obj_id = %s ',
786 $ilDB->quote($a_obj_id, 'integer')
787 );
788 $res = $ilDB->query($query);
789 while ($row = $ilDB->fetchObject($res)) {
790 $users[] = $row->usr;
791 }
792 return $users ? $users : array();
793 }
794
798 public static function hasAccessed($a_obj_id, $a_usr_id)
799 {
800 global $DIC;
801
802 $ilDB = $DIC['ilDB'];
803
804 if (isset(self::$has_accessed[$a_obj_id][$a_usr_id])) {
805 return self::$has_accessed[$a_obj_id][$a_usr_id];
806 }
807
808 $set = $ilDB->query(
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")
812 );
813 if ($rec = $ilDB->fetchAssoc($set)) {
814 return self::$has_accessed[$a_obj_id][$a_usr_id] = true;
815 }
816 return self::$has_accessed[$a_obj_id][$a_usr_id] = false;
817 }
818
824 public static function _activate()
825 {
827 return 'change event tracking is already active';
828 } else {
829 global $DIC;
830
831 $ilDB = $DIC['ilDB'];
832
833 // Insert initial data into table write_event
834 // We need to do this here, because we need
835 // to catch up write events that occured while the change event tracking was
836 // deactivated.
837
838 // IGNORE isn't supported in oracle
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')
848 ));
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") .
859 ')';
860 $res = $ilDB->query($query);
861 }
862
863 global $DIC;
864
865 $ilSetting = $DIC['ilSetting'];
866 $ilSetting->set('enable_change_event_tracking', '1');
867
868 return $res;
869 }
870 }
871
877 public static function _deactivate()
878 {
879 global $DIC;
880
881 $ilSetting = $DIC['ilSetting'];
882 $ilSetting->set('enable_change_event_tracking', '0');
883 }
884
890 public static function _isActive()
891 {
892 global $DIC;
893
894 $ilSetting = $DIC['ilSetting'];
895 return $ilSetting->get('enable_change_event_tracking', '0') == '1';
896 }
897
904 public static function _delete($a_obj_id)
905 {
906 global $DIC;
907
908 $ilDB = $DIC['ilDB'];
909
910 $query = sprintf(
911 'DELETE FROM write_event WHERE obj_id = %s ',
912 $ilDB->quote($a_obj_id, 'integer')
913 );
914 $aff = $ilDB->manipulate($query);
915
916 $query = sprintf(
917 'DELETE FROM read_event WHERE obj_id = %s ',
918 $ilDB->quote($a_obj_id, 'integer')
919 );
920 $aff = $ilDB->manipulate($query);
921 return true;
922 }
923
924 public static function _deleteReadEvents($a_obj_id)
925 {
926 global $DIC;
927
928 $ilDB = $DIC['ilDB'];
929
930 $ilDB->manipulate("DELETE FROM read_event" .
931 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer"));
932 }
933
934 public static function _deleteReadEventsForUsers($a_obj_id, array $a_user_ids)
935 {
936 global $DIC;
937
938 $ilDB = $DIC['ilDB'];
939
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"));
943 }
944
945 public static function _getAllUserIds($a_obj_id)
946 {
947 global $DIC;
948
949 $ilDB = $DIC['ilDB'];
950
951 $res = array();
952
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"];
957 }
958
959 return $res;
960 }
961
968 public static function _updateAccessForScormOfflinePlayer($obj_id, $usr_id, $i_last_access, $t_first_access)
969 {
970 global $DIC;
971
972 $ilDB = $DIC['ilDB'];
973 $res = $ilDB->queryF(
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)
977 );
978 return $res;
979 }
980}
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.
global $DIC
Definition: goto.php:24
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$ret
Definition: parser.php:6
global $ilSetting
Definition: privfeed.php:17
$query
foreach($_POST as $key=> $value) $res
global $ilDB