ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilChangeEvent.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2007 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
56 {
72  function _recordWriteEvent($obj_id, $usr_id, $action, $parent_obj_id = null)
73  {
74  global $ilDB;
75 
76  if ($parent_obj_id == null)
77  {
78  $pset = $ilDB->query('SELECT r2.obj_id par_obj_id FROM object_reference r1 '.
79  'JOIN tree t ON t.child = r1.ref_id '.
80  'JOIN object_reference r2 ON r2.ref_id = t.parent '.
81  'WHERE r1.obj_id = '.$ilDB->quote($obj_id,'integer'));
82 
83  while ($prec = $ilDB->fetchAssoc($pset))
84  {
85  $nid = $ilDB->nextId("write_event");
86  $query = sprintf('INSERT INTO write_event '.
87  '(write_id, obj_id, parent_obj_id, usr_id, action, ts) VALUES '.
88  '(%s, %s, %s, %s, %s, '.$ilDB->now().')',
89  $ilDB->quote($nid,'integer'),
90  $ilDB->quote($obj_id,'integer'),
91  $ilDB->quote($prec["par_obj_id"],'integer'),
92  $ilDB->quote($usr_id,'integer'),
93  $ilDB->quote($action,'text'));
94 
95  $aff = $ilDB->manipulate($query);
96  }
97  }
98  else
99  {
100  $nid = $ilDB->nextId("write_event");
101  $query = sprintf('INSERT INTO write_event '.
102  '(write_id, obj_id, parent_obj_id, usr_id, action, ts) '.
103  'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().')',
104  $ilDB->quote($nid,'integer'),
105  $ilDB->quote($obj_id,'integer'),
106  $ilDB->quote($parent_obj_id,'integer'),
107  $ilDB->quote($usr_id,'integer'),
108  $ilDB->quote($action,'text'));
109  $aff = $ilDB->manipulate($query);
110 
111  }
112  //error_log ('ilChangeEvent::_recordWriteEvent '.$q);
113  }
114 
123  function _recordReadEvent($obj_id, $usr_id, $isCatchupWriteEvents = true)
124  {
125  global $ilDB;
126 
127  include_once('Services/Tracking/classes/class.ilObjUserTracking.php');
128  $validTimeSpan = ilObjUserTracking::_getValidTimeSpan();
129 
130 
131  $query = sprintf('SELECT * FROM read_event '.
132  'WHERE obj_id = %s '.
133  'AND usr_id = %s ',
134  $ilDB->quote($obj_id,'integer'),
135  $ilDB->quote($usr_id,'integer'));
136  $res = $ilDB->query($query);
137 
138  if($res->numRows())
139  {
140  $row = $ilDB->fetchObject($res);
141  // Update
142  $query = sprintf('UPDATE read_event SET '.
143  'read_count = read_count + 1, '.
144  'spent_seconds = %s, '.
145  'last_access = %s '.
146  'WHERE obj_id = %s '.
147  'AND usr_id = %s ',
148  $ilDB->quote((time() - $row->last_access) <= $validTimeSpan ? $row->spent_seconds + time() - $row->last_access : $row->spent_seconds,'integer'),
149  $ilDB->quote(time(),'integer'),
150  $ilDB->quote($obj_id,'integer'),
151  $ilDB->quote($usr_id,'integer'));
152  $aff = $ilDB->manipulate($query);
153  }
154  else
155  {
156  $query = sprintf('INSERT INTO read_event (obj_id,usr_id,last_access,read_count,spent_seconds,first_access) '.
157  'VALUES (%s,%s,%s,%s,%s,'.$ilDB->now().') ',
158  $ilDB->quote($obj_id,'integer'),
159  $ilDB->quote($usr_id,'integer'),
160  $ilDB->quote(time(),'integer'),
161  $ilDB->quote(1,'integer'),
162  $ilDB->quote(0,'integer'));
163 
164  $aff = $ilDB->manipulate($query);
165  }
166 
167  if ($isCatchupWriteEvents)
168  {
170  }
171  }
172 
181  function _catchupWriteEvents($obj_id, $usr_id, $timestamp = null)
182  {
183  global $ilDB;
184 
185  $query = "SELECT obj_id FROM catch_write_events ".
186  "WHERE obj_id = ".$ilDB->quote($obj_id ,'integer')." ".
187  "AND usr_id = ".$ilDB->quote($usr_id ,'integer');
188  $res = $ilDB->query($query);
189  if($res->numRows())
190  {
191  $query = "UPDATE catch_write_events ".
192  "SET ts = ".($timestamp == null ? $ilDB->now() : $ilDB->quote($timestamp, 'timestamp'))." ".
193  "WHERE usr_id = ".$ilDB->quote($usr_id ,'integer')." ".
194  "AND obj_id = ".$ilDB->quote($obj_id ,'integer');
195  $res = $ilDB->manipulate($query);
196  }
197  else
198  {
199  $query = "INSERT INTO catch_write_events (ts,obj_id,usr_id) ".
200  "VALUES( ".
201  $ilDB->now().", ".
202  $ilDB->quote($obj_id,'integer').", ".
203  $ilDB->quote($usr_id,'integer')." ".
204  ")";
205  $res = $ilDB->manipulate($query);
206 
207  }
208 
209  /*
210  $q = "INSERT INTO catch_write_events ".
211  "(obj_id, usr_id, ts) ".
212  "VALUES (".
213  $ilDB->quote($obj_id,'integer').",".
214  $ilDB->quote($usr_id,'integer').",";
215  if ($timestamp == null)
216  {
217  $q .= "NOW()".
218  ") ON DUPLICATE KEY UPDATE ts=NOW()";
219  }
220  else {
221  $q .= $ilDB->quote($timestamp).
222  ") ON DUPLICATE KEY UPDATE ts=".$ilDB->quote($timestamp);
223  }
224  //error_log ('ilChangeEvent::_catchupWriteEvents '.$q);
225  $r = $ilDB->query($q);
226  */
227  }
275  public static function _lookupUncaughtWriteEvents($obj_id, $usr_id)
276  {
277  global $ilDB;
278 
279  $q = "SELECT ts ".
280  "FROM catch_write_events ".
281  "WHERE obj_id=".$ilDB->quote($obj_id ,'integer')." ".
282  "AND usr_id=".$ilDB->quote($usr_id ,'integer');
283  $r = $ilDB->query($q);
284  $catchup = null;
285  while ($row = $r->fetchRow(DB_FETCHMODE_ASSOC)) {
286  $catchup = $row['ts'];
287  }
288 
289  if($catchup == null)
290  {
291  $query = sprintf('SELECT * FROM write_event '.
292  'WHERE obj_id = %s '.
293  'AND usr_id <> %s '.
294  'ORDER BY ts DESC',
295  $ilDB->quote($obj_id,'integer'),
296  $ilDB->quote($usr_id,'integer'));
297  $res = $ilDB->query($query);
298  }
299  else
300  {
301  $query = sprintf('SELECT * FROM write_event '.
302  'WHERE obj_id = %s '.
303  'AND usr_id <> %s '.
304  'AND ts >= %s '.
305  'ORDER BY ts DESC',
306  $ilDB->quote($obj_id,'integer'),
307  $ilDB->quote($usr_id,'integer'),
308  $ilDB->quote($catchup,'timestamp'));
309  $res = $ilDB->query($query);
310  }
311  $events = array();
312  while($row = $ilDB->fetchAssoc($res))
313  {
314  $events[] = $row;
315  }
316  return $events;
317  }
328  public static function _lookupChangeState($obj_id, $usr_id)
329  {
330  global $ilDB;
331 
332  $q = "SELECT ts ".
333  "FROM catch_write_events ".
334  "WHERE obj_id=".$ilDB->quote($obj_id ,'integer')." ".
335  "AND usr_id=".$ilDB->quote($usr_id ,'integer');
336  $r = $ilDB->query($q);
337  $catchup = null;
338  while ($row = $r->fetchRow(DB_FETCHMODE_ASSOC)) {
339  $catchup = $row['ts'];
340  }
341 
342  if($catchup == null)
343  {
344  $ilDB->setLimit(1);
345  $query = sprintf('SELECT * FROM write_event '.
346  'WHERE obj_id = %s '.
347  'AND usr_id <> %s ',
348  $ilDB->quote($obj_id,'integer'),
349  $ilDB->quote($usr_id,'integer'));
350  $res = $ilDB->query($query);
351  }
352  else
353  {
354  $ilDB->setLimit(1);
355  $query = sprintf('SELECT * FROM write_event '.
356  'WHERE obj_id = %s '.
357  'AND usr_id <> %s '.
358  'AND ts > %s ',
359  $ilDB->quote($obj_id,'integer'),
360  $ilDB->quote($usr_id,'integer'),
361  $ilDB->quote($catchup,'timestamp'));
362  $res = $ilDB->query($query);
363  }
364 
365  $numRows = $res->numRows();
366  if ($numRows > 0)
367  {
368  $row = $ilDB->fetchAssoc($res);
369  // if we have write events, and user never catched one, report as new (1)
370  // if we have write events, and user catched an old write event, report as changed (2)
371  return ($catchup == null) ? 1 : 2;
372  }
373  else
374  {
375  return 0; // user catched all write events, report as unchanged (0)
376  }
377  }
393  public static function _lookupInsideChangeState($parent_obj_id, $usr_id)
394  {
395  global $ilDB;
396 
397  $q = "SELECT ts ".
398  "FROM catch_write_events ".
399  "WHERE obj_id=".$ilDB->quote($parent_obj_id)." ".
400  "AND usr_id=".$ilDB->quote($usr_id);
401  $r = $ilDB->query($q);
402  $catchup = null;
403  while ($row = $r->fetchRow(DB_FETCHMODE_ASSOC)) {
404  $catchup = $row['ts'];
405  }
406 
407  if($catchup == null)
408  {
409  $ilDB->setLimit(1);
410  $query = sprintf('SELECT * FROM write_event '.
411  'WHERE parent_obj_id = %s '.
412  'AND usr_id <> %s ',
413  $ilDB->quote($parent_obj_id,'integer'),
414  $ilDB->quote($usr_id,'integer'));
415  $res = $ilDB->query($query);
416  }
417  else
418  {
419  $ilDB->setLimit(1);
420  $query = sprintf('SELECT * FROM write_event '.
421  'WHERE parent_obj_id = %s '.
422  'AND usr_id <> %s '.
423  'AND ts > %s ',
424  $ilDB->quote($parent_obj_id,'integer'),
425  $ilDB->quote($usr_id,'integer'),
426  $ilDB->quote($catchup,'timestamp'));
427  $res = $ilDB->query($query);
428  }
429  $numRows = $res->numRows();
430  if ($numRows > 0)
431  {
432  $row = $ilDB->fetchAssoc($res);
433  // if we have write events, and user never catched one, report as new (1)
434  // if we have write events, and user catched an old write event, report as changed (2)
435  return ($catchup == null) ? 1 : 2;
436  }
437  else
438  {
439  return 0; // user catched all write events, report as unchanged (0)
440  }
441  }
486  public static function _lookupReadEvents($obj_id, $usr_id = null)
487  {
488  global $ilDB;
489 
490  if ($usr_id == null)
491  {
492  $query = sprintf('SELECT * FROM read_event '.
493  'WHERE obj_id = %s '.
494  'ORDER BY last_access DESC',
495  $ilDB->quote($obj_id,'integer'));
496  $res = $ilDB->query($query);
497  }
498  else
499  {
500  $query = sprintf('SELECT * FROM read_event '.
501  'WHERE obj_id = %s '.
502  'AND usr_id = %s '.
503  'ORDER BY last_access DESC',
504  $ilDB->quote($obj_id,'integer'),
505  $ilDB->quote($usr_id,'integer'));
506  $res = $ilDB->query($query);
507  }
508 
509  $counter = 0;
510  while ($row = $ilDB->fetchAssoc($res))
511  {
512  $events[$counter]['obj_id'] = $row['obj_id'];
513  $events[$counter]['usr_id'] = $row['usr_id'];
514  $events[$counter]['last_access'] = $row['last_access'];
515  $events[$counter]['read_count'] = $row['read_count'];
516  $events[$counter]['spent_seconds'] = $row['spent_seconds'];
517  $events[$counter]['first_access'] = $row['first_access'];
518 
519  $counter++;
520 
521  }
522  return $events ? $events : array();
523  }
524 
531  public static function lookupUsersInProgress($a_obj_id)
532  {
533  global $ilDB;
534 
535  $query = sprintf('SELECT DISTINCT(usr_id) usr FROM read_event '.
536  'WHERE obj_id = %s ',
537  $ilDB->quote($a_obj_id,'integer'));
538  $res = $ilDB->query($query);
539  while($row = $ilDB->fetchObject($res))
540  {
541  $users[] = $row->usr;
542  }
543  return $users ? $users : array();
544  }
545 
551  public static function _activate() {
553  {
554  return 'change event tracking is already active';
555  }
556  else
557  {
558  global $ilDB;
559 
560  // Insert initial data into table write_event
561  // We need to do this here, because we need
562  // to catch up write events that occured while the change event tracking was
563  // deactivated.
564 
565  // IGNORE isn't supported in oracle
566  $set = $ilDB->query(sprintf('SELECT r1.obj_id,r2.obj_id p,d.owner,%s,d.create_date '.
567  'FROM object_data d '.
568  'LEFT JOIN write_event w ON d.obj_id = w.obj_id '.
569  'JOIN object_reference r1 ON d.obj_id=r1.obj_id '.
570  'JOIN tree t ON t.child=r1.ref_id '.
571  'JOIN object_reference r2 on r2.ref_id=t.parent '.
572  'WHERE w.obj_id IS NULL',
573  $ilDB->quote('create','text')));
574  while ($rec = $ilDB->fetchAssoc($set))
575  {
576  $nid = $ilDB->nextId("write_event");
577  $query = 'INSERT INTO write_event '.
578  '(write_id, obj_id,parent_obj_id,usr_id,action,ts) VALUES ('.
579  $ilDB->quote($nid, "integer").",".
580  $ilDB->quote($rec["obj_id"], "integer").",".
581  $ilDB->quote($rec["p"], "integer").",".
582  $ilDB->quote($rec["owner"], "integer").",".
583  $ilDB->quote("create", "text").",".
584  $ilDB->quote($rec["create_date"], "timestamp").
585  ')';
586  $res = $ilDB->query($query);
587  }
588 
589  if ($ilDB->isError($res) || $ilDB->isError($res->result))
590  {
591  return 'couldn\'t insert initial data into table "write_event": '.
592  (($ilDB->isError($r->result)) ? $r->result->getMessage() : $r->getMessage());
593  }
594 
595 
596  global $ilias;
597  $ilias->setSetting('enable_change_event_tracking', '1');
598 
599  return $res;
600  }
601  }
602 
608  public static function _deactivate() {
609  global $ilias;
610  $ilias->setSetting('enable_change_event_tracking', '0');
611 
612  }
613 
619  public static function _isActive() {
620  global $ilias;
621  return $ilias->getSetting('enable_change_event_tracking', '0') == '1';
622 
623  }
624 
631  public static function _delete($a_obj_id)
632  {
633  global $ilDB;
634 
635  $query = sprintf('DELETE FROM write_event WHERE obj_id = %s ',
636  $ilDB->quote($a_obj_id,'integer'));
637  $aff = $ilDB->manipulate($query);
638 
639  $query = sprintf('DELETE FROM read_event WHERE obj_id = %s ',
640  $ilDB->quote($a_obj_id,'integer'));
641  $aff = $ilDB->manipulate($query);
642  return true;
643  }
644 }
645 ?>