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)
    76     public static function closeRawEntry($a_session_id, ?
int $a_context = null, $a_expired_at = null): void
    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
 
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)