19 declare(strict_types=1);
65 $this->
ilCtrl = $DIC->ctrl();
66 $this->ilTabs = $DIC->tabs();
67 $this->
lng = $DIC->language();
68 $this->tpl = $DIC->ui()->mainTemplate();
69 $this->
toolbar = $DIC->toolbar();
71 $this->
access = $DIC->access();
72 $this->clientIniFile = $DIC->clientIni();
73 $this->
user = $DIC->user();
74 $this->
logger = $DIC->logger()->auth();
77 $kindlyTo = $DIC->refinery()->kindlyTo();
78 if (
$http->request()->getMethod() ===
'POST') {
79 if (
$http->wrapper()->post()->has(self::REQUEST_SMD)) {
80 $this->smd =
$http->wrapper()->post()->retrieve(self::REQUEST_SMD, $kindlyTo->int());
82 if (
$http->wrapper()->post()->has(self::REQUEST_SMM)) {
83 $this->smm =
$http->wrapper()->post()->retrieve(self::REQUEST_SMM, $kindlyTo->string());
85 if (
$http->wrapper()->post()->has(self::REQUEST_STO)) {
86 $this->sto =
$http->wrapper()->post()->retrieve(self::REQUEST_STO, $kindlyTo->string());
88 if (
$http->wrapper()->post()->has(self::REQUEST_SST)) {
89 $this->sst =
$http->wrapper()->post()->retrieve(self::REQUEST_SST, $kindlyTo->string());
92 if (
$http->wrapper()->query()->has(self::REQUEST_SMD)) {
93 $this->smd =
$http->wrapper()->query()->retrieve(self::REQUEST_SMD, $kindlyTo->int());
95 if (
$http->wrapper()->query()->has(self::REQUEST_SMM)) {
96 $this->smm =
$http->wrapper()->query()->retrieve(self::REQUEST_SMM, $kindlyTo->string());
98 if (
$http->wrapper()->query()->has(self::REQUEST_STO)) {
99 $this->sto =
$http->wrapper()->query()->retrieve(self::REQUEST_STO, $kindlyTo->string());
101 if (
$http->wrapper()->query()->has(self::REQUEST_SST)) {
102 $this->sst =
$http->wrapper()->query()->retrieve(self::REQUEST_SST, $kindlyTo->string());
105 if (
$http->wrapper()->query()->has(self::REQUEST_REF)) {
106 $this->ref_id =
$http->wrapper()->query()->retrieve(self::REQUEST_REF, $kindlyTo->int());
114 switch ($this->
ilCtrl->getNextClass()) {
116 $cmd = $this->
ilCtrl->getCmd(
'current');
125 $this->ilTabs->addSubTab(
127 $this->
lng->txt(
'trac_current_system_load'),
128 $this->
ilCtrl->getLinkTarget($this,
'current')
130 $this->ilTabs->addSubTab(
132 $this->
lng->txt(
'trac_short_system_load'),
133 $this->
ilCtrl->getLinkTarget($this,
'short')
135 $this->ilTabs->addSubTab(
137 $this->
lng->txt(
'trac_long_system_load'),
138 $this->
ilCtrl->getLinkTarget($this,
'long')
140 $this->ilTabs->addSubTab(
142 $this->
lng->txt(
'trac_periodic_system_load'),
143 $this->
ilCtrl->getLinkTarget($this,
'periodic')
147 protected function current(
bool $a_export =
false): void
149 $this->ilTabs->activateSubTab(
'current');
153 $mode = self::MODE_TODAY;
167 case self::MODE_TODAY:
168 $time_from = strtotime(
'today');
169 $time_to = strtotime(
'tomorrow') - 1;
170 $scale = self::SCALE_DAY;
173 case self::MODE_LAST_DAY:
175 $time_from = $time_to - 60 * 60 * 24;
176 $scale = self::SCALE_DAY;
179 case self::MODE_LAST_WEEK:
181 $time_from = $time_to - 60 * 60 * 24 * 7;
182 $scale = self::SCALE_WEEK;
185 case self::MODE_LAST_MONTH:
187 $time_from = $time_to - 60 * 60 * 24 * 30;
188 $scale = self::SCALE_MONTH;
193 self::MODE_TODAY => $this->
lng->txt(
'trac_session_statistics_mode_today'),
194 self::MODE_LAST_DAY => $this->
lng->txt(
'trac_session_statistics_mode_last_day'),
195 self::MODE_LAST_WEEK => $this->
lng->txt(
'trac_session_statistics_mode_last_week'),
196 self::MODE_LAST_MONTH => $this->
lng->txt(
'trac_session_statistics_mode_last_month')
199 $title = $this->
lng->txt(
'trac_current_system_load') .
' - ' . $mode_options[$mode];
204 $this->
toolbar->setFormAction($this->
ilCtrl->getFormAction($this,
'current'));
208 $mode_selector->setValue($mode);
209 $this->
toolbar->addInputItem($mode_selector,
true);
212 'avg' => $this->
lng->txt(
'trac_session_active_avg'),
213 'min' => $this->
lng->txt(
'trac_session_active_min'),
214 'max' => $this->
lng->txt(
'trac_session_active_max')
217 $measure_selector =
new ilSelectInputGUI(
' ' . $this->
lng->txt(
'trac_measure'),
'smm');
218 $measure_selector->
setOptions($measure_options);
219 $measure_selector->setValue($measure);
220 $this->
toolbar->addInputItem($measure_selector,
true);
222 $this->
toolbar->addFormButton($this->
lng->txt(
'ok'),
'current');
224 if (count(
$data[
'active'])) {
225 $this->
toolbar->addSeparator();
226 $this->
toolbar->addFormButton($this->
lng->txt(
'export'),
'currentExport');
229 $this->tpl->setContent($this->
render(
$data, $scale, $measure));
257 protected function short(
bool $a_export =
false): void
259 $this->ilTabs->activateSubTab(
'short');
263 $time_to = $this->
importDate((
string) $this->sst);
267 $mode = self::MODE_DAY;
282 $time_from = $time_to - 60 * 60 * 24;
283 $scale = self::SCALE_DAY;
286 case self::MODE_WEEK:
287 $time_from = $time_to - 60 * 60 * 24 * 7;
288 $scale = self::SCALE_WEEK;
293 self::MODE_DAY => $this->
lng->txt(
'trac_session_statistics_mode_day'),
294 self::MODE_WEEK => $this->
lng->txt(
'trac_session_statistics_mode_week')
297 $title = $this->
lng->txt(
'trac_short_system_load') .
' - ' . $mode_options[$mode];
302 $this->
toolbar->setFormAction($this->
ilCtrl->getFormAction($this,
'short'));
306 $this->
toolbar->addInputItem($start_selector,
true);
310 $mode_selector->setValue($mode);
311 $this->
toolbar->addInputItem($mode_selector,
true);
314 'avg' => $this->
lng->txt(
'trac_session_active_avg'),
315 'min' => $this->
lng->txt(
'trac_session_active_min'),
316 '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;
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);
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));
477 $left =
new ilTemplate(
'tpl.session_statistics_left.html',
true,
true,
'components/ILIAS/Authentication');
479 $left->setVariable(
'CAPTION_CURRENT', $this->
lng->txt(
'users_online'));
480 $left->setVariable(
'VALUE_CURRENT', $active);
482 $left->setVariable(
'CAPTION_LAST_AGGR', $this->
lng->txt(
'trac_last_aggregation'));
486 if ($this->
access->checkAccess(
'write',
'', $this->ref_id)) {
487 $left->setVariable(
'URL_SYNC', $this->
ilCtrl->getFormAction($this,
'adminSync'));
488 $left->setVariable(
'CMD_SYNC',
'adminSync');
489 $left->setVariable(
'TXT_SYNC', $this->
lng->txt(
'trac_sync_session_stats'));
495 protected function buildData(
int $a_time_from,
int $a_time_to,
string $a_title): array
500 $opened = (
int) $counters[
'opened'];
501 unset($counters[
'opened']);
509 $data[
'title'] = $a_title .
' (' .
515 $data[
'opened'] = [$this->
lng->txt(
'trac_sessions_opened'), $opened];
516 $data[
'closed'] = [$this->
lng->txt(
'trac_sessions_closed'), array_sum($counters)];
517 foreach ($counters as $type => $counter) {
518 $data[
'closed_details'][] = [$this->
lng->txt(
'trac_' . $type), (
int) $counter];
521 $data[
'active'] = ilSessionStatistics::getActiveSessions($a_time_from, $a_time_to);
522 $this->
logger->debug(
'Data to plot: ' . var_export(
$data,
true));
526 protected function render(array $a_data,
int $a_scale, ?
string $a_measure =
null): string
528 $center =
new ilTemplate(
'tpl.session_statistics_center.html',
true,
true,
'components/ILIAS/Authentication');
530 foreach ($a_data as $idx => $item) {
537 case 'closed_details':
538 $center->setCurrentBlock(
'closed_details');
539 foreach ($item as $detail) {
540 $center->setVariable(
'CAPTION_CLOSED_DETAILS', $detail[0]);
541 $center->setVariable(
'VALUE_CLOSED_DETAILS', $detail[1]);
542 $center->parseCurrentBlock();
547 $tpl_var = strtoupper($idx);
548 $center->setVariable(
'CAPTION_' . $tpl_var, $item[0]);
549 $center->setVariable(
'VALUE_' . $tpl_var, $item[1]);
554 if ($a_data[
'active']) {
555 $center->setVariable(
'CHART', $this->
getChart($a_data[
'active'], $a_data[
'title'], $a_scale, $a_measure));
557 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'trac_session_statistics_no_data'));
560 return $center->get();
569 int $a_scale = self::SCALE_DAY,
570 ?
string $a_measure =
null 573 $chart->setSize(
'700',
'500');
574 $chart->setYAxisToInteger(
true);
577 $chart->setLegend($legend);
580 $measures = [
'min',
'avg',
'max'];
582 $measures = [$a_measure];
591 $colors = $act_line = [];
592 foreach ($measures as $measure) {
594 $act_line[$measure]->setLineSteps(
true);
595 $act_line[$measure]->setLabel($this->
lng->txt(
'trac_session_active_' . $measure));
596 $colors[] = $colors_map[$measure];
599 $chart->setColors($colors);
603 $scale = ceil(count($chart_data) / 5);
605 foreach ($chart_data as $idx => $item) {
606 $date = $item[
'slot_begin'];
608 if ($a_scale === self::SCALE_PERIODIC_WEEK || !($idx % ceil($scale))) {
610 case self::SCALE_DAY:
611 $labels[$date] = date(
'H:i', $date);
614 case self::SCALE_WEEK:
615 $labels[$date] = date(
'd.m. H', $date) .
'h';
618 case self::SCALE_MONTH:
619 $labels[$date] = date(
'd.m.', $date);
622 case self::SCALE_YEAR:
623 $labels[$date] = date(
'Y-m', $date);
626 case self::SCALE_PERIODIC_WEEK:
627 $day = substr((
string) $date, 0, 1);
628 $hour = substr((
string) $date, 1, 2);
629 $min = substr((
string) $date, 3, 2);
632 $day_value = ($day - 1) * 60 * 60 * 24;
633 $date = $day_value + $hour * 60 * 60 + $min * 60;
636 if ((!isset($old_hour) || $hour != $old_hour) && $hour && $hour % 6 == 0) {
637 $labels[$date] = $hour;
641 if (!isset($old_day) || $day != $old_day) {
649 foreach ($measures as $measure) {
650 $value = (
int) $item[
'active_' . $measure];
651 $act_line[$measure]->addPoint($date, $value);
655 foreach ($act_line as $line) {
656 $chart->addData($line);
659 $chart->setTicks($labels,
null,
true);
661 return $chart->getHTML();
668 case self::SCALE_DAY:
672 case self::SCALE_WEEK:
678 foreach ($a_data as $item) {
679 $date_parts = getdate($item[
'slot_begin']);
684 case self::SCALE_MONTH:
686 $slot = mktime($date_parts[
'hours'], 0, 0, $date_parts[
'mon'], $date_parts[
'mday'], $date_parts[
'year']);
689 case self::SCALE_YEAR:
691 $slot = mktime(0, 0, 1, $date_parts[
'mon'], $date_parts[
'mday'], $date_parts[
'year']);
694 case self::SCALE_PERIODIC_WEEK:
696 $day = $date_parts[
'wday'];
700 $slot = $day . date(
'His', $item[
'slot_begin']);
705 foreach ($item as
$id => $value) {
706 switch (substr((
string)
$id, -3)) {
708 if (!isset($tmp[$slot][$id]) || $value < $tmp[$slot][$id]) {
709 $tmp[$slot][
$id] = $value;
714 if (!isset($tmp[$slot][$id]) || $value > $tmp[$slot][$id]) {
715 $tmp[$slot][
$id] = $value;
720 $tmp[$slot][
$id][] = $value;
726 foreach ($tmp as $slot => $attr) {
727 $tmp[$slot][
'active_avg'] = (
int) round(array_sum($attr[
'active_avg']) / count($attr[
'active_avg']));
728 $tmp[$slot][
'slot_begin'] = $slot;
731 return array_values($tmp);
741 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'trac_sync_session_stats_success'),
true);
742 $this->
ilCtrl->redirect($this);
745 protected function exportCSV(array $a_data, $a_scale): never
750 $csv->setSeparator(
';');
756 $this->
lng->txt(
'trac_name_of_installation') => $this->clientIniFile->readVariable(
'client',
'name'),
758 $this->
lng->txt(
'trac_report_owner') => $this->
user->getFullName(),
760 foreach ($a_data as $idx => $item) {
763 $meta[$this->
lng->txt(
'title')] = $item;
770 case 'closed_details':
771 foreach ($item as $detail) {
772 $meta[$a_data[
'closed'][0] .
' - ' . $detail[0]] = $detail[1];
777 $meta[$item[0]] = $item[1];
781 foreach ($meta as $caption => $value) {
782 $csv->addColumn(strip_tags((
string) $caption));
783 $csv->addColumn(strip_tags((
string) $value));
793 $first = array_keys(array_shift($first));
794 foreach ($first as $column) {
796 if ($a_scale === self::SCALE_PERIODIC_WEEK && $column ===
'slot_begin') {
797 $csv->addColumn(
'weekday');
798 $csv->addColumn(
'time');
800 $csv->addColumn(strip_tags((
string) $column));
806 foreach ($aggr_data as $row) {
807 foreach ($row as $column => $value) {
808 if (is_array($value)) {
809 $value = implode(
', ', $value);
814 if ($a_scale === self::SCALE_PERIODIC_WEEK) {
816 $value = substr((
string) $value, 1, 2) .
':' . substr((
string) $value, 3, 2);
823 $value = date(
'd.m.Y H:i', $value);
826 $csv->addColumn(strip_tags((
string) $value));
832 $filename =
'session_statistics_' . date(
'Ymd', $now) .
'.csv';
833 header(
'Content-type: text/comma-separated-values');
834 header(
'Content-Disposition: attachment; filename="' .
$filename .
'"');
836 header(
'Cache-Control: must-revalidate, post-check=0,pre-check=0');
838 echo $csv->getCSVString();
static array static setUseRelativeDates(bool $a_status)
set use relative dates
exportCSV(array $a_data, $a_scale)
static getNumberOfSessionsByType(int $a_from, int $a_to)
Get session counters by type (opened, closed)
static parseIncomingDate($value, bool $add_time=false)
Try to parse incoming value to date object.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _destroyExpiredSessions()
Destroy expired sessions.
const int SCALE_PERIODIC_WEEK
static aggretateRaw(int $a_now)
Aggregate raw session data (older than given time)
adaptDataToScale(int $a_scale, array $a_data)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
ilGlobalTemplateInterface $tpl
static _numericDayToString(int $a_day, bool $a_long=true, ?ilLanguage $lng=null)
static getLastAggregation()
Get timestamp of last aggregation.
importDate(string $a_incoming, ?int $a_default=null)
const int MODE_LAST_MONTH
render(array $a_data, int $a_scale, ?string $a_measure=null)
static getExistingSessionCount(array $a_types)
static array $session_types_controlled
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
getChart(array $a_data, string $a_title, int $a_scale=self::SCALE_DAY, ?string $a_measure=null)
Build chart for active sessions.
current(bool $a_export=false)
periodic($a_export=false)
short(bool $a_export=false)
buildData(int $a_time_from, int $a_time_to, string $a_title)
static formatPeriod(ilDateTime $start, ilDateTime $end, bool $a_skip_starting_day=false, ?ilObjUser $user=null)
Format a period of two dates Shows: 14.
static getInstanceByType(int $a_type, string $a_id)