ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilChangeEvent.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=0);
44{
45 private static array $has_accessed = [];
46
61 public static function _recordWriteEvent(
62 int $obj_id,
63 int $usr_id,
64 string $action,
65 ?int $parent_obj_id = null
66 ): void {
67 global $DIC;
68
69 $ilDB = $DIC['ilDB'];
70
71 /* see _recordReadEvent
72 if (!ilChangeEvent::_isActive())
73 {
74 return;
75 }
76 */
77
78 if ($parent_obj_id == null) {
79 $pset = $ilDB->query(
80 'SELECT r2.obj_id par_obj_id FROM object_reference r1 ' .
81 'JOIN tree t ON t.child = r1.ref_id ' .
82 'JOIN object_reference r2 ON r2.ref_id = t.parent ' .
83 'WHERE r1.obj_id = ' . $ilDB->quote($obj_id, 'integer')
84 );
85
86 while ($prec = $ilDB->fetchAssoc($pset)) {
87 $nid = $ilDB->nextId("write_event");
88 $query = sprintf(
89 'INSERT INTO write_event ' .
90 '(write_id, obj_id, parent_obj_id, usr_id, action, ts) VALUES ' .
91 '(%s, %s, %s, %s, %s, ' . $ilDB->now() . ')',
92 $ilDB->quote($nid, 'integer'),
93 $ilDB->quote($obj_id, 'integer'),
94 $ilDB->quote($prec["par_obj_id"], 'integer'),
95 $ilDB->quote($usr_id, 'integer'),
96 $ilDB->quote($action, 'text')
97 );
98
99 $aff = $ilDB->manipulate($query);
100 }
101 } else {
102 $nid = $ilDB->nextId("write_event");
103 $query = sprintf(
104 'INSERT INTO write_event ' .
105 '(write_id, obj_id, parent_obj_id, usr_id, action, ts) ' .
106 'VALUES (%s,%s,%s,%s,%s,' . $ilDB->now() . ')',
107 $ilDB->quote($nid, 'integer'),
108 $ilDB->quote($obj_id, 'integer'),
109 $ilDB->quote($parent_obj_id, 'integer'),
110 $ilDB->quote($usr_id, 'integer'),
111 $ilDB->quote($action, 'text')
112 );
113 $aff = $ilDB->manipulate($query);
114 }
115 }
116
117 public static function _recordReadEvent(
118 string $a_type,
119 int $a_ref_id,
120 int $obj_id,
121 int $usr_id,
122 bool $isCatchupWriteEvents = true,
123 $a_ext_rc = null,
124 $a_ext_time = null
125 ): void {
126 global $DIC;
127
128 $ilDB = $DIC['ilDB'];
129 $tree = $DIC['tree'];
130
131 $validTimeSpan = ilObjUserTracking::_getValidTimeSpan();
132
133 $query = sprintf(
134 'SELECT * FROM read_event ' .
135 'WHERE obj_id = %s ' .
136 'AND usr_id = %s ',
137 $ilDB->quote($obj_id, 'integer'),
138 $ilDB->quote($usr_id, 'integer')
139 );
140 $res = $ilDB->query($query);
141 $row = $ilDB->fetchObject($res);
142
143 // read counter
144 if ($a_ext_rc !== null) {
145 $read_count = 'read_count = ' . $ilDB->quote(
146 $a_ext_rc,
147 "integer"
148 ) . ", ";
149 $read_count_init = max(1, (int) $a_ext_rc);
150 $read_count_diff = max(1, (int) $a_ext_rc) - (int) ($row?->read_count ?? 0);
151 } else {
152 $read_count = 'read_count = read_count + 1, ';
153 $read_count_init = 1;
154 $read_count_diff = 1;
155 }
156
157 if ($row) {
158 if ($a_ext_time !== null) {
159 $time = (int) $a_ext_time;
160 } else {
161 $time = $ilDB->quote(
162 (time() - $row->last_access) <= $validTimeSpan
163 ? $row->spent_seconds + time() - $row->last_access
164 : $row->spent_seconds,
165 'integer'
166 );
167
168 // if we are in the valid interval, we do not
169 // add anything to the read_count, since this is the
170 // same access for us
171 if ((time() - $row->last_access) <= $validTimeSpan) {
172 $read_count = '';
173 $read_count_init = 1;
174 $read_count_diff = 0;
175 }
176 }
177 $time_diff = $time - (int) ($row->spent_seconds ?? 0);
178
179 // Update
180 $query = sprintf(
181 'UPDATE read_event SET ' .
182 $read_count .
183 'spent_seconds = %s, ' .
184 'last_access = %s ' .
185 'WHERE obj_id = %s ' .
186 'AND usr_id = %s ',
187 $time,
188 $ilDB->quote(time(), 'integer'),
189 $ilDB->quote($obj_id, 'integer'),
190 $ilDB->quote($usr_id, 'integer')
191 );
192 $aff = $ilDB->manipulate($query);
193
194 self::_recordObjStats($obj_id, $time_diff, $read_count_diff);
195 } else {
196 if ($a_ext_time !== false) {
197 $time = (int) $a_ext_time;
198 } else {
199 $time = 0;
200 }
201
202 $time_diff = $time - (int) ($row->spent_seconds ?? 0);
203
204 // #10407
205 $ilDB->replace(
206 'read_event',
207 array(
208 'obj_id' => array('integer', $obj_id),
209 'usr_id' => array('integer', $usr_id)
210 ),
211 array(
212 'read_count' => array('integer', $read_count_init),
213 'spent_seconds' => array('integer', $time),
214 'first_access' => array('timestamp', date("Y-m-d H:i:s")),
215 // was $ilDB->now()
216 'last_access' => array('integer', time())
217 )
218 );
219
220 self::$has_accessed[$obj_id][$usr_id] = true;
221
222 self::_recordObjStats($obj_id, $time_diff, $read_count_diff);
223 }
224
225 if ($isCatchupWriteEvents) {
226 ilChangeEvent::_catchupWriteEvents($obj_id, $usr_id);
227 }
228
229 // update parents (no categories or root)
230 if (!in_array($a_type, array("cat", "root", "crs"))) {
231 if ($tree->isInTree($a_ref_id)) {
232 $path = $tree->getPathId($a_ref_id);
233
234 foreach ($path as $p) {
235 $obj2_id = ilObject::_lookupObjId($p);
236 $obj2_type = ilObject::_lookupType($obj2_id);
237 //echo "<br>1-$obj2_type-$p-$obj2_id-";
238 if (($p != $a_ref_id) && (in_array(
239 $obj2_type,
240 array("crs",
241 "fold",
242 "grp",
243 "lso"
244 )
245 ))) {
246 $query = sprintf(
247 'SELECT * FROM read_event ' .
248 'WHERE obj_id = %s ' .
249 'AND usr_id = %s ',
250 $ilDB->quote($obj2_id, 'integer'),
251 $ilDB->quote($usr_id, 'integer')
252 );
253 $res2 = $ilDB->query($query);
254 if ($row2 = $ilDB->fetchAssoc($res2)) {
255 //echo "<br>2";
256 // update read count and spent seconds
257 $query = sprintf(
258 'UPDATE read_event SET ' .
259 'childs_read_count = childs_read_count + %s ,' .
260 'childs_spent_seconds = childs_spent_seconds + %s ' .
261 'WHERE obj_id = %s ' .
262 'AND usr_id = %s ',
263 $ilDB->quote((int) $read_count_diff, 'integer'),
264 $ilDB->quote((int) $time_diff, 'integer'),
265 $ilDB->quote($obj2_id, 'integer'),
266 $ilDB->quote($usr_id, 'integer')
267 );
268 $aff = $ilDB->manipulate($query);
269
270 self::_recordObjStats(
271 $obj2_id,
272 null,
273 null,
274 (int) $time_diff,
275 (int) $read_count_diff
276 );
277 } else {
278 // #10407
279 $ilDB->replace(
280 'read_event',
281 array(
282 'obj_id' => array('integer', $obj2_id),
283 'usr_id' => array('integer', $usr_id)
284 ),
285 array(
286 'read_count' => array('integer', 1),
287 'spent_seconds' => array('integer', $time),
288 'first_access' => array('timestamp',
289 date("Y-m-d H:i:s")
290 ), // was $ilDB->now()
291 'last_access' => array('integer', time()),
292 'childs_read_count' => array('integer',
293 (int) $read_count_diff
294 ),
295 'childs_spent_seconds' => array('integer',
296 (int) $time_diff
297 )
298 )
299 );
300
301 self::$has_accessed[$obj2_id][$usr_id] = true;
302
303 self::_recordObjStats(
304 $obj2_id,
305 $time,
306 1,
307 (int) $time_diff,
308 (int) $read_count_diff
309 );
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(
323 int $a_obj_id,
324 ?int $a_spent_seconds,
325 ?int $a_read_count,
326 ?int $a_childs_spent_seconds = null,
327 ?int $a_child_read_count = null
328 ): void {
329 global $DIC;
330
331 $ilDB = $DIC['ilDB'];
332
334 $a_obj_id <= 0) { // #12706
335 return;
336 }
337
338 $now = time();
339
340 $fields = array();
341 $fields['log_id'] = array("integer", $ilDB->nextId('obj_stat_log'));
342 $fields["obj_id"] = array("integer", $a_obj_id);
343 $fields["obj_type"] = array("text", ilObject::_lookupType($a_obj_id));
344 $fields["tstamp"] = array("timestamp", $now);
345 $fields["yyyy"] = array("integer", date("Y"));
346 $fields["mm"] = array("integer", date("m"));
347 $fields["dd"] = array("integer", date("d"));
348 $fields["hh"] = array("integer", date("H"));
349 if ($a_spent_seconds > 0) {
350 $fields["spent_seconds"] = array("integer", $a_spent_seconds);
351 }
352 if ($a_read_count > 0) {
353 $fields["read_count"] = array("integer", $a_read_count);
354 }
355 if ($a_childs_spent_seconds > 0) {
356 $fields["childs_spent_seconds"] = array("integer",
357 $a_childs_spent_seconds
358 );
359 }
360 if ($a_child_read_count > 0) {
361 $fields["childs_read_count"] = array("integer",
362 $a_child_read_count
363 );
364 }
365 $ilDB->insert("obj_stat_log", $fields);
366
367 // 0.01% probability
368 if (mt_rand(1, 100) == 1) {
369 self::_syncObjectStats($now);
370 }
371 }
372
373 public static function _syncObjectStats(
374 ?int $a_now = null,
375 int $a_minimum = 20000
376 ) {
377 global $DIC;
378
379 $ilDB = $DIC['ilDB'];
380
381 if (!$a_now) {
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 $ilAtomQuery = $ilDB->buildAtomQuery();
392 $ilAtomQuery->addTableLock('obj_stat_log');
393 $ilAtomQuery->addTableLock('obj_stat_tmp');
394
395 $ilAtomQuery->addQueryCallable(
396 function (ilDBInterface $ilDB) use ($a_now, $a_minimum, &$ret) {
397 // if other process was transferring, we had to wait for the lock and
398 // the source table should now have less than minimum/needed entries
399 $set = $ilDB->query(
400 "SELECT COUNT(*) AS counter FROM obj_stat_log"
401 );
402 $row = $ilDB->fetchAssoc($set);
403 if ($row["counter"] >= $a_minimum) {
404 // use only "full" seconds to have a clear cut
405 $ilDB->query(
406 "INSERT INTO obj_stat_tmp" .
407 " SELECT * FROM obj_stat_log" .
408 " WHERE tstamp < " . $ilDB->quote(
409 $a_now,
410 "timestamp"
411 )
412 );
413
414 // remove transferred entries from source table
415 $ilDB->query(
416 "DELETE FROM obj_stat_log" .
417 " WHERE tstamp < " . $ilDB->quote(
418 $a_now,
419 "timestamp"
420 )
421 );
422
423 $ret = true;
424 } else {
425 $ret = false;
426 }
427 }
428 );
429
430 $ilAtomQuery->run();
431
432 //continue only if obj_stat_log counter >= $a_minimum
433 if ($ret) {
434 $ilAtomQuery = $ilDB->buildAtomQuery();
435 $ilAtomQuery->addTableLock('obj_stat_tmp');
436 $ilAtomQuery->addTableLock('obj_stat');
437
438 $ilAtomQuery->addQueryCallable(
439 function (ilDBInterface $ilDB) use ($a_now, $a_minimum) {
440 // process log data (timestamp is not needed anymore)
441 $sql = "SELECT obj_id, obj_type, yyyy, mm, dd, hh, SUM(read_count) AS read_count," .
442 " SUM(childs_read_count) AS childs_read_count, SUM(spent_seconds) AS spent_seconds," .
443 " SUM(childs_spent_seconds) AS childs_spent_seconds" .
444 " FROM obj_stat_tmp" .
445 " GROUP BY obj_id, obj_type, yyyy, mm, dd, hh";
446 $set = $ilDB->query($sql);
447 while ($row = $ilDB->fetchAssoc($set)) {
448 // "primary key"
449 $where = array("obj_id" => array("integer",
450 $row["obj_id"]
451 ),
452 "obj_type" => array("text",
453 $row["obj_type"]
454 ),
455 "yyyy" => array("integer",
456 $row["yyyy"]
457 ),
458 "mm" => array("integer", $row["mm"]),
459 "dd" => array("integer", $row["dd"]),
460 "hh" => array("integer", $row["hh"])
461 );
462
463 $where_sql = array();
464 foreach ($where as $field => $def) {
465 $where_sql[] = $field . " = " . $ilDB->quote(
466 $def[1],
467 $def[0]
468 );
469 }
470 $where_sql = implode(" AND ", $where_sql);
471
472 // existing entry?
473 $check = $ilDB->query(
474 "SELECT read_count, childs_read_count, spent_seconds," .
475 "childs_spent_seconds" .
476 " FROM obj_stat" .
477 " WHERE " . $where_sql
478 );
479 if ($ilDB->numRows($check)) {
480 $old = $ilDB->fetchAssoc($check);
481
482 // add existing values
483 $fields = array("read_count" => array("integer",
484 $old["read_count"] + $row["read_count"]
485 ),
486 "childs_read_count" => array("integer",
487 $old["childs_read_count"] + $row["childs_read_count"]
488 ),
489 "spent_seconds" => array("integer",
490 $old["spent_seconds"] + $row["spent_seconds"]
491 ),
492 "childs_spent_seconds" => array("integer",
493 $old["childs_spent_seconds"] + $row["childs_spent_seconds"]
494 )
495 );
496
497 $ilDB->update("obj_stat", $fields, $where);
498 } else {
499 // new entry
500 $fields = $where;
501 $fields["read_count"] = array("integer",
502 $row["read_count"]
503 );
504 $fields["childs_read_count"] = array("integer",
505 $row["childs_read_count"]
506 );
507 $fields["spent_seconds"] = array("integer",
508 $row["spent_seconds"]
509 );
510 $fields["childs_spent_seconds"] = array("integer",
511 $row["childs_spent_seconds"]
512 );
513
514 $ilDB->insert("obj_stat", $fields);
515 }
516 }
517
518 // clean up transfer table
519 $ilDB->query("DELETE FROM obj_stat_tmp");
520 }
521 );
522
523 $ilAtomQuery->run();
524 }
525 }
526 }
527
540 public static function _catchupWriteEvents(
541 int $obj_id,
542 int $usr_id,
543 ?string $timestamp = null
544 ): void {
545 }
546
558 public static function _lookupUncaughtWriteEvents(
559 int $obj_id,
560 int $usr_id
561 ): array {
562 return [];
563 }
564
578 public static function _lookupChangeState(int $obj_id, int $usr_id): int
579 {
580 return 0;
581 }
582
588 public static function _lookupReadEvents($obj_id, $usr_id = null)
589 {
590 global $DIC;
591
592 $ilDB = $DIC['ilDB'];
593
594 if ($usr_id == null) {
595 $query = sprintf(
596 'SELECT * FROM read_event ' .
597 'WHERE obj_id = %s ' .
598 'ORDER BY last_access DESC',
599 $ilDB->quote($obj_id, 'integer')
600 );
601 $res = $ilDB->query($query);
602 } else {
603 $query = sprintf(
604 'SELECT * FROM read_event ' .
605 'WHERE obj_id = %s ' .
606 'AND usr_id = %s ' .
607 'ORDER BY last_access DESC',
608 $ilDB->quote($obj_id, 'integer'),
609 $ilDB->quote($usr_id, 'integer')
610 );
611 $res = $ilDB->query($query);
612 }
613
614 $counter = 0;
615 $events = [];
616 while ($row = $ilDB->fetchAssoc($res)) {
617 $events[$counter]['obj_id'] = $row['obj_id'];
618 $events[$counter]['usr_id'] = $row['usr_id'];
619 $events[$counter]['last_access'] = $row['last_access'];
620 $events[$counter]['read_count'] = $row['read_count'];
621 $events[$counter]['spent_seconds'] = $row['spent_seconds'];
622 $events[$counter]['first_access'] = $row['first_access'];
623
624 $counter++;
625 }
626 return $events;
627 }
628
629 public static function lookupUsersInProgress(int $a_obj_id): array
630 {
631 global $DIC;
632
633 $ilDB = $DIC['ilDB'];
634
635 $query = sprintf(
636 'SELECT DISTINCT(usr_id) usr FROM read_event ' .
637 'WHERE obj_id = %s ',
638 $ilDB->quote($a_obj_id, 'integer')
639 );
640 $res = $ilDB->query($query);
641 $users = [];
642 while ($row = $ilDB->fetchObject($res)) {
643 $users[] = (int) $row->usr;
644 }
645 return $users;
646 }
647
651 public static function hasAccessed(int $a_obj_id, int $a_usr_id): bool
652 {
653 global $DIC;
654
655 $ilDB = $DIC['ilDB'];
656
657 if (isset(self::$has_accessed[$a_obj_id][$a_usr_id])) {
658 return self::$has_accessed[$a_obj_id][$a_usr_id];
659 }
660
661 $set = $ilDB->query(
662 "SELECT usr_id FROM read_event WHERE " .
663 "obj_id = " . $ilDB->quote($a_obj_id, "integer") . " AND " .
664 "usr_id = " . $ilDB->quote($a_usr_id, "integer")
665 );
666 if ($rec = $ilDB->fetchAssoc($set)) {
667 return self::$has_accessed[$a_obj_id][$a_usr_id] = true;
668 }
669 return self::$has_accessed[$a_obj_id][$a_usr_id] = false;
670 }
671
675 public static function _activate(): bool
676 {
678 return false;
679 } else {
680 global $DIC;
681
682 $ilDB = $DIC['ilDB'];
683
684 // Insert initial data into table write_event
685 // We need to do this here, because we need
686 // to catch up write events that occured while the change event tracking was
687 // deactivated.
688
689 // IGNORE isn't supported in oracle
690 $set = $ilDB->query(
691 sprintf(
692 'SELECT r1.obj_id,r2.obj_id p,d.owner,%s,d.create_date ' .
693 'FROM object_data d ' .
694 'LEFT JOIN write_event w ON d.obj_id = w.obj_id ' .
695 'JOIN object_reference r1 ON d.obj_id=r1.obj_id ' .
696 'JOIN tree t ON t.child=r1.ref_id ' .
697 'JOIN object_reference r2 on r2.ref_id=t.parent ' .
698 'WHERE w.obj_id IS NULL',
699 $ilDB->quote('create', 'text')
700 )
701 );
702 $res = null;
703 while ($rec = $ilDB->fetchAssoc($set)) {
704 $nid = $ilDB->nextId("write_event");
705 $query = 'INSERT INTO write_event ' .
706 '(write_id, obj_id,parent_obj_id,usr_id,action,ts) VALUES (' .
707 $ilDB->quote($nid, "integer") . "," .
708 $ilDB->quote($rec["obj_id"], "integer") . "," .
709 $ilDB->quote($rec["p"], "integer") . "," .
710 $ilDB->quote($rec["owner"], "integer") . "," .
711 $ilDB->quote("create", "text") . "," .
712 $ilDB->quote($rec["create_date"], "timestamp") .
713 ')';
714 $res = $ilDB->query($query);
715 }
716
717 global $DIC;
718
719 $ilSetting = $DIC['ilSetting'];
720 $ilSetting->set('enable_change_event_tracking', '1');
721
722 return $res !== null;
723 }
724 }
725
729 public static function _deactivate(): bool
730 {
731 global $DIC;
732
733 $ilSetting = $DIC['ilSetting'];
734 $ilSetting->set('enable_change_event_tracking', '0');
735 return true;
736 }
737
741 public static function _isActive(): bool
742 {
743 global $DIC;
744
745 $ilSetting = $DIC['ilSetting'];
746 return $ilSetting->get('enable_change_event_tracking', '0') == '1';
747 }
748
752 public static function _delete(int $a_obj_id): bool
753 {
754 global $DIC;
755
756 $ilDB = $DIC['ilDB'];
757 $query = sprintf(
758 'DELETE FROM write_event WHERE obj_id = %s ',
759 $ilDB->quote($a_obj_id, 'integer')
760 );
761 $aff = $ilDB->manipulate($query);
762
763 $query = sprintf(
764 'DELETE FROM read_event WHERE obj_id = %s ',
765 $ilDB->quote($a_obj_id, 'integer')
766 );
767 $aff = $ilDB->manipulate($query);
768 return true;
769 }
770
771 public static function _deleteReadEvents(int $a_obj_id): void
772 {
773 global $DIC;
774
775 $ilDB = $DIC['ilDB'];
776
777 $ilDB->manipulate(
778 "DELETE FROM read_event" .
779 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer")
780 );
781 }
782
783 public static function _deleteReadEventsForUsers(
784 int $a_obj_id,
785 array $a_user_ids
786 ): void {
787 global $DIC;
788
789 $ilDB = $DIC['ilDB'];
790
791 $ilDB->manipulate(
792 "DELETE FROM read_event" .
793 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer") .
794 " AND " . $ilDB->in("usr_id", $a_user_ids, "", "integer")
795 );
796 }
797
798 public static function _getAllUserIds(int $a_obj_id): array
799 {
800 global $DIC;
801
802 $ilDB = $DIC['ilDB'];
803 $res = array();
804 $set = $ilDB->query(
805 "SELECT usr_id FROM read_event" .
806 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer")
807 );
808 while ($row = $ilDB->fetchAssoc($set)) {
809 $res[] = (int) $row["usr_id"];
810 }
811 return $res;
812 }
813
820 int $obj_id,
821 int $usr_id,
822 int $i_last_access,
823 string $t_first_access
824 ): bool {
825 global $DIC;
826
827 $ilDB = $DIC->database();
828 $res = $ilDB->queryF(
829 'UPDATE read_event SET first_access=%s, last_access = %s WHERE obj_id=%s AND usr_id=%s',
830 array('timestamp', 'integer', 'integer', 'integer'),
831 array($t_first_access, $i_last_access, $obj_id, $usr_id)
832 );
833 return true;
834 }
835}
$check
Definition: buildRTE.php:81
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:70
Class ilChangeEvent tracks change events on repository objects.
static _deleteReadEvents(int $a_obj_id)
static _updateAccessForScormOfflinePlayer(int $obj_id, int $usr_id, int $i_last_access, string $t_first_access)
_updateAccessForScormOfflinePlayer needed to synchronize last_access and first_access when learning m...
static _syncObjectStats(?int $a_now=null, int $a_minimum=20000)
static _recordReadEvent(string $a_type, int $a_ref_id, int $obj_id, int $usr_id, bool $isCatchupWriteEvents=true, $a_ext_rc=null, $a_ext_time=null)
static _lookupReadEvents($obj_id, $usr_id=null)
Reads all read events which occured on the object.
static _isActive()
Returns true, if change event tracking is active.
static hasAccessed(int $a_obj_id, int $a_usr_id)
Has accessed.
static _deleteReadEventsForUsers(int $a_obj_id, array $a_user_ids)
static array $has_accessed
static _activate()
Activates change event tracking.
static _lookupChangeState(int $obj_id, int $usr_id)
Returns the change state of the object for the specified user.
static _deactivate()
Deactivates change event tracking.
static lookupUsersInProgress(int $a_obj_id)
static _recordObjStats(int $a_obj_id, ?int $a_spent_seconds, ?int $a_read_count, ?int $a_childs_spent_seconds=null, ?int $a_child_read_count=null)
static _catchupWriteEvents(int $obj_id, int $usr_id, ?string $timestamp=null)
Catches up with all write events which occured before the specified timestamp.
static _delete(int $a_obj_id)
Delete object entries.
static _getAllUserIds(int $a_obj_id)
static _recordWriteEvent(int $obj_id, int $usr_id, string $action, ?int $parent_obj_id=null)
Records a write event.
static _lookupType(int $id, bool $reference=false)
static _lookupObjId(int $ref_id)
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface ilDBInterface.
$path
Definition: ltiservices.php:30
$res
Definition: ltiservices.php:69
global $ilSetting
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26
$counter