19 declare(strict_types=1);
37 return (
bool)
$ilSetting->get(
'session_statistics',
"1");
43 public static function createRawEntry(
string $a_session_id,
int $a_session_type,
int $a_timestamp,
int $a_user_id): void
49 if (!$a_user_id || !$a_session_id || !self::isActive()) {
57 "usr_session_stats_raw",
59 "session_id" => array(
"text", $a_session_id)
62 "type" => array(
"integer", $a_session_type),
63 "start_time" => array(
"integer", $a_timestamp),
64 "user_id" => array(
"integer", $a_user_id)
82 if (!self::isActive()) {
87 if (!is_array($a_session_id)) {
89 $end_time = $a_expired_at;
93 $sql =
"UPDATE usr_session_stats_raw" .
94 " SET end_time = " .
$ilDB->quote($end_time,
"integer");
96 $sql .=
",end_context = " .
$ilDB->quote($a_context,
"integer");
98 $sql .=
" WHERE session_id = " .
$ilDB->quote($a_session_id,
"text") .
99 " AND end_time IS NULL";
100 $ilDB->manipulate($sql);
103 elseif (!$a_expired_at) {
104 $sql =
"UPDATE usr_session_stats_raw" .
105 " SET end_time = " .
$ilDB->quote(time(),
"integer");
107 $sql .=
",end_context = " .
$ilDB->quote($a_context,
"integer");
109 $sql .=
" WHERE " .
$ilDB->in(
"session_id", $a_session_id,
false,
"text") .
110 " AND end_time IS NULL";
111 $ilDB->manipulate($sql);
115 foreach ($a_session_id as
$id => $ts) {
116 $sql =
"UPDATE usr_session_stats_raw" .
117 " SET end_time = " .
$ilDB->quote($ts,
"integer");
119 $sql .=
",end_context = " .
$ilDB->quote($a_context,
"integer");
121 $sql .=
" WHERE session_id = " .
$ilDB->quote(
$id,
"text") .
122 " AND end_time IS NULL";
123 $ilDB->manipulate($sql);
137 $ilDB = $DIC[
'ilDB'];
140 $sql =
"SELECT MAX(slot_end) previous_slot_end" .
141 " FROM usr_session_stats";
144 $previous_slot_end = $row[
"previous_slot_end"];
148 if (!$previous_slot_end) {
149 $slot = (
int) (floor(date(
"i") / self::SLOT_SIZE));
152 $current_slot_begin = mktime((
int) date(
"H", $a_now) - 1, 60 - self::SLOT_SIZE, 0);
156 $current_slot_begin = mktime((
int) date(
"H", $a_now), ($slot - 1) * self::SLOT_SIZE, 0);
159 $current_slot_begin = $previous_slot_end + 1;
162 $current_slot_end = $current_slot_begin + (60 * self::SLOT_SIZE) - 1;
165 if ($current_slot_end < $a_now) {
166 return array($current_slot_begin, $current_slot_end);
181 $ilDB = $DIC[
'ilDB'];
183 $sql =
"SELECT COUNT(*) counter FROM usr_session_stats_raw" .
184 " WHERE (end_time IS NULL OR end_time >= " .
$ilDB->quote($a_time,
"integer") .
")" .
185 " AND start_time <= " .
$ilDB->quote($a_time,
"integer") .
189 return (
int) $row[
"counter"];
195 protected static function getRawData(
int $a_begin,
int $a_end): array
199 $ilDB = $DIC[
'ilDB'];
201 $sql =
"SELECT start_time,end_time,end_context FROM usr_session_stats_raw" .
202 " WHERE start_time <= " .
$ilDB->quote($a_end,
"integer") .
203 " AND (end_time IS NULL OR end_time >= " .
$ilDB->quote($a_begin,
"integer") .
")" .
205 " ORDER BY start_time";
223 $ilDB = $DIC[
'ilDB'];
225 $ilAtomQuery =
$ilDB->buildAtomQuery();
226 $ilAtomQuery->addTableLock(
"usr_session_stats");
230 $slot = self::getCurrentSlot($a_now);
231 if (!is_array($slot)) {
238 "slot_begin" => array(
"integer", $slot[0]),
239 "slot_end" => array(
"integer", $slot[1]),
241 $ilDB->
insert(
"usr_session_stats", $fields);
256 if (!self::isActive()) {
260 $slot = self::createNewAggregationSlot($a_now);
261 while (is_array($slot)) {
262 self::aggregateRawHelper($slot[0], $slot[1]);
263 $slot = self::createNewAggregationSlot($a_now);
267 self::deleteAggregatedRaw($a_now);
278 $ilDB = $DIC[
'ilDB'];
287 $closed_counter = $events = array();
289 foreach (self::getRawData($a_begin, $a_end) as $item) {
298 if ($item[
"start_time"] >= $a_begin) {
300 $events[$item[
"start_time"]][] = 1;
303 if ($item[
"end_time"] && $item[
"end_time"] <= $a_end) {
304 if (in_array($item[
"end_context"], $separate_closed,
true)) {
305 if (!isset($closed_counter[$item[
"end_context"]])) {
306 $closed_counter[$item[
"end_context"]] = 0;
309 $closed_counter[$item[
"end_context"]]++;
311 $closed_counter[0] = ($closed_counter[0] ?? 0) + 1;
313 $events[$item[
"end_time"]][] = -1;
318 $active_begin = self::getNumberOfActiveRawSessions($a_begin - 1);
319 $active_end = $active_min = $active_max = $active_avg = $active_begin;
322 if (count($events)) {
323 $last_update_avg = $a_begin - 1;
324 $slot_seconds = self::SLOT_SIZE * 60;
329 foreach ($events as $ts => $actions) {
331 foreach ($actions as $action) {
343 if ($active_end > $active_max) {
344 $active_max = $active_end;
348 if ($active_end < $active_min) {
349 $active_min = $active_end;
353 $diff = $ts - $last_update_avg;
354 $active_avg += $diff / $slot_seconds * $active_end;
355 $last_update_avg = $ts;
359 if ($last_update_avg < $a_end) {
360 $diff = $a_end - $last_update_avg;
361 $active_avg += $diff / $slot_seconds * $active_end;
364 $active_avg = round($active_avg);
370 "active_min" => array(
"integer", $active_min),
371 "active_max" => array(
"integer", $active_max),
372 "active_avg" => array(
"integer", $active_avg),
373 "active_end" => array(
"integer", $active_end),
374 "opened" => array(
"integer", $opened_counter),
378 "closed_misc" => array(
"integer", (
int) ($closed_counter[0] ?? 0)),
383 array(
"slot_begin" => array(
"integer", $a_begin),
384 "slot_end" => array(
"integer", $a_end))
397 $ilDB = $DIC[
'ilDB'];
400 $cut = $a_now - (60 * 60 * 24 * 7);
402 $ilDB->manipulate(
"DELETE FROM usr_session_stats_raw" .
403 " WHERE start_time <= " .
$ilDB->quote($cut,
"integer"));
413 $ilDB = $DIC[
'ilDB'];
415 $sql =
"SELECT SUM(opened) opened, SUM(closed_manual) closed_manual," .
416 " SUM(closed_expire) closed_expire," .
417 " SUM(closed_login) closed_login, SUM(closed_misc) closed_misc" .
418 " FROM usr_session_stats" .
419 " WHERE slot_end > " .
$ilDB->quote($a_from,
"integer") .
420 " AND slot_begin < " .
$ilDB->quote($a_to,
"integer");
428 public static function getActiveSessions(
int $a_from,
int $a_to): array
433 $ilDB = $DIC[
'ilDB'];
435 $sql =
"SELECT slot_begin, slot_end, active_min, active_max, active_avg" .
436 " FROM usr_session_stats" .
437 " WHERE slot_end > " .
$ilDB->quote($a_from,
"integer") .
438 " AND slot_begin < " .
$ilDB->quote($a_to,
"integer") .
439 " ORDER BY slot_begin";
444 foreach ($row as $key => $value) {
445 $entry[$key] = (
int) $value;
459 $ilDB = $DIC[
'ilDB'];
461 $sql =
"SELECT max(slot_end) latest FROM usr_session_stats";
464 if ($row[
"latest"]) {
465 return (
int) $row[
"latest"];
static getNumberOfActiveRawSessions(int $a_time)
Count number of active sessions at given time.
static getNumberOfSessionsByType(int $a_from, int $a_to)
Get session counters by type (opened, closed)
static deleteAggregatedRaw($a_now)
Remove already aggregated raw data.
insert(string $table_name, array $values)
static createRawEntry(string $a_session_id, int $a_session_type, int $a_timestamp, int $a_user_id)
Create raw data entry.
const SESSION_CLOSE_LOGIN
static aggretateRaw(int $a_now)
Aggregate raw session data (older than given time)
const SESSION_CLOSE_EXPIRE
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static aggregateRawHelper(int $a_begin, int $a_end)
Aggregate statistics data for one slot.
static getLastAggregation()
Get timestamp of last aggregation.
static getCurrentSlot(int $a_now)
Get next slot to aggregate.
static closeRawEntry($a_session_id, ?int $a_context=null, $a_expired_at=null)
Close raw data entry.
static getRawData(int $a_begin, int $a_end)
Read raw data for timespan.
static isActive()
Is session statistics active at all?
static array $session_types_controlled
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
static createNewAggregationSlot(int $a_now)
Create new slot (using table lock)