ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
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, $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 _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 44 of file class.ilChangeEvent.php.

Member Function Documentation

◆ _activate()

static ilChangeEvent::_activate ( )
static

Activates change event tracking.

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

616 : bool
617 {
619 return false;
620 } else {
621 global $DIC;
622
623 $ilDB = $DIC['ilDB'];
624
625 // Insert initial data into table write_event
626 // We need to do this here, because we need
627 // to catch up write events that occured while the change event tracking was
628 // deactivated.
629
630 // IGNORE isn't supported in oracle
631 $set = $ilDB->query(
632 sprintf(
633 'SELECT r1.obj_id,r2.obj_id p,d.owner,%s,d.create_date ' .
634 'FROM object_data d ' .
635 'LEFT JOIN write_event w ON d.obj_id = w.obj_id ' .
636 'JOIN object_reference r1 ON d.obj_id=r1.obj_id ' .
637 'JOIN tree t ON t.child=r1.ref_id ' .
638 'JOIN object_reference r2 on r2.ref_id=t.parent ' .
639 'WHERE w.obj_id IS NULL',
640 $ilDB->quote('create', 'text')
641 )
642 );
643 $res = null;
644 while ($rec = $ilDB->fetchAssoc($set)) {
645 $nid = $ilDB->nextId("write_event");
646 $query = 'INSERT INTO write_event ' .
647 '(write_id, obj_id,parent_obj_id,usr_id,action,ts) VALUES (' .
648 $ilDB->quote($nid, "integer") . "," .
649 $ilDB->quote($rec["obj_id"], "integer") . "," .
650 $ilDB->quote($rec["p"], "integer") . "," .
651 $ilDB->quote($rec["owner"], "integer") . "," .
652 $ilDB->quote("create", "text") . "," .
653 $ilDB->quote($rec["create_date"], "timestamp") .
654 ')';
655 $res = $ilDB->query($query);
656 }
657
658 global $DIC;
659
660 $ilSetting = $DIC['ilSetting'];
661 $ilSetting->set('enable_change_event_tracking', '1');
662
663 return $res !== null;
664 }
665 }
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:

◆ _deactivate()

static ilChangeEvent::_deactivate ( )
static

Deactivates change event tracking.

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

670 : bool
671 {
672 global $DIC;
673
674 $ilSetting = $DIC['ilSetting'];
675 $ilSetting->set('enable_change_event_tracking', '0');
676 return true;
677 }

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 693 of file class.ilChangeEvent.php.

693 : bool
694 {
695 global $DIC;
696
697 $ilDB = $DIC['ilDB'];
698 $query = sprintf(
699 'DELETE FROM write_event WHERE obj_id = %s ',
700 $ilDB->quote($a_obj_id, 'integer')
701 );
702 $aff = $ilDB->manipulate($query);
703
704 $query = sprintf(
705 'DELETE FROM read_event WHERE obj_id = %s ',
706 $ilDB->quote($a_obj_id, 'integer')
707 );
708 $aff = $ilDB->manipulate($query);
709 return true;
710 }

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 712 of file class.ilChangeEvent.php.

712 : void
713 {
714 global $DIC;
715
716 $ilDB = $DIC['ilDB'];
717
718 $ilDB->manipulate(
719 "DELETE FROM read_event" .
720 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer")
721 );
722 }

References $DIC, and $ilDB.

◆ _deleteReadEventsForUsers()

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

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

727 : void {
728 global $DIC;
729
730 $ilDB = $DIC['ilDB'];
731
732 $ilDB->manipulate(
733 "DELETE FROM read_event" .
734 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer") .
735 " AND " . $ilDB->in("usr_id", $a_user_ids, "", "integer")
736 );
737 }

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 739 of file class.ilChangeEvent.php.

739 : array
740 {
741 global $DIC;
742
743 $ilDB = $DIC['ilDB'];
744 $res = array();
745 $set = $ilDB->query(
746 "SELECT usr_id FROM read_event" .
747 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer")
748 );
749 while ($row = $ilDB->fetchAssoc($set)) {
750 $res[] = (int) $row["usr_id"];
751 }
752 return $res;
753 }

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 682 of file class.ilChangeEvent.php.

682 : bool
683 {
684 global $DIC;
685
686 $ilSetting = $DIC['ilSetting'];
687 return $ilSetting->get('enable_change_event_tracking', '0') == '1';
688 }

References $DIC, and $ilSetting.

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

+ Here is the caller graph for this function:

◆ _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 529 of file class.ilChangeEvent.php.

