19 declare(strict_types=1);
60 private ?
string $smm = null;
61 private ?
string $sst = null;
62 private ?
string $sto = null;
68 $this->
ilCtrl = $DIC->ctrl();
69 $this->ilTabs = $DIC->tabs();
70 $this->
lng = $DIC->language();
71 $this->tpl = $DIC->ui()->mainTemplate();
72 $this->
toolbar = $DIC->toolbar();
74 $this->
access = $DIC->access();
75 $this->clientIniFile = $DIC->clientIni();
76 $this->
user = $DIC->user();
77 $this->
logger = $DIC->logger()->auth();
80 $kindlyTo = $DIC->refinery()->kindlyTo();
81 if (
$http->request()->getMethod() ===
"POST") {
82 if (
$http->wrapper()->post()->has(self::REQUEST_SMD)) {
83 $this->smd =
$http->wrapper()->post()->retrieve(self::REQUEST_SMD, $kindlyTo->int());
85 if (
$http->wrapper()->post()->has(self::REQUEST_SMM)) {
86 $this->smm =
$http->wrapper()->post()->retrieve(self::REQUEST_SMM, $kindlyTo->string());
88 if (
$http->wrapper()->post()->has(self::REQUEST_STO)) {
89 $this->sto =
$http->wrapper()->post()->retrieve(self::REQUEST_STO, $kindlyTo->string());
91 if (
$http->wrapper()->post()->has(self::REQUEST_SST)) {
92 $this->sst =
$http->wrapper()->post()->retrieve(self::REQUEST_SST, $kindlyTo->string());
95 if (
$http->wrapper()->query()->has(self::REQUEST_SMD)) {
96 $this->smd =
$http->wrapper()->query()->retrieve(self::REQUEST_SMD, $kindlyTo->int());
98 if (
$http->wrapper()->query()->has(self::REQUEST_SMM)) {
99 $this->smm =
$http->wrapper()->query()->retrieve(self::REQUEST_SMM, $kindlyTo->string());
101 if (
$http->wrapper()->query()->has(self::REQUEST_STO)) {
102 $this->sto =
$http->wrapper()->query()->retrieve(self::REQUEST_STO, $kindlyTo->string());
104 if (
$http->wrapper()->query()->has(self::REQUEST_SST)) {
105 $this->sst =
$http->wrapper()->query()->retrieve(self::REQUEST_SST, $kindlyTo->string());
108 if (
$http->wrapper()->query()->has(self::REQUEST_REF)) {
109 $this->ref_id =
$http->wrapper()->query()->retrieve(self::REQUEST_REF, $kindlyTo->int());
117 switch ($this->
ilCtrl->getNextClass()) {
119 $cmd = $this->
ilCtrl->getCmd(
"current");
128 $this->ilTabs->addSubTab(
130 $this->
lng->txt(
"trac_current_system_load"),
131 $this->
ilCtrl->getLinkTarget($this,
"current")
133 $this->ilTabs->addSubTab(
135 $this->
lng->txt(
"trac_short_system_load"),
136 $this->
ilCtrl->getLinkTarget($this,
"short")
138 $this->ilTabs->addSubTab(
140 $this->
lng->txt(
"trac_long_system_load"),
141 $this->
ilCtrl->getLinkTarget($this,
"long")
143 $this->ilTabs->addSubTab(
145 $this->
lng->txt(
"trac_periodic_system_load"),
146 $this->
ilCtrl->getLinkTarget($this,
"periodic")
150 protected function current(
bool $a_export =
false): void
152 $this->ilTabs->activateSubTab(
"current");
156 $mode = self::MODE_TODAY;
170 case self::MODE_TODAY:
171 $time_from = strtotime(
"today");
172 $time_to = strtotime(
"tomorrow") - 1;
173 $scale = self::SCALE_DAY;
176 case self::MODE_LAST_DAY:
178 $time_from = $time_to - 60 * 60 * 24;
179 $scale = self::SCALE_DAY;
182 case self::MODE_LAST_WEEK:
184 $time_from = $time_to - 60 * 60 * 24 * 7;
185 $scale = self::SCALE_WEEK;
188 case self::MODE_LAST_MONTH:
190 $time_from = $time_to - 60 * 60 * 24 * 30;
191 $scale = self::SCALE_MONTH;
195 $mode_options = array(
196 self::MODE_TODAY => $this->
lng->txt(
"trac_session_statistics_mode_today"),
197 self::MODE_LAST_DAY => $this->
lng->txt(
"trac_session_statistics_mode_last_day"),
198 self::MODE_LAST_WEEK => $this->
lng->txt(
"trac_session_statistics_mode_last_week"),
199 self::MODE_LAST_MONTH => $this->
lng->txt(
"trac_session_statistics_mode_last_month"));
201 $title = $this->
lng->txt(
"trac_current_system_load") .
" - " . $mode_options[$mode];
206 $this->
toolbar->setFormAction($this->
ilCtrl->getFormAction($this,
"current"));
209 $mode_selector->setOptions($mode_options);
210 $mode_selector->setValue($mode);
211 $this->
toolbar->addInputItem($mode_selector,
true);
213 $measure_options = array(
214 "avg" => $this->
lng->txt(
"trac_session_active_avg"),
215 "min" => $this->
lng->txt(
"trac_session_active_min"),
216 "max" => $this->
lng->txt(
"trac_session_active_max"));
218 $measure_selector =
new ilSelectInputGUI(
" " . $this->
lng->txt(
"trac_measure"),
"smm");
219 $measure_selector->setOptions($measure_options);
220 $measure_selector->setValue($measure);
221 $this->
toolbar->addInputItem($measure_selector,
true);
223 $this->
toolbar->addFormButton($this->
lng->txt(
"ok"),
"current");
225 if (count(
$data[
"active"])) {
226 $this->
toolbar->addSeparator();
227 $this->
toolbar->addFormButton($this->
lng->txt(
"export"),
"currentExport");
230 $this->tpl->setContent($this->
render(
$data, $scale, $measure));
246 protected function importDate(
string $a_incoming,
int $a_default = null)
258 protected function short(
bool $a_export =
false): void
260 $this->ilTabs->activateSubTab(
"short");
264 $time_to = $this->
importDate((
string) $this->sst);
268 $mode = self::MODE_DAY;
283 $time_from = $time_to - 60 * 60 * 24;
284 $scale = self::SCALE_DAY;
287 case self::MODE_WEEK:
288 $time_from = $time_to - 60 * 60 * 24 * 7;
289 $scale = self::SCALE_WEEK;
293 $mode_options = array(
294 self::MODE_DAY => $this->
lng->txt(
"trac_session_statistics_mode_day"),
295 self::MODE_WEEK => $this->
lng->txt(
"trac_session_statistics_mode_week")
298 $title = $this->
lng->txt(
"trac_short_system_load") .
" - " . $mode_options[$mode];
303 $this->
toolbar->setFormAction($this->
ilCtrl->getFormAction($this,
"short"));
307 $this->
toolbar->addInputItem($start_selector,
true);
310 $mode_selector->setOptions($mode_options);
311 $mode_selector->setValue($mode);
312 $this->
toolbar->addInputItem($mode_selector,
true);
314 $measure_options = array(
315 "avg" => $this->
lng->txt(
"trac_session_active_avg"),
316 "min" => $this->
lng->txt(
"trac_session_active_min"),
317 "max" => $this->
lng->txt(
"trac_session_active_max"));
319 $measure_selector =
new ilSelectInputGUI(
" " . $this->
lng->txt(
"trac_measure"),
"smm");
320 $measure_selector->setOptions($measure_options);
321 $measure_selector->setValue($measure);
322 $this->
toolbar->addInputItem($measure_selector,
true);
324 $this->
toolbar->addFormButton($this->
lng->txt(
"ok"),
"short");
326 if (count(
$data[
"active"])) {
327 $this->
toolbar->addSeparator();
328 $this->
toolbar->addFormButton($this->
lng->txt(
"export"),
"shortExport");
331 $this->tpl->setContent($this->
render(
$data, $scale, $measure));
342 protected function long($a_export =
false): void
344 $this->ilTabs->activateSubTab(
"long");
348 $time_to = $this->
importDate((
string) $this->sst);
352 $mode = self::MODE_WEEK;
359 case self::MODE_WEEK:
360 $time_from = $time_to - 60 * 60 * 24 * 7;
361 $scale = self::SCALE_WEEK;
364 case self::MODE_MONTH:
365 $time_from = $time_to - 60 * 60 * 24 * 30;
366 $scale = self::SCALE_MONTH;
369 case self::MODE_YEAR:
370 $time_from = $time_to - 60 * 60 * 24 * 365;
371 $scale = self::SCALE_YEAR;
375 $mode_options = array(
376 self::MODE_WEEK => $this->
lng->txt(
"trac_session_statistics_mode_week"),
377 self::MODE_MONTH => $this->
lng->txt(
"trac_session_statistics_mode_month"),
378 self::MODE_YEAR => $this->
lng->txt(
"trac_session_statistics_mode_year")
381 $title = $this->
lng->txt(
"trac_long_system_load") .
" - " . $mode_options[$mode];
386 $this->
toolbar->setFormAction($this->
ilCtrl->getFormAction($this,
"long"));
390 $this->
toolbar->addInputItem($start_selector,
true);
393 $mode_selector->setOptions($mode_options);
394 $mode_selector->setValue($mode);
395 $this->
toolbar->addInputItem($mode_selector,
true);
397 $this->
toolbar->addFormButton($this->
lng->txt(
"ok"),
"long");
399 if (count(
$data[
"active"])) {
400 $this->
toolbar->addSeparator();
401 $this->
toolbar->addFormButton($this->
lng->txt(
"export"),
"longExport");
404 $this->tpl->setContent($this->
render(
$data, $scale));
415 protected function periodic($a_export =
false): void
417 $this->ilTabs->activateSubTab(
"periodic");
421 $time_to = $this->
importDate((
string) $this->sst);
424 $time_from = $this->
importDate((
string) $this->sto, strtotime(
"-7 days"));
427 if ($time_to < $time_from) {
429 $time_to = $time_from;
433 $title = $this->
lng->txt(
"trac_periodic_system_load");
438 $this->
toolbar->setFormAction($this->
ilCtrl->getFormAction($this,
"periodic"));
442 $this->
toolbar->addInputItem($end_selector,
true);
446 $this->
toolbar->addInputItem($start_selector,
true);
448 $this->
toolbar->addFormButton($this->
lng->txt(
"ok"),
"periodic");
450 if (count(
$data[
"active"])) {
451 $this->
toolbar->addSeparator();
452 $this->
toolbar->addFormButton($this->
lng->txt(
"export"),
"periodicExport");
455 $this->tpl->setContent($this->
render(
$data, self::SCALE_PERIODIC_WEEK));
472 $control_active = ((
int) $this->
settings->get(
'session_handling_type',
"0") === 1);
473 if ($control_active) {
486 $left =
new ilTemplate(
"tpl.session_statistics_left.html",
true,
true,
"Services/Authentication");
488 $left->setVariable(
"CAPTION_CURRENT", $this->
lng->txt(
"users_online"));
489 $left->setVariable(
"VALUE_CURRENT", $active);
491 $left->setVariable(
"CAPTION_LAST_AGGR", $this->
lng->txt(
"trac_last_aggregation"));
494 $left->setVariable(
"CAPTION_LAST_MAX", $this->
lng->txt(
"trac_last_maxed_out_sessions"));
497 $left->setVariable(
"CAPTION_SESSION_CONTROL", $this->
lng->txt(
"sess_load_dependent_session_handling"));
498 if (!$control_active) {
499 $left->setVariable(
"VALUE_SESSION_CONTROL", $this->
lng->txt(
"no"));
501 $left->setVariable(
"VALUE_SESSION_CONTROL", $this->
lng->txt(
"yes"));
503 $left->setCurrentBlock(
"control_details");
505 $left->setVariable(
"CAPTION_SESSION_CONTROL_LIMIT", $this->
lng->txt(
"session_max_count"));
506 $left->setVariable(
"VALUE_SESSION_CONTROL_LIMIT", $control_max_sessions);
508 $left->setVariable(
"CAPTION_SESSION_CONTROL_IDLE_MIN", $this->
lng->txt(
"session_min_idle"));
509 $left->setVariable(
"VALUE_SESSION_CONTROL_IDLE_MIN", $control_min_idle);
511 $left->setVariable(
"CAPTION_SESSION_CONTROL_IDLE_MAX", $this->
lng->txt(
"session_max_idle"));
512 $left->setVariable(
"VALUE_SESSION_CONTROL_IDLE_MAX", $control_max_idle);
514 $left->setVariable(
"CAPTION_SESSION_CONTROL_IDLE_FIRST", $this->
lng->txt(
"session_max_idle_after_first_request"));
515 $left->setVariable(
"VALUE_SESSION_CONTROL_IDLE_FIRST", $control_max_idle_first);
517 $left->parseCurrentBlock();
521 if ($this->
access->checkAccess(
"write",
"", $this->ref_id)) {
522 $left->setVariable(
"URL_SYNC", $this->
ilCtrl->getFormAction($this,
"adminSync"));
523 $left->setVariable(
"CMD_SYNC",
"adminSync");
524 $left->setVariable(
"TXT_SYNC", $this->
lng->txt(
"trac_sync_session_stats"));
530 protected function buildData(
int $a_time_from,
int $a_time_to,
string $a_title): array
536 $opened = (
int) $counters[
"opened"];
537 $closed_limit = (
int) $counters[
"closed_limit"];
538 unset($counters[
"opened"], $counters[
"closed_limit"]);
546 $data[
"title"] = $a_title .
" (" .
552 $data[
"maxed_out_time"] = array($this->
lng->txt(
"trac_maxed_out_time"), $maxed_out_duration);
553 $data[
"maxed_out_counter"] = array($this->
lng->txt(
"trac_maxed_out_counter"), $closed_limit);
554 $data[
"opened"] = array($this->
lng->txt(
"trac_sessions_opened"), $opened);
555 $data[
"closed"] = array($this->
lng->txt(
"trac_sessions_closed"), array_sum($counters));
556 foreach ($counters as
$type => $counter) {
557 $data[
"closed_details"][] = array($this->
lng->txt(
"trac_" .
$type), (
int) $counter);
560 $data[
"active"] = ilSessionStatistics::getActiveSessions($a_time_from, $a_time_to);
561 $this->
logger->debug(
"Data to plot: " . var_export($data,
true));
565 protected function render(array $a_data,
int $a_scale,
string $a_measure = null): string
567 $center =
new ilTemplate(
"tpl.session_statistics_center.html",
true,
true,
"Services/Authentication");
569 foreach ($a_data as $idx => $item) {
576 case "closed_details":
577 $center->setCurrentBlock(
"closed_details");
578 foreach ($item as $detail) {
579 $center->setVariable(
"CAPTION_CLOSED_DETAILS", $detail[0]);
580 $center->setVariable(
"VALUE_CLOSED_DETAILS", $detail[1]);
581 $center->parseCurrentBlock();
586 $tpl_var = strtoupper($idx);
587 $center->setVariable(
"CAPTION_" . $tpl_var, $item[0]);
588 $center->setVariable(
"VALUE_" . $tpl_var, $item[1]);
593 if ($a_data[
"active"]) {
594 $center->setVariable(
"CHART", $this->
getChart($a_data[
"active"], $a_data[
"title"], $a_scale, $a_measure));
596 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
"trac_session_statistics_no_data"));
599 return $center->get();
605 protected function getChart(array $a_data,
string $a_title,
int $a_scale = self::SCALE_DAY,
string $a_measure = null): string
608 $chart->setSize(
"700",
"500");
609 $chart->setYAxisToInteger(
true);
612 $chart->setLegend($legend);
615 $measures = [
"min",
"avg",
"max"];
617 $measures = [$a_measure];
620 $colors_map = array(
"min" =>
"#00cc00",
624 $colors = $act_line = array();
625 foreach ($measures as $measure) {
627 $act_line[$measure]->setLineSteps(
true);
628 $act_line[$measure]->setLabel($this->
lng->txt(
"trac_session_active_" . $measure));
629 $colors[] = $colors_map[$measure];
632 if ($a_scale === self::SCALE_DAY || $a_scale === self::SCALE_WEEK) {
634 $max_line->setLabel($this->
lng->txt(
"session_max_count"));
635 $colors[] =
"#cc0000";
638 $chart->setColors($colors);
642 $scale = ceil(count($chart_data) / 5);
644 foreach ($chart_data as $idx => $item) {
645 $date = $item[
"slot_begin"];
647 if ($a_scale === self::SCALE_PERIODIC_WEEK || !($idx % ceil($scale))) {
649 case self::SCALE_DAY:
650 $labels[$date] = date(
"H:i", $date);
653 case self::SCALE_WEEK:
654 $labels[$date] = date(
"d.m. H", $date) .
"h";
657 case self::SCALE_MONTH:
658 $labels[$date] = date(
"d.m.", $date);
661 case self::SCALE_YEAR:
662 $labels[$date] = date(
"Y-m", $date);
665 case self::SCALE_PERIODIC_WEEK:
666 $day = substr((
string) $date, 0, 1);
667 $hour = substr((
string) $date, 1, 2);
668 $min = substr((
string) $date, 3, 2);
671 $day_value = ($day - 1) * 60 * 60 * 24;
672 $date = $day_value + $hour * 60 * 60 + $min * 60;
675 if ((!isset($old_hour) || $hour != $old_hour) && $hour && $hour % 6 == 0) {
676 $labels[$date] = $hour;
680 if (!isset($old_day) || $day != $old_day) {
688 foreach ($measures as $measure) {
689 $value = (
int) $item[
"active_" . $measure];
690 $act_line[$measure]->addPoint($date, $value);
693 if (isset($max_line)) {
694 $max_line->addPoint($date, (
int) $item[
"max_sessions"]);
698 foreach ($act_line as $line) {
699 $chart->addData($line);
701 if (isset($max_line)) {
702 $chart->addData($max_line);
705 $chart->setTicks($labels, null,
true);
707 return $chart->getHTML();
714 case self::SCALE_DAY:
718 case self::SCALE_WEEK:
724 foreach ($a_data as $item) {
725 $date_parts = getdate($item[
"slot_begin"]);
730 case self::SCALE_MONTH:
732 $slot = mktime($date_parts[
"hours"], 0, 0, $date_parts[
"mon"], $date_parts[
"mday"], $date_parts[
"year"]);
735 case self::SCALE_YEAR:
737 $slot = mktime(0, 0, 1, $date_parts[
"mon"], $date_parts[
"mday"], $date_parts[
"year"]);
740 case self::SCALE_PERIODIC_WEEK:
742 $day = $date_parts[
"wday"];
746 $slot = $day . date(
"His", $item[
"slot_begin"]);
751 foreach ($item as
$id => $value) {
752 switch (substr((
string)
$id, -3)) {
754 if (!isset($tmp[$slot][$id]) || $value < $tmp[$slot][$id]) {
755 $tmp[$slot][
$id] = $value;
760 if (!isset($tmp[$slot][$id]) || $value > $tmp[$slot][$id]) {
761 $tmp[$slot][
$id] = $value;
766 $tmp[$slot][
$id][] = $value;
772 foreach ($tmp as $slot => $attr) {
773 $tmp[$slot][
"active_avg"] = (
int) round(array_sum($attr[
"active_avg"]) / count($attr[
"active_avg"]));
774 $tmp[$slot][
"slot_begin"] = $slot;
777 return array_values($tmp);
787 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
"trac_sync_session_stats_success"),
true);
788 $this->
ilCtrl->redirect($this);
791 protected function exportCSV(array $a_data, $a_scale): void
796 $csv->setSeparator(
";");
802 $this->
lng->txt(
"trac_name_of_installation") => $this->clientIniFile->readVariable(
'client',
'name'),
804 $this->
lng->txt(
"trac_report_owner") => $this->
user->getFullName(),
806 foreach ($a_data as $idx => $item) {
809 $meta[$this->
lng->txt(
"title")] = $item;
816 case "closed_details":
817 foreach ($item as $detail) {
818 $meta[$a_data[
"closed"][0] .
" - " . $detail[0]] = $detail[1];
823 $meta[$item[0]] = $item[1];
827 foreach ($meta as $caption => $value) {
828 $csv->addColumn(strip_tags((
string) $caption));
829 $csv->addColumn(strip_tags((
string) $value));
839 $first = array_keys(array_shift($first));
840 foreach ($first as $column) {
842 if ($a_scale === self::SCALE_PERIODIC_WEEK && $column ===
"slot_begin") {
843 $csv->addColumn(
"weekday");
844 $csv->addColumn(
"time");
846 $csv->addColumn(strip_tags((
string) $column));
852 foreach ($aggr_data as $row) {
853 foreach ($row as $column => $value) {
854 if (is_array($value)) {
855 $value = implode(
', ', $value);
860 if ($a_scale === self::SCALE_PERIODIC_WEEK) {
862 $value = substr((
string) $value, 1, 2) .
":" . substr((
string) $value, 3, 2);
869 $value = date(
"d.m.Y H:i", $value);
872 $csv->addColumn(strip_tags((
string) $value));
878 $filename =
"session_statistics_" . date(
"Ymd", $now) .
".csv";
879 header(
"Content-type: text/comma-separated-values");
880 header(
"Content-Disposition: attachment; filename=\"" .
$filename .
"\"");
881 header(
"Expires: 0");
882 header(
"Cache-Control: must-revalidate, post-check=0,pre-check=0");
883 header(
"Pragma: public");
884 echo $csv->getCSVString();
const DEFAULT_MAX_COUNT
default value for settings that have not been defined in setup or administration yet ...
exportCSV(array $a_data, $a_scale)
static getNumberOfSessionsByType(int $a_from, int $a_to)
Get session counters by type (opened, closed)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const SCALE_PERIODIC_WEEK
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
render(array $a_data, int $a_scale, string $a_measure=null)
static _destroyExpiredSessions()
Destroy expired sessions.
static aggretateRaw(int $a_now)
Aggregate raw session data (older than given time)
getChart(array $a_data, string $a_title, int $a_scale=self::SCALE_DAY, string $a_measure=null)
Build chart for active sessions.
adaptDataToScale(int $a_scale, array $a_data)
ilGlobalTemplateInterface $tpl
static getLastAggregation()
Get timestamp of last aggregation.
importDate(string $a_incoming, int $a_default=null)
static _numericDayToString(int $a_day, bool $a_long=true)
static getExistingSessionCount(array $a_types)
returns number of valid sessions relating to given session types
static getMaxedOutDuration(int $a_from, int $a_to)
Get maxed out duration in given timeframe.
static array $session_types_controlled
static formatPeriod(ilDateTime $start, ilDateTime $end, bool $a_skip_starting_day=false)
Format a period of two dates Shows: 14.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
current(bool $a_export=false)
static parseIncomingDate($a_value, bool $a_add_time=false)
Try to parse incoming value to date object.
periodic($a_export=false)
static setUseRelativeDates(bool $a_status)
set use relative dates
static getLastMaxedOut()
Get latest slot during which sessions were maxed out.
short(bool $a_export=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
buildData(int $a_time_from, int $a_time_to, string $a_title)
const DEFAULT_MAX_IDLE_AFTER_FIRST_REQUEST
static getInstanceByType(int $a_type, string $a_id)