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  {
366  self::_syncObjectStats($now);
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 ?>
static hasAccessed($a_obj_id, $a_usr_id)
Has accessed.
$path
Definition: aliased.php:25
static _activate()
Activates change event tracking.
static _enabledObjectStatistics()
check wether object statistics is enabled or not
static _recordWriteEvent($obj_id, $usr_id, $action, $parent_obj_id=null)
Records a write event.
static _deleteReadEvents($a_obj_id)
static _getAllUserIds($a_obj_id)
static now()
Return current timestamp in Y-m-d H:i:s format.
update($table_name, $values, $where)
static _catchupWriteEvents($obj_id, $usr_id, $timestamp=null)
Catches up with all write events which occured before the specified timestamp.
numRows($query_result)
$counter
Interface ilDBInterface.
$a_type
Definition: workflow.php:93
$time_diff
Definition: langcheck.php:760
quote($value, $type)
static _delete($a_obj_id)
Delete object entries.
$r
Definition: example_031.php:79
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 _lookupObjId($a_id)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
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.
$old
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 ...
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
static _lookupUncaughtWriteEvents($obj_id, $usr_id)
Catches up with all write events which occured before the specified timestamp.
Class ilChangeEvent tracks change events on repository objects.
global $ilSetting
Definition: privfeed.php:17
static _deleteReadEventsForUsers($a_obj_id, array $a_user_ids)
static _isActive()
Returns true, if change event tracking is active.
static _deactivate()
Deactivates change event tracking.
global $ilDB
$ret
Definition: parser.php:6
query($query)
static _recordObjStats($a_obj_id, $a_spent_seconds, $a_read_count, $a_childs_spent_seconds=null, $a_child_read_count=null)
insert($table_name, $values)
fetchAssoc($query_result)
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
static _syncObjectStats($a_now=null, $a_minimum=20000)
Process object statistics log data.
static _lookupChangeState($obj_id, $usr_id)
Returns the change state of the object for the specified user.
static lookupUsersInProgress($a_obj_id)
Lookup users in progress.