530 {
531 global $DIC;
532
533 $ilDB = $DIC['ilDB'];
534
535 if ($usr_id == null) {
536 $query = sprintf(
537 'SELECT * FROM read_event ' .
538 'WHERE obj_id = %s ' .
539 'ORDER BY last_access DESC',
540 $ilDB->quote($obj_id, 'integer')
541 );
542 $res = $ilDB->query($query);
543 } else {
544 $query = sprintf(
545 'SELECT * FROM read_event ' .
546 'WHERE obj_id = %s ' .
547 'AND usr_id = %s ' .
548 'ORDER BY last_access DESC',
549 $ilDB->quote($obj_id, 'integer'),
550 $ilDB->quote($usr_id, 'integer')
551 );
552 $res = $ilDB->query($query);
553 }
554
555 $counter = 0;
556 $events = [];
557 while ($row = $ilDB->fetchAssoc($res)) {
558 $events[$counter]['obj_id'] = $row['obj_id'];
559 $events[$counter]['usr_id'] = $row['usr_id'];
560 $events[$counter]['last_access'] = $row['last_access'];
561 $events[$counter]['read_count'] = $row['read_count'];
562 $events[$counter]['spent_seconds'] = $row['spent_seconds'];
563 $events[$counter]['first_access'] = $row['first_access'];
564
565 $counter++;
566 }
567 return $events;
568 }
$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:

◆ _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 318 of file class.ilChangeEvent.php.

324 : void {
325 global $DIC;
326
327 $ilDB = $DIC['ilDB'];
328
330 $a_obj_id <= 0) { // #12706
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 $fields["spent_seconds"] = array("integer", $a_spent_seconds);
347 }
348 if ($a_read_count > 0) {
349 $fields["read_count"] = array("integer", $a_read_count);
350 }
351 if ($a_childs_spent_seconds > 0) {
352 $fields["childs_spent_seconds"] = array("integer",
353 $a_childs_spent_seconds
354 );
355 }
356 if ($a_child_read_count > 0) {
357 $fields["childs_read_count"] = array("integer",
358 $a_child_read_count
359 );
360 }
361 $ilDB->insert("obj_stat_log", $fields);
362
363 // 0.01% probability
364 if (mt_rand(1, 100) == 1) {
366 }
367 }
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,
  $a_ext_rc = null,
  $a_ext_time = null 
)
static

Definition at line 118 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 // update parents (no categories or root)
226 if (!in_array($a_type, array("cat", "root", "crs"))) {
227 if ($tree->isInTree($a_ref_id)) {
228 $path = $tree->getPathId($a_ref_id);
229
230 foreach ($path as $p) {
231 $obj2_id = ilObject::_lookupObjId($p);
232 $obj2_type = ilObject::_lookupType($obj2_id);
233 //echo "<br>1-$obj2_type-$p-$obj2_id-";
234 if (($p != $a_ref_id) && (in_array(
235 $obj2_type,
236 array("crs",
237 "fold",
238 "grp",
239 "lso"
240 )
241 ))) {
242 $query = sprintf(
243 'SELECT * FROM read_event ' .
244 'WHERE obj_id = %s ' .
245 'AND usr_id = %s ',
246 $ilDB->quote($obj2_id, 'integer'),
247 $ilDB->quote($usr_id, 'integer')
248 );
249 $res2 = $ilDB->query($query);
250 if ($row2 = $ilDB->fetchAssoc($res2)) {
251 //echo "<br>2";
252 // update read count and spent seconds
253 $query = sprintf(
254 'UPDATE read_event SET ' .
255 'childs_read_count = childs_read_count + %s ,' .
256 'childs_spent_seconds = childs_spent_seconds + %s ' .
257 'WHERE obj_id = %s ' .
258 'AND usr_id = %s ',
259 $ilDB->quote((int) $read_count_diff, 'integer'),
260 $ilDB->quote((int) $time_diff, 'integer'),
261 $ilDB->quote($obj2_id, 'integer'),
262 $ilDB->quote($usr_id, 'integer')
263 );
264 $aff = $ilDB->manipulate($query);
265
267 $obj2_id,
268 null,
269 null,
270 (int) $time_diff,
271 (int) $read_count_diff
272 );
273 } else {
274 // #10407
275 $ilDB->replace(
276 'read_event',
277 array(
278 'obj_id' => array('integer', $obj2_id),
279 'usr_id' => array('integer', $usr_id)
280 ),
281 array(
282 'read_count' => array('integer', 1),
283 'spent_seconds' => array('integer', $time),
284 'first_access' => array('timestamp',
285 date("Y-m-d H:i:s")
286 ), // was $ilDB->now()
287 'last_access' => array('integer', time()),
288 'childs_read_count' => array('integer',
289 (int) $read_count_diff
290 ),
291 'childs_spent_seconds' => array('integer',
292 (int) $time_diff
293 )
294 )
295 );
296
297 self::$has_accessed[$obj2_id][$usr_id] = true;
298
300 $obj2_id,
301 $time,
302 1,
303 (int) $time_diff,
304 (int) $read_count_diff
305 );
306 }
307 }
308 }
309 }
310 }
311
312 // @todo:
313 // - calculate diff of spent_seconds and read_count
314 // - use ref id to get parents of types grp, crs, fold
315 // - add diffs to childs_spent_seconds and childs_read_count
316 }
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 _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 62 of file class.ilChangeEvent.php.

67 : void {
68 global $DIC;
69
70 $ilDB = $DIC['ilDB'];
71
72 /* see _recordReadEvent
73 if (!ilChangeEvent::_isActive())
74 {
75 return;
76 }
77 */
78
79 if ($parent_obj_id == null) {
80 $pset = $ilDB->query(
81 'SELECT r2.obj_id par_obj_id FROM object_reference r1 ' .
82 'JOIN tree t ON t.child = r1.ref_id ' .
83 'JOIN object_reference r2 ON r2.ref_id = t.parent ' .
84 'WHERE r1.obj_id = ' . $ilDB->quote($obj_id, 'integer')
85 );
86
87 while ($prec = $ilDB->fetchAssoc($pset)) {
88 $nid = $ilDB->nextId("write_event");
89 $query = sprintf(
90 'INSERT INTO write_event ' .
91 '(write_id, obj_id, parent_obj_id, usr_id, action, ts) VALUES ' .
92 '(%s, %s, %s, %s, %s, ' . $ilDB->now() . ')',
93 $ilDB->quote($nid, 'integer'),
94 $ilDB->quote($obj_id, 'integer'),
95 $ilDB->quote($prec["par_obj_id"], 'integer'),
96 $ilDB->quote($usr_id, 'integer'),
97 $ilDB->quote($action, 'text')
98 );
99
100 $aff = $ilDB->manipulate($query);
101 }
102 } else {
103 $nid = $ilDB->nextId("write_event");
104 $query = sprintf(
105 'INSERT INTO write_event ' .
106 '(write_id, obj_id, parent_obj_id, usr_id, action, ts) ' .
107 'VALUES (%s,%s,%s,%s,%s,' . $ilDB->now() . ')',
108 $ilDB->quote($nid, 'integer'),
109 $ilDB->quote($obj_id, 'integer'),
110 $ilDB->quote($parent_obj_id, 'integer'),
111 $ilDB->quote($usr_id, 'integer'),
112 $ilDB->quote($action, 'text')
113 );
114 $aff = $ilDB->manipulate($query);
115 }
116 }

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 369 of file class.ilChangeEvent.php.

372 {
373 global $DIC;
374
375 $ilDB = $DIC['ilDB'];
376
377 if (!$a_now) {
378 $a_now = time();
379 }
380
381 set_time_limit(0);
382
383 // has source table enough entries?
384 $set = $ilDB->query("SELECT COUNT(*) AS counter FROM obj_stat_log");
385 $row = $ilDB->fetchAssoc($set);
386 if ($row["counter"] >= $a_minimum) {
387 $ilAtomQuery = $ilDB->buildAtomQuery();
388 $ilAtomQuery->addTableLock('obj_stat_log');
389 $ilAtomQuery->addTableLock('obj_stat_tmp');
390
391 $ilAtomQuery->addQueryCallable(
392 function (ilDBInterface $ilDB) use ($a_now, $a_minimum, &$ret) {
393 // if other process was transferring, we had to wait for the lock and
394 // the source table should now have less than minimum/needed entries
395 $set = $ilDB->query(
396 "SELECT COUNT(*) AS counter FROM obj_stat_log"
397 );
398 $row = $ilDB->fetchAssoc($set);
399 if ($row["counter"] >= $a_minimum) {
400 // use only "full" seconds to have a clear cut
401 $ilDB->query(
402 "INSERT INTO obj_stat_tmp" .
403 " SELECT * FROM obj_stat_log" .
404 " WHERE tstamp < " . $ilDB->quote(
405 $a_now,
406 "timestamp"
407 )
408 );
409
410 // remove transferred entries from source table
411 $ilDB->query(
412 "DELETE FROM obj_stat_log" .
413 " WHERE tstamp < " . $ilDB->quote(
414 $a_now,
415 "timestamp"
416 )
417 );
418
419 $ret = true;
420 } else {
421 $ret = false;
422 }
423 }
424 );
425
426 $ilAtomQuery->run();
427
428 //continue only if obj_stat_log counter >= $a_minimum
429 if ($ret) {
430 $ilAtomQuery = $ilDB->buildAtomQuery();
431 $ilAtomQuery->addTableLock('obj_stat_tmp');
432 $ilAtomQuery->addTableLock('obj_stat');
433
434 $ilAtomQuery->addQueryCallable(
435 function (ilDBInterface $ilDB) use ($a_now, $a_minimum) {
436 // process log data (timestamp is not needed anymore)
437 $sql = "SELECT obj_id, obj_type, yyyy, mm, dd, hh, SUM(read_count) AS read_count," .
438 " SUM(childs_read_count) AS childs_read_count, SUM(spent_seconds) AS spent_seconds," .
439 " SUM(childs_spent_seconds) AS childs_spent_seconds" .
440 " FROM obj_stat_tmp" .
441 " GROUP BY obj_id, obj_type, yyyy, mm, dd, hh";
442 $set = $ilDB->query($sql);
443 while ($row = $ilDB->fetchAssoc($set)) {
444 // "primary key"
445 $where = array("obj_id" => array("integer",
446 $row["obj_id"]
447 ),
448 "obj_type" => array("text",
449 $row["obj_type"]
450 ),
451 "yyyy" => array("integer",
452 $row["yyyy"]
453 ),
454 "mm" => array("integer", $row["mm"]),
455 "dd" => array("integer", $row["dd"]),
456 "hh" => array("integer", $row["hh"])
457 );
458
459 $where_sql = array();
460 foreach ($where as $field => $def) {
461 $where_sql[] = $field . " = " . $ilDB->quote(
462 $def[1],
463 $def[0]
464 );
465 }
466 $where_sql = implode(" AND ", $where_sql);
467
468 // existing entry?
469 $check = $ilDB->query(
470 "SELECT read_count, childs_read_count, spent_seconds," .
471 "childs_spent_seconds" .
472 " FROM obj_stat" .
473 " WHERE " . $where_sql
474 );
475 if ($ilDB->numRows($check)) {
476 $old = $ilDB->fetchAssoc($check);
477
478 // add existing values
479 $fields = array("read_count" => array("integer",
480 $old["read_count"] + $row["read_count"]
481 ),
482 "childs_read_count" => array("integer",
483 $old["childs_read_count"] + $row["childs_read_count"]
484 ),
485 "spent_seconds" => array("integer",
486 $old["spent_seconds"] + $row["spent_seconds"]
487 ),
488 "childs_spent_seconds" => array("integer",
489 $old["childs_spent_seconds"] + $row["childs_spent_seconds"]
490 )
491 );
492
493 $ilDB->update("obj_stat", $fields, $where);
494 } else {
495 // new entry
496 $fields = $where;
497 $fields["read_count"] = array("integer",
498 $row["read_count"]
499 );
500 $fields["childs_read_count"] = array("integer",
501 $row["childs_read_count"]
502 );
503 $fields["spent_seconds"] = array("integer",
504 $row["spent_seconds"]
505 );
506 $fields["childs_spent_seconds"] = array("integer",
507 $row["childs_spent_seconds"]
508 );
509
510 $ilDB->insert("obj_stat", $fields);
511 }
512 }
513
514 // clean up transfer table
515 $ilDB->query("DELETE FROM obj_stat_tmp");
516 }
517 );
518
519 $ilAtomQuery->run();
520 }
521 }
522 }
$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 760 of file class.ilChangeEvent.php.

765 : bool {
766 global $DIC;
767
768 $ilDB = $DIC->database();
769 $res = $ilDB->queryF(
770 'UPDATE read_event SET first_access=%s, last_access = %s WHERE obj_id=%s AND usr_id=%s',
771 array('timestamp', 'integer', 'integer', 'integer'),
772 array($t_first_access, $i_last_access, $obj_id, $usr_id)
773 );
774 return true;
775 }

◆ hasAccessed()

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

Has accessed.

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

592 : bool
593 {
594 global $DIC;
595
596 $ilDB = $DIC['ilDB'];
597
598 if (isset(self::$has_accessed[$a_obj_id][$a_usr_id])) {
599 return self::$has_accessed[$a_obj_id][$a_usr_id];
600 }
601
602 $set = $ilDB->query(
603 "SELECT usr_id FROM read_event WHERE " .
604 "obj_id = " . $ilDB->quote($a_obj_id, "integer") . " AND " .
605 "usr_id = " . $ilDB->quote($a_usr_id, "integer")
606 );
607 if ($rec = $ilDB->fetchAssoc($set)) {
608 return self::$has_accessed[$a_obj_id][$a_usr_id] = true;
609 }
610 return self::$has_accessed[$a_obj_id][$a_usr_id] = false;
611 }

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 570 of file class.ilChangeEvent.php.

570 : array
571 {
572 global $DIC;
573
574 $ilDB = $DIC['ilDB'];
575
576 $query = sprintf(
577 'SELECT DISTINCT(usr_id) usr FROM read_event ' .
578 'WHERE obj_id = %s ',
579 $ilDB->quote($a_obj_id, 'integer')
580 );
581 $res = $ilDB->query($query);
582 $users = [];
583 while ($row = $ilDB->fetchObject($res)) {
584 $users[] = (int) $row->usr;
585 }
586 return $users;
587 }

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 46 of file class.ilChangeEvent.php.


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