ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ilChangeEvent Class Reference

Class ilChangeEvent tracks change events on repository objects. More...

+ Collaboration diagram for ilChangeEvent:

Static Public Member Functions

static _recordWriteEvent (int $obj_id, int $usr_id, string $action, ?int $parent_obj_id=null)
 Records a write event. More...
 
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 _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 _syncObjectStats (?int $a_now=null, int $a_minimum=20000)
 
static _catchupWriteEvents (int $obj_id, int $usr_id, ?string $timestamp=null)
 Catches up with all write events which occured before the specified timestamp. More...
 
static _lookupUncaughtWriteEvents (int $obj_id, int $usr_id)
 Reads all write events which occured on the object which happened after the last time the user caught up with them. More...
 
static _lookupChangeState (int $obj_id, int $usr_id)
 Returns the change state of the object for the specified user. More...
 
static _lookupReadEvents ($obj_id, $usr_id=null)
 Reads all read events which occured on the object. More...
 
static lookupUsersInProgress (int $a_obj_id)
 
static hasAccessed (int $a_obj_id, int $a_usr_id)
 Has accessed. More...
 
static _activate ()
 Activates change event tracking. More...
 
static _deactivate ()
 Deactivates change event tracking. More...
 
static _isActive ()
 Returns true, if change event tracking is active. More...
 
static _delete (int $a_obj_id)
 Delete object entries. More...
 
static _deleteReadEvents (int $a_obj_id)
 
static _deleteReadEventsForUsers (int $a_obj_id, array $a_user_ids)
 
static _getAllUserIds (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 modul is used offline called in . More...
 

Static Private Attributes

static array $has_accessed = []
 

Detailed Description

Class ilChangeEvent tracks change events on repository objects.

The following events are considered to be a 'write event':

  • The creation of a new repository object
  • A change of the data or meta-data of an object
  • A move, link, copy, deletion or undeletion of the object UI objects, which cause a 'write event', must call _recordWriteEvent(...) In most cases, UI objects let the user catch up with write events on the object, when doing this call. The following events are considered to be a 'read event':
  • Opening a container object in the browser*
  • Opening / downloading / reading an object UI objects, which cause a 'read event', must call _recordReadEvent(...). In most cases, UI objects let the user catch up with write events on the object, when doing this call. *reading the content of a container using WebDAV is not counted, because WebDAV clients can't see all objects in a container. A user can catch up with write events, by calling __catchupWriteEvents(...). A user can query, if an object has changed, since the last time he has caught up with write events, by calling _lookupUncaughtWriteEvents(...).
    Author
    Werner Randelshofer werne.nosp@m.r.ra.nosp@m.ndels.nosp@m.hofe.nosp@m.r@hsl.nosp@m.u.ch
    Version
    Id
    class.ilChangeEvent.php,v 1.02 2007/05/07 19:25:34 wrandels Exp

Definition at line 43 of file class.ilChangeEvent.php.

Member Function Documentation

◆ _activate()

static ilChangeEvent::_activate ( )
static

Activates change event tracking.

Definition at line 675 of file class.ilChangeEvent.php.

675 : 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 }
static _isActive()
Returns true, if change event tracking is active.
$res
Definition: ltiservices.php:69
global $ilSetting
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26

References $DIC, $ilDB, $ilSetting, $res, and _isActive().

Referenced by ilObjRepositorySettingsGUI\saveSettings().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _catchupWriteEvents()

static ilChangeEvent::_catchupWriteEvents ( int  $obj_id,
int  $usr_id,
?string  $timestamp = null 
)
static

Catches up with all write events which occured before the specified timestamp.

Parameters
$obj_idint The object.
$usr_idint The user.
$timestampstring|null timestamp.
Returns
void

This method was only used to write to catch_write_events, but the methods reading out that table are not used anywhere.

Deprecated:
, will be removed with ILIAS 11

Definition at line 540 of file class.ilChangeEvent.php.

544 : void {
545 }

Referenced by ilContainerGUI\pasteObject(), ilContainerGUI\performPasteIntoMultipleObjectsObject(), ilObjCategoryGUI\updateObject(), ilObjCourseGUI\updateObject(), ilObjGroupGUI\updateObject(), and ilObjRootFolderGUI\updateObject().

+ Here is the caller graph for this function:

◆ _deactivate()

static ilChangeEvent::_deactivate ( )
static

Deactivates change event tracking.

Definition at line 729 of file class.ilChangeEvent.php.

729 : bool
730 {
731 global $DIC;
732
733 $ilSetting = $DIC['ilSetting'];
734 $ilSetting->set('enable_change_event_tracking', '0');
735 return true;
736 }

References $DIC, and $ilSetting.

Referenced by ilObjRepositorySettingsGUI\saveSettings().

+ Here is the caller graph for this function:

◆ _delete()

static ilChangeEvent::_delete ( int  $a_obj_id)
static

Delete object entries.

