ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilSessionStatisticsGUI.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 include_once "Services/Authentication/classes/class.ilSessionStatistics.php";
6 
16 {
17  const MODE_TODAY = 1;
18  const MODE_LAST_DAY = 2;
19  const MODE_LAST_WEEK = 3;
20  const MODE_LAST_MONTH = 4;
21  const MODE_DAY = 5;
22  const MODE_WEEK = 6;
23  const MODE_MONTH = 7;
24  const MODE_YEAR = 8;
25 
26  const SCALE_DAY = 1;
27  const SCALE_WEEK = 2;
28  const SCALE_MONTH = 3;
29  const SCALE_YEAR = 4;
31 
32  function executeCommand()
33  {
34  global $ilCtrl;
35 
36  $this->setSubTabs();
37 
38  switch($ilCtrl->getNextClass())
39  {
40  default:
41  $cmd = $ilCtrl->getCmd("current");
42  $this->$cmd();
43  }
44 
45  return true;
46  }
47 
48  protected function setSubTabs()
49  {
50  global $ilTabs, $ilCtrl, $lng;
51 
52  $ilTabs->addSubTab("current", $lng->txt("trac_current_system_load"),
53  $ilCtrl->getLinkTarget($this, "current"));
54  $ilTabs->addSubTab("short", $lng->txt("trac_short_system_load"),
55  $ilCtrl->getLinkTarget($this, "short"));
56  $ilTabs->addSubTab("long", $lng->txt("trac_long_system_load"),
57  $ilCtrl->getLinkTarget($this, "long"));
58  $ilTabs->addSubTab("periodic", $lng->txt("trac_periodic_system_load"),
59  $ilCtrl->getLinkTarget($this, "periodic"));
60  }
61 
62  protected function current($a_export = false)
63  {
64  global $tpl, $ilToolbar, $ilCtrl, $ilTabs, $lng;
65 
66  $ilTabs->activateSubTab("current");
67 
68  // current mode
69  if(!$_REQUEST["smd"])
70  {
71  $_REQUEST["smd"] = self::MODE_TODAY;
72  }
73  $mode = (int)$_REQUEST["smd"];
74 
75  // current measure
76  if(!$_REQUEST["smm"])
77  {
78  $_REQUEST["smm"] = "avg";
79  }
80  $measure = (string)$_REQUEST["smm"];
81 
82 
83  switch($mode)
84  {
85  case self::MODE_TODAY:
86  $time_from = strtotime("today");
87  $time_to = strtotime("tomorrow")-1;
88  $scale = self::SCALE_DAY;
89  break;
90 
91  case self::MODE_LAST_DAY:
92  $time_to = time();
93  $time_from = $time_to-60*60*24;
94  $scale = self::SCALE_DAY;
95  break;
96 
97  case self::MODE_LAST_WEEK:
98  $time_to = time();
99  $time_from = $time_to-60*60*24*7;
100  $scale = self::SCALE_WEEK;
101  break;
102 
103  case self::MODE_LAST_MONTH:
104  $time_to = time();
105  $time_from = $time_to-60*60*24*30;
106  $scale = self::SCALE_MONTH;
107  break;
108  }
109 
110  $mode_options = array(
111  self::MODE_TODAY => $lng->txt("trac_session_statistics_mode_today"),
112  self::MODE_LAST_DAY => $lng->txt("trac_session_statistics_mode_last_day"),
113  self::MODE_LAST_WEEK => $lng->txt("trac_session_statistics_mode_last_week"),
114  self::MODE_LAST_MONTH => $lng->txt("trac_session_statistics_mode_last_month"));
115 
116  $title = $lng->txt("trac_current_system_load")." - ".$mode_options[$mode];
117  $data = $this->buildData($time_from, $time_to, $title);
118 
119  if(!$a_export)
120  {
121  // toolbar
122  include_once "Services/Form/classes/class.ilPropertyFormGUI.php";
123  $ilToolbar->setFormAction($ilCtrl->getFormAction($this, "current"));
124 
125  $mode_selector = new ilSelectInputGUI("&nbsp;".$lng->txt("trac_scale"), "smd");
126  $mode_selector->setOptions($mode_options);
127  $mode_selector->setValue($mode);
128  $ilToolbar->addInputItem($mode_selector, true);
129 
130  $measure_options = array(
131  "avg" => $lng->txt("trac_session_active_avg"),
132  "min" => $lng->txt("trac_session_active_min"),
133  "max" => $lng->txt("trac_session_active_max"));
134 
135  $measure_selector = new ilSelectInputGUI("&nbsp;".$lng->txt("trac_measure"), "smm");
136  $measure_selector->setOptions($measure_options);
137  $measure_selector->setValue($measure);
138  $ilToolbar->addInputItem($measure_selector, true);
139 
140  $ilToolbar->addFormButton($lng->txt("ok"), "current");
141 
142  if(sizeof($data["active"]))
143  {
144  $ilToolbar->addSeparator();
145  $ilToolbar->addFormButton($lng->txt("export"), "currentExport");
146  }
147 
148  $tpl->setContent($this->render($data, $scale, $measure));
149 
150  $tpl->setLeftContent($this->renderCurrentBasics());
151  }
152  else
153  {
154  $this->exportCSV($data, $scale);
155  }
156  }
157 
158  protected function currentExport()
159  {
160  $this->current(true);
161  }
162 
163  protected function short($a_export = false)
164  {
165  global $tpl, $ilToolbar, $ilCtrl, $ilTabs, $lng;
166 
167  $ilTabs->activateSubTab("short");
168 
169  // current start
170  if(!$_REQUEST["sst"])
171  {
172  $_REQUEST["sst"] = date("Ymd");
173  }
174  else
175  {
176  $org = $_REQUEST["sst"]["date"];
177  $_REQUEST["sst"] = $org["y"].
178  str_pad($org["m"], 2, "0", STR_PAD_LEFT).
179  str_pad($org["d"], 2, "0", STR_PAD_LEFT);
180  }
181  $start = (int)$_REQUEST["sst"];
182 
183  // current mode
184  if(!$_REQUEST["smd"])
185  {
186  $_REQUEST["smd"] = self::MODE_DAY;
187  }
188  $mode = (int)$_REQUEST["smd"];
189 
190  // current measure
191  if(!$_REQUEST["smm"])
192  {
193  $_REQUEST["smm"] = "avg";
194  }
195  $measure = (string)$_REQUEST["smm"];
196 
197 
198  $time_to = mktime(23, 59, 59, substr($start, 4, 2), substr($start, 6, 2),
199  substr($start, 0, 4));
200  switch($mode)
201  {
202  case self::MODE_DAY:
203  $time_from = $time_to-60*60*24;
204  $scale = self::SCALE_DAY;
205  break;
206 
207  case self::MODE_WEEK:
208  $time_from = $time_to-60*60*24*7;
209  $scale = self::SCALE_WEEK;
210  break;
211  }
212 
213  $mode_options = array(
214  self::MODE_DAY => $lng->txt("trac_session_statistics_mode_day"),
215  self::MODE_WEEK => $lng->txt("trac_session_statistics_mode_week")
216  );
217 
218  $title = $lng->txt("trac_short_system_load")." - ".$mode_options[$mode];
219  $data = $this->buildData($time_from, $time_to, $title);
220 
221  if(!$a_export)
222  {
223  // toolbar
224  include_once "Services/Form/classes/class.ilPropertyFormGUI.php";
225  $ilToolbar->setFormAction($ilCtrl->getFormAction($this, "short"));
226 
227  $start_selector = new ilDateTimeInputGUI($lng->txt("trac_end_at"), "sst");
228  $start_selector->setDate(new ilDate($time_to, IL_CAL_UNIX));
229  $ilToolbar->addInputItem($start_selector, true);
230 
231  $mode_selector = new ilSelectInputGUI("&nbsp;".$lng->txt("trac_scale"), "smd");
232  $mode_selector->setOptions($mode_options);
233  $mode_selector->setValue($mode);
234  $ilToolbar->addInputItem($mode_selector, true);
235 
236  $measure_options = array(
237  "avg" => $lng->txt("trac_session_active_avg"),
238  "min" => $lng->txt("trac_session_active_min"),
239  "max" => $lng->txt("trac_session_active_max"));
240 
241  $measure_selector = new ilSelectInputGUI("&nbsp;".$lng->txt("trac_measure"), "smm");
242  $measure_selector->setOptions($measure_options);
243  $measure_selector->setValue($measure);
244  $ilToolbar->addInputItem($measure_selector, true);
245 
246  $ilToolbar->addFormButton($lng->txt("ok"), "short");
247 
248  if(sizeof($data["active"]))
249  {
250  $ilToolbar->addSeparator();
251  $ilToolbar->addFormButton($lng->txt("export"), "shortExport");
252  }
253 
254  $tpl->setContent($this->render($data, $scale, $measure));
255  }
256  else
257  {
258  $this->exportCSV($data, $scale);
259  }
260  }
261 
262  protected function shortExport()
263  {
264  $this->short(true);
265  }
266 
267  protected function long($a_export = false)
268  {
269  global $tpl, $ilToolbar, $ilCtrl, $ilTabs, $lng;
270 
271  $ilTabs->activateSubTab("long");
272 
273  // current start
274  if(!$_REQUEST["sst"])
275  {
276  $_REQUEST["sst"] = date("Ymd");
277  }
278  else
279  {
280  $org = $_REQUEST["sst"]["date"];
281  $_REQUEST["sst"] = $org["y"].
282  str_pad($org["m"], 2, "0", STR_PAD_LEFT).
283  str_pad($org["d"], 2, "0", STR_PAD_LEFT);
284  }
285  $start = (int)$_REQUEST["sst"];
286 
287  // current mode
288  if(!$_REQUEST["smd"])
289  {
290  $_REQUEST["smd"] = self::MODE_WEEK;
291  }
292  $mode = (int)$_REQUEST["smd"];
293 
294 
295  $time_to = mktime(23, 59, 59, substr($start, 4, 2), substr($start, 6, 2),
296  substr($start, 0, 4));
297  switch($mode)
298  {
299  case self::MODE_WEEK:
300  $time_from = $time_to-60*60*24*7;
301  $scale = self::SCALE_WEEK;
302  break;
303 
304  case self::MODE_MONTH:
305  $time_from = $time_to-60*60*24*30;
306  $scale = self::SCALE_MONTH;
307  break;
308 
309  case self::MODE_YEAR:
310  $time_from = $time_to-60*60*24*365;
311  $scale = self::SCALE_YEAR;
312  break;
313  }
314 
315  $mode_options = array(
316  self::MODE_WEEK => $lng->txt("trac_session_statistics_mode_week"),
317  self::MODE_MONTH => $lng->txt("trac_session_statistics_mode_month"),
318  self::MODE_YEAR => $lng->txt("trac_session_statistics_mode_year")
319  );
320 
321  $title = $lng->txt("trac_long_system_load")." - ".$mode_options[$mode];
322  $data = $this->buildData($time_from, $time_to, $title);
323 
324  if(!$a_export)
325  {
326  // toolbar
327  include_once "Services/Form/classes/class.ilPropertyFormGUI.php";
328  $ilToolbar->setFormAction($ilCtrl->getFormAction($this, "long"));
329 
330  $start_selector = new ilDateTimeInputGUI($lng->txt("trac_end_at"), "sst");
331  $start_selector->setDate(new ilDate($time_to, IL_CAL_UNIX));
332  $ilToolbar->addInputItem($start_selector, true);
333 
334  $mode_selector = new ilSelectInputGUI("&nbsp;".$lng->txt("trac_scale"), "smd");
335  $mode_selector->setOptions($mode_options);
336  $mode_selector->setValue($mode);
337  $ilToolbar->addInputItem($mode_selector, true);
338 
339  $ilToolbar->addFormButton($lng->txt("ok"), "long");
340 
341  if(sizeof($data["active"]))
342  {
343  $ilToolbar->addSeparator();
344  $ilToolbar->addFormButton($lng->txt("export"), "longExport");
345  }
346 
347  $tpl->setContent($this->render($data, $scale));
348  }
349  else
350  {
351  $this->exportCSV($data, $scale);
352  }
353  }
354 
355  protected function longExport()
356  {
357  $this->long(true);
358  }
359 
360  protected function periodic($a_export = false)
361  {
362  global $tpl, $ilToolbar, $ilCtrl, $ilTabs, $lng;
363 
364  $ilTabs->activateSubTab("periodic");
365 
366  // current start
367  if(!$_REQUEST["sst"])
368  {
369  $_REQUEST["sst"] = date("Y-m-d");
370  }
371  else
372  {
373  $org = $_REQUEST["sst"]["date"];
374  $_REQUEST["sst"] = $org["y"].
375  "-".str_pad($org["m"], 2, "0", STR_PAD_LEFT).
376  "-".str_pad($org["d"], 2, "0", STR_PAD_LEFT);
377  }
378  $start = $_REQUEST["sst"];
379 
380  // current end
381  if(!$_REQUEST["sto"])
382  {
383  $_REQUEST["sto"] = date("Y-m-d", strtotime("-7 days"));
384  }
385  else
386  {
387  $org = $_REQUEST["sto"]["date"];
388  $_REQUEST["sto"] = $org["y"].
389  "-".str_pad($org["m"], 2, "0", STR_PAD_LEFT).
390  "-".str_pad($org["d"], 2, "0", STR_PAD_LEFT);
391  }
392  $end = $_REQUEST["sto"];
393 
394 
395  $time_to = mktime(23, 59, 59, substr($start, 5, 2), substr($start, 8, 2),
396  substr($start, 0, 4));
397  $time_from = mktime(0, 0, 1, substr($end, 5, 2), substr($end, 8, 2),
398  substr($end, 0, 4));
399 
400  // mixed up dates?
401  if($time_to < $time_from)
402  {
403  $tmp = $time_to;
404  $time_to = $time_from;
405  $time_from = $tmp;
406  }
407 
408  $title = $lng->txt("trac_periodic_system_load");
409  $data = $this->buildData($time_from, $time_to, $title);
410 
411  if(!$a_export)
412  {
413  // toolbar
414  include_once "Services/Form/classes/class.ilPropertyFormGUI.php";
415  $ilToolbar->setFormAction($ilCtrl->getFormAction($this, "periodic"));
416 
417  $end_selector = new ilDateTimeInputGUI($lng->txt("trac_begin_at"), "sto");
418  $end_selector->setDate(new ilDate($end, IL_CAL_DATE));
419  $ilToolbar->addInputItem($end_selector, true);
420 
421  $start_selector = new ilDateTimeInputGUI($lng->txt("trac_end_at"), "sst");
422  $start_selector->setDate(new ilDate($start, IL_CAL_DATE));
423  $ilToolbar->addInputItem($start_selector, true);
424 
425  $ilToolbar->addFormButton($lng->txt("ok"), "periodic");
426 
427  if(sizeof($data["active"]))
428  {
429  $ilToolbar->addSeparator();
430  $ilToolbar->addFormButton($lng->txt("export"), "periodicExport");
431  }
432 
433  $tpl->setContent($this->render($data, self::SCALE_PERIODIC_WEEK));
434  }
435  else
436  {
437  $this->exportCSV($data, self::SCALE_PERIODIC_WEEK);
438  }
439  }
440 
441  protected function periodicExport()
442  {
443  $this->periodic(true);
444  }
445 
446  protected function renderCurrentBasics()
447  {
448  global $ilSetting, $lng, $ilCtrl, $ilAccess;
449 
450  // basic data - not time related
451 
452  include_once "Services/Authentication/classes/class.ilSessionControl.php";
454 
455  $control_active = ($ilSetting->get('session_handling_type', 0) == 1);
456  if($control_active)
457  {
458  $control_max_sessions = (int)$ilSetting->get('session_max_count', ilSessionControl::DEFAULT_MAX_COUNT);
459  $control_min_idle = (int)$ilSetting->get('session_min_idle', ilSessionControl::DEFAULT_MIN_IDLE);
460  $control_max_idle = (int)$ilSetting->get('session_max_idle', ilSessionControl::DEFAULT_MAX_IDLE);
461  $control_max_idle_first = (int)$ilSetting->get('session_max_idle_after_first_request', ilSessionControl::DEFAULT_MAX_IDLE_AFTER_FIRST_REQUEST);
462  }
463 
466 
467 
468  // build left column
469 
470  $left = new ilTemplate("tpl.session_statistics_left.html", true, true, "Services/Authentication");
471 
472  $left->setVariable("CAPTION_CURRENT", $lng->txt("users_online"));
473  $left->setVariable("VALUE_CURRENT", $active);
474 
475  $left->setVariable("CAPTION_LAST_AGGR", $lng->txt("trac_last_aggregation"));
476  $left->setVariable("VALUE_LAST_AGGR", ilDatePresentation::formatDate($last_aggr));
477 
478  $left->setVariable("CAPTION_LAST_MAX", $lng->txt("trac_last_maxed_out_sessions"));
479  $left->setVariable("VALUE_LAST_MAX", ilDatePresentation::formatDate($last_maxed_out));
480 
481  $left->setVariable("CAPTION_SESSION_CONTROL", $lng->txt("sess_load_dependent_session_handling"));
482  if(!$control_active)
483  {
484  $left->setVariable("VALUE_SESSION_CONTROL", $lng->txt("no"));
485  }
486  else
487  {
488  $left->setVariable("VALUE_SESSION_CONTROL", $lng->txt("yes"));
489 
490  $left->setCurrentBlock("control_details");
491 
492  $left->setVariable("CAPTION_SESSION_CONTROL_LIMIT", $lng->txt("session_max_count"));
493  $left->setVariable("VALUE_SESSION_CONTROL_LIMIT", $control_max_sessions);
494 
495  $left->setVariable("CAPTION_SESSION_CONTROL_IDLE_MIN", $lng->txt("session_min_idle"));
496  $left->setVariable("VALUE_SESSION_CONTROL_IDLE_MIN", $control_min_idle);
497 
498  $left->setVariable("CAPTION_SESSION_CONTROL_IDLE_MAX", $lng->txt("session_max_idle"));
499  $left->setVariable("VALUE_SESSION_CONTROL_IDLE_MAX", $control_max_idle);
500 
501  $left->setVariable("CAPTION_SESSION_CONTROL_IDLE_FIRST", $lng->txt("session_max_idle_after_first_request"));
502  $left->setVariable("VALUE_SESSION_CONTROL_IDLE_FIRST", $control_max_idle_first);
503 
504  $left->parseCurrentBlock();
505  }
506 
507  // sync button
508  if($ilAccess->checkAccess("write", "", (int)$_REQUEST["ref_id"]))
509  {
510  $left->setVariable("URL_SYNC", $ilCtrl->getFormAction($this, "adminSync"));
511  $left->setVariable("CMD_SYNC", "adminSync");
512  $left->setVariable("TXT_SYNC", $lng->txt("trac_sync_session_stats"));
513  }
514 
515  return $left->get();
516  }
517 
518  protected function buildData($a_time_from, $a_time_to, $a_title)
519  {
520  global $lng;
521 
522  // basic data - time related
523 
524  $maxed_out_duration = round(ilSessionStatistics::getMaxedOutDuration($a_time_from, $a_time_to)/60);
525  $counters = ilSessionStatistics::getNumberOfSessionsByType($a_time_from, $a_time_to);
526  $opened = (int)$counters["opened"];
527  $closed_limit = (int)$counters["closed_limit"];
528  unset($counters["opened"]);
529  unset($counters["closed_limit"]);
530 
531 
532  // build center column
533 
534  $data = array();
535 
537  $data["title"] = $a_title." (".
539  new ilDateTime($a_time_to, IL_CAL_UNIX)).")";
540 
541  $data["maxed_out_time"] = array($lng->txt("trac_maxed_out_time"), $maxed_out_duration);
542  $data["maxed_out_counter"] = array($lng->txt("trac_maxed_out_counter"), $closed_limit);
543  $data["opened"] = array($lng->txt("trac_sessions_opened"), $opened);
544  $data["closed"] = array($lng->txt("trac_sessions_closed"), array_sum($counters));
545  foreach($counters as $type => $counter)
546  {
547  $data["closed_details"][] = array($lng->txt("trac_".$type), (int)$counter);
548  }
549 
550  $data["active"] = ilSessionStatistics::getActiveSessions($a_time_from, $a_time_to);
551 
552  return $data;
553  }
554 
555  protected function render($a_data, $a_scale, $a_measure = null)
556  {
557  global $lng;
558 
559  $center = new ilTemplate("tpl.session_statistics_center.html", true, true, "Services/Authentication");
560 
561  foreach($a_data as $idx => $item)
562  {
563  switch($idx)
564  {
565  case "active":
566  case "title":
567  // nothing to do
568  break;
569 
570  case "closed_details":
571  $center->setCurrentBlock("closed_details");
572  foreach($item as $detail)
573  {
574  $center->setVariable("CAPTION_CLOSED_DETAILS", $detail[0]);
575  $center->setVariable("VALUE_CLOSED_DETAILS", $detail[1]);
576  $center->parseCurrentBlock();
577  }
578  break;
579 
580  default:
581  $tpl_var = strtoupper($idx);
582  $center->setVariable("CAPTION_".$tpl_var, $item[0]);
583  $center->setVariable("VALUE_".$tpl_var, $item[1]);
584  break;
585  }
586  }
587 
588  if($a_data["active"])
589  {
590  $center->setVariable("CHART", $this->getChart($a_data["active"], $a_data["title"], $a_scale, $a_measure));
591  }
592  else
593  {
594  ilUtil::sendInfo($lng->txt("trac_session_statistics_no_data"));
595  }
596 
597  return $center->get();
598  }
599 
609  protected function getChart($a_data, $a_title, $a_scale = self::SCALE_DAY, $a_measure = null)
610  {
611  global $lng;
612 
613  include_once "Services/Chart/classes/class.ilChart.php";
614  $chart = ilChart::getInstanceByType(ilChart::TYPE_GRID, "objstacc");
615  $chart->setsize(700, 500);
616  $chart->setYAxisToInteger(true);
617 
618  $legend = new ilChartLegend();
619  $chart->setLegend($legend);
620 
621  if(!$a_measure)
622  {
623  $a_measure = array("min", "avg", "max");
624  }
625  else if(!is_array($a_measure))
626  {
627  $a_measure = array($a_measure);
628  }
629 
630  $colors_map = array("min" => "#00cc00",
631  "avg" => "#0000cc",
632  "max" => "#cc00cc");
633 
634  $colors = $act_line = array();
635  foreach($a_measure as $measure)
636  {
637  $act_line[$measure] = $chart->getDataInstance(ilChartGrid::DATA_LINES);
638  $act_line[$measure]->setLineSteps(true);
639  $act_line[$measure]->setLabel($lng->txt("trac_session_active_".$measure));
640  $colors[] = $colors_map[$measure];
641  }
642 
643  if($a_scale != self::SCALE_PERIODIC_WEEK)
644  {
645  $max_line = $chart->getDataInstance(ilChartGrid::DATA_LINES);
646  $max_line->setLabel($lng->txt("session_max_count"));
647  $colors[] = "#cc0000";
648  }
649 
650  $chart->setColors($colors);
651 
652  $chart_data = $this->adaptDataToScale($a_scale, $a_data, 700);
653  unset($a_data);
654 
655  $scale = ceil(sizeof($chart_data)/5);
656  $labels = array();
657  foreach($chart_data as $idx => $item)
658  {
659  $date = $item["slot_begin"];
660 
661  if($a_scale == self::SCALE_PERIODIC_WEEK || !($idx % ceil($scale)))
662  {
663  switch($a_scale)
664  {
665  case self::SCALE_DAY:
666  $labels[$date] = date("H:i", $date);
667  break;
668 
669  case self::SCALE_WEEK:
670  $labels[$date] = date("d.m. H", $date)."h";
671  break;
672 
673  case self::SCALE_MONTH:
674  $labels[$date] = date("d.m.", $date);
675  break;
676 
677  case self::SCALE_YEAR:
678  $labels[$date] = date("Y-m", $date);
679  break;
680 
681  case self::SCALE_PERIODIC_WEEK:
682  $day = substr($date, 0, 1);
683  $hour = substr($date, 1, 2);
684  $min = substr($date, 3, 2);
685 
686  // build ascending scale from day values
687  $day_value = ($day-1)*60*60*24;
688  $date = $day_value+$hour*60*60+$min*60;
689 
690  // 6-hour interval labels
691  if($hour != $old_hour && $hour && $hour%6 == 0)
692  {
693  $labels[$date] = $hour;
694  $old_hour = $hour;
695  }
696  // day label
697  if($day != $old_day)
698  {
699  $labels[$date] = ilCalendarUtil::_numericDayToString($day, false);
700  $old_day = $day;
701  }
702  break;
703  }
704  }
705 
706  foreach($a_measure as $measure)
707  {
708  $value = (int)$item["active_".$measure];
709  $act_line[$measure]->addPoint($date, $value);
710  }
711 
712  if($a_scale != self::SCALE_PERIODIC_WEEK)
713  {
714  $max_line->addPoint($date, (int)$item["max_sessions"]);
715  }
716  }
717 
718  foreach($act_line as $line)
719  {
720  $chart->addData($line);
721  }
722  if($a_scale != self::SCALE_PERIODIC_WEEK)
723  {
724  $chart->addData($max_line);
725  }
726 
727  $chart->setTicks($labels, null, true);
728 
729  return $chart->getHTML();
730  }
731 
732  protected function adaptDataToScale($a_scale, array $a_data)
733  {
734  // can we use original data?
735  switch($a_scale)
736  {
737  case self::SCALE_DAY:
738  // 96 values => ok
739  // fallthrough
740 
741  case self::SCALE_WEEK:
742  // 672 values => ok
743  return $a_data;
744  }
745 
746  $tmp = array();
747  foreach($a_data as $item)
748  {
749  $date_parts = getdate($item["slot_begin"]);
750 
751  // aggregate slots for scale
752  switch($a_scale)
753  {
754  case self::SCALE_MONTH:
755  // aggregate to hours => 720 values
756  $slot = mktime($date_parts["hours"], 0, 0, $date_parts["mon"], $date_parts["mday"], $date_parts["year"]);
757  break;
758 
759  case self::SCALE_YEAR:
760  // aggregate to days => 365 values
761  $slot = mktime(0, 0, 1, $date_parts["mon"], $date_parts["mday"], $date_parts["year"]);
762  break;
763 
764  case self::SCALE_PERIODIC_WEEK:
765  // aggregate to weekdays => 672 values
766  $day = $date_parts["wday"];
767  if(!$day)
768  {
769  $day = 7;
770  }
771  $slot = $day.date("His", $item["slot_begin"]);
772  break;
773  }
774 
775  // process minx/max, prepare avg
776  foreach($item as $id => $value)
777  {
778  switch(substr($id, -3))
779  {
780  case "min":
781  if(!$tmp[$slot][$id] || $value < $tmp[$slot][$id])
782  {
783  $tmp[$slot][$id] = $value;
784  }
785  break;
786 
787  case "max":
788  if(!$tmp[$slot][$id] || $value > $tmp[$slot][$id])
789  {
790  $tmp[$slot][$id] = $value;
791  }
792  break;
793 
794  case "avg":
795  $tmp[$slot][$id][] = $value;
796  break;
797  }
798  }
799  }
800 
801  foreach($tmp as $slot => $attr)
802  {
803  $tmp[$slot]["active_avg"] = (int)round(array_sum($attr["active_avg"])/sizeof($attr["active_avg"]));
804  $tmp[$slot]["slot_begin"] = $slot;
805  }
806  ksort($tmp);
807  return array_values($tmp);
808  }
809 
810  protected function adminSync()
811  {
812  global $ilCtrl, $lng;
813 
814  // see ilSession::_writeData()
815  $now = time();
818 
819  ilUtil::sendSuccess($lng->txt("trac_sync_session_stats_success"), true);
820  $ilCtrl->redirect($this);
821  }
822 
823  protected function exportCSV(array $a_data, $a_scale)
824  {
825  global $lng, $ilClientIniFile, $ilUser;
826 
828  include_once './Services/Link/classes/class.ilLink.php';
829 
830  include_once "./Services/Utilities/classes/class.ilCSVWriter.php";
831  $csv = new ilCSVWriter();
832  $csv->setSeparator(";");
833 
834  $now = time();
835 
836  // meta
837  $meta = array(
838  $lng->txt("trac_name_of_installation") => $ilClientIniFile->readVariable('client', 'name'),
839  $lng->txt("trac_report_date") =>
841  $lng->txt("trac_report_owner") => $ilUser->getFullName(),
842  );
843  foreach($a_data as $idx => $item)
844  {
845  switch($idx)
846  {
847  case "title":
848  $meta[$lng->txt("title")] = $item;
849  break;
850 
851  case "active":
852  // nothing to do
853  break;
854 
855  case "closed_details":
856  foreach($item as $detail)
857  {
858  $meta[$a_data["closed"][0]." - ".$detail[0]] = $detail[1];
859  }
860  break;
861 
862  default:
863  $meta[$item[0]] = $item[1];
864  break;
865  }
866  }
867  foreach($meta as $caption => $value)
868  {
869  $csv->addColumn(strip_tags($caption));
870  $csv->addColumn(strip_tags($value));
871  $csv->addRow();
872  }
873  $csv->addRow();
874 
875  // aggregate data
876  $aggr_data = $this->adaptDataToScale($a_scale, $a_data["active"], 700);
877  unset($a_data);
878 
879  // header
880  $first = $aggr_data;
881  $first = array_keys(array_shift($first));
882  foreach ($first as $column)
883  {
884  // split weekday and time slot again
885  if($a_scale == self::SCALE_PERIODIC_WEEK && $column == "slot_begin")
886  {
887  $csv->addColumn("weekday");
888  $csv->addColumn("time");
889  }
890  else
891  {
892  $csv->addColumn(strip_tags($column));
893  }
894  }
895  $csv->addRow();
896 
897  // data
898  foreach($aggr_data as $row)
899  {
900  foreach ($row as $column => $value)
901  {
902  if(is_array($value))
903  {
904  $value = implode(', ', $value);
905  }
906  switch($column)
907  {
908  case "slot_begin":
909  // split weekday and time slot again
910  if($a_scale == self::SCALE_PERIODIC_WEEK)
911  {
912  $csv->addColumn(ilCalendarUtil::_numericDayToString(substr($value, 0, 1)));
913  $value = substr($value, 1, 2).":".substr($value, 3, 2);
914  break;
915  }
916  // fallthrough
917 
918  case "slot_end":
919  $value = date("d.m.Y H:i", $value);
920  break;
921  }
922  $csv->addColumn(strip_tags($value));
923  }
924  $csv->addRow();
925  }
926 
927  // send
928  $filename .= "session_statistics_".date("Ymd", $now).".csv";
929  header("Content-type: text/comma-separated-values");
930  header("Content-Disposition: attachment; filename=\"".$filename."\"");
931  header("Expires: 0");
932  header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
933  header("Pragma: public");
934  echo $csv->getCSVString();
935  exit();
936  }
937 }
938 
939 ?>