Definition at line 752 of file class.ilChangeEvent.php.

752 : 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 }

References $DIC, and $ilDB.

Referenced by ilObjectLP\handleDelete().

+ Here is the caller graph for this function:

◆ _deleteReadEvents()

static ilChangeEvent::_deleteReadEvents ( int  $a_obj_id)
static

Definition at line 771 of file class.ilChangeEvent.php.

771 : 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 }

References $DIC, and $ilDB.

◆ _deleteReadEventsForUsers()

static ilChangeEvent::_deleteReadEventsForUsers ( int  $a_obj_id,
array  $a_user_ids 
)
static

Definition at line 783 of file class.ilChangeEvent.php.

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 }

Referenced by ilObjSCORM2004LearningModule\deleteTrackingDataOfUsers(), ilObjSCORMLearningModule\deleteTrackingDataOfUsers(), and ilObjectLP\resetLPDataForUserIds().

+ Here is the caller graph for this function:

◆ _getAllUserIds()

static ilChangeEvent::_getAllUserIds ( int  $a_obj_id)
static

Definition at line 798 of file class.ilChangeEvent.php.

798 : 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 }

References $DIC, $ilDB, $res, and ILIAS\Repository\int().

Referenced by ilObjectLP\gatherLPUsers().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _isActive()

static ilChangeEvent::_isActive ( )
static

Returns true, if change event tracking is active.

Definition at line 741 of file class.ilChangeEvent.php.

741 : bool
742 {
743 global $DIC;
744
745 $ilSetting = $DIC['ilSetting'];
746 return $ilSetting->get('enable_change_event_tracking', '0') == '1';
747 }

References $DIC, and $ilSetting.

Referenced by ilObjUserTracking\__readSettings(), _activate(), ilObjRepositorySettingsGUI\addToExternalSettingsForm(), and ilObjRepositorySettingsGUI\initSettingsForm().

+ Here is the caller graph for this function:

◆ _lookupChangeState()

static ilChangeEvent::_lookupChangeState ( int  $obj_id,
int  $usr_id 
)
static

Returns the change state of the object for the specified user.

which happened after the last time the user caught up with them.

Parameters
$obj_idint The object
$usr_idint The user who is interested into these events.
Returns
int 0 = object is unchanged, 1 = object is new, 2 = object has changed

This method is unused, so the table it read from was removed for performance reasons.

Deprecated:
, will be removed with ILIAS 11

Definition at line 578 of file class.ilChangeEvent.php.

578 : int
579 {
580 return 0;
581 }

◆ _lookupReadEvents()

static ilChangeEvent::_lookupReadEvents (   $obj_id,
  $usr_id = null 
)
static

Reads all read events which occured on the object.

Parameters
$obj_idint The object
$usr_idint Optional, the user who performed these events.

Definition at line 588 of file class.ilChangeEvent.php.

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 }
$counter

References $counter, $DIC, $ilDB, and $res.

Referenced by ilLPStatusContentVisited\_getCompleted(), ilLPStatusTypicalLearningTime\_getCompleted(), ilLPStatusVisits\_getCompleted(), ilLPStatusTypicalLearningTime\_getInProgress(), ilLPStatusVisits\_getInProgress(), ilLearningProgress\_getProgress(), ilLearningProgress\_lookupProgressByObjId(), ilLPStatusTypicalLearningTime\determineStatus(), ilLPStatusVisits\determineStatus(), and ILIAS\MediaCast\Presentation\VideoViewGUI\renderSideColumn().

+ Here is the caller graph for this function:

◆ _lookupUncaughtWriteEvents()

static ilChangeEvent::_lookupUncaughtWriteEvents ( int  $obj_id,
int  $usr_id 
)
static

Reads all write events which occured on the object which happened after the last time the user caught up with them.

Parameters
$obj_idint The object
$usr_idint The user who is interested into these events.
Returns
array with rows from table write_event

This method is unused, so the table it read from was removed for performance reasons.

Deprecated:
, will be removed with ILIAS 11

Definition at line 558 of file class.ilChangeEvent.php.

561 : array {
562 return [];
563 }

◆ _recordObjStats()

static ilChangeEvent::_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

Definition at line 322 of file class.ilChangeEvent.php.

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) {
370 }
371 }
static _syncObjectStats(?int $a_now=null, int $a_minimum=20000)
static _lookupType(int $id, bool $reference=false)

◆ _recordReadEvent()

static ilChangeEvent::_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

Definition at line 117 of file class.ilChangeEvent.php.

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
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
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 }
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 _lookupObjId(int $ref_id)
$path
Definition: ltiservices.php:30

Referenced by ilObjSCORMTracking\_syncReadEvent(), ilSCORM2004Tracking\_syncReadEvent(), ilRemoteObjectBaseGUI\callObject(), ilSurveyExecutionGUI\executeCommand(), ilObjForumGUI\getContent(), ilWikiPageGUI\increaseViewCount(), ilContainerGUI\performPasteIntoMultipleObjectsObject(), ilObjIndividualAssessmentGUI\recordIndividualAssessmentRead(), ilObjLearningSequenceGUI\recordLearningSequenceRead(), ilObjLinkResourceGUI\redirectToLink(), ilObjBlogGUI\renderFullscreenHeader(), ilObjPortfolioBaseGUI\renderFullscreenHeader(), ilObjCategoryGUI\renderObject(), ilObjFileGUI\sendFile(), ilContainerContentGUI\setOutput(), ilObjMediaCastGUI\showContentObject(), ilObjSCORMTracking\syncGlobalStatus(), ilLMTracker\trackAccess(), ilObjCmiXapiGUI\trackObjectReadEvent(), ilObjLTIConsumerGUI\trackObjectReadEvent(), ilObjTestGUI\trackTestObjectReadEvent(), ilObjectGUI\viewObject(), and ilObjForumGUI\viewThreadObject().

+ Here is the caller graph for this function:

◆ _recordWriteEvent()

static ilChangeEvent::_recordWriteEvent ( int  $obj_id,
int  $usr_id,
string  $action,
?int  $parent_obj_id = null 
)
static

Records a write event.

The parent object should be specified for the 'delete', 'undelete' and 'add' and 'remove' events.

Parameters
int$obj_idThe object which was written to.
int$usr_idThe user who performed a write action.
string$actionThe name of the write action. 'create', 'update', 'delete', 'add', 'remove', 'undelete'.
int | null$parent_obj_idThe object id of the parent object. If this is null, then the event is recorded for all parents of the object. If this is not null, then the event is only recorded for the specified parent.
Returns
void

Definition at line 61 of file class.ilChangeEvent.php.

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 }

References $ilDB.

Referenced by ilObjCourseGUI\afterSave(), ILIAS\Repository\Deletion\EventStandardAdapter\beforeSubtreeRemoval(), ilContainerGUI\pasteObject(), ilContainerGUI\performPasteIntoMultipleObjectsObject(), ilObject2GUI\putObjectInTree(), ilObjectGUI\putObjectInTree(), ilObjCategoryGUI\updateObject(), ilObjCourseGUI\updateObject(), ilObjGroupGUI\updateObject(), and ilObjRootFolderGUI\updateObject().

+ Here is the caller graph for this function:

◆ _syncObjectStats()

static ilChangeEvent::_syncObjectStats ( ?int  $a_now = null,
int  $a_minimum = 20000 
)
static

Definition at line 373 of file class.ilChangeEvent.php.

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 }
$check
Definition: buildRTE.php:81
Interface ilDBInterface.

References $check, $DIC, and $ilDB.

Referenced by ilLPObjectStatisticsGUI\adminSync().

+ Here is the caller graph for this function:

◆ _updateAccessForScormOfflinePlayer()

static ilChangeEvent::_updateAccessForScormOfflinePlayer ( int  $obj_id,
int  $usr_id,
int  $i_last_access,
string  $t_first_access 
)
static

_updateAccessForScormOfflinePlayer needed to synchronize last_access and first_access when learning modul is used offline called in .

/Modules/ScormAicc/classes/class.ilSCORMOfflineMode.php

Definition at line 819 of file class.ilChangeEvent.php.

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 }

◆ hasAccessed()

static ilChangeEvent::hasAccessed ( int  $a_obj_id,
int  $a_usr_id 
)
static

Has accessed.

Definition at line 651 of file class.ilChangeEvent.php.

651 : 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 }

References $DIC, and $ilDB.

Referenced by ilLPStatusCollection\determineStatus(), ilLPStatusExerciseReturned\determineStatus(), ilLPStatusManual\determineStatus(), ilLPStatusManualByTutor\determineStatus(), ilLPStatusObjectives\determineStatus(), ilLPStatusTypicalLearningTime\determineStatus(), ilLPStatusVisitedPages\determineStatus(), and ilLPStatusVisits\determineStatus().

+ Here is the caller graph for this function:

◆ lookupUsersInProgress()

static ilChangeEvent::lookupUsersInProgress ( int  $a_obj_id)
static

Definition at line 629 of file class.ilChangeEvent.php.

629 : 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 }

References $DIC, $ilDB, $res, and ILIAS\Repository\int().

Referenced by ilLPStatusQuestions\_getCompleted(), ilLPStatusCollection\_getInProgress(), ilLPStatusExerciseReturned\_getInProgress(), ilLPStatusManual\_getInProgress(), ilLPStatusManualByTutor\_getInProgress(), ilLPStatusQuestions\_getInProgress(), ilLPStatusVisitedPages\_getInProgress(), ilLPStatusCollectionMobs\_getStatusInfo(), and ilLPStatusObjectives\_getStatusInfo().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $has_accessed

array ilChangeEvent::$has_accessed = []
staticprivate

Definition at line 45 of file class.ilChangeEvent.php.


The documentation for this class was generated from the following file: