ILIAS  release_4-3 Revision
 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 = new ilChart("objstacc", 700, 500);
615  $chart->setYAxisToInteger(true);
616 
617  $legend = new ilChartLegend();
618  $chart->setLegend($legend);
619 
620  if(!$a_measure)
621  {
622  $a_measure = array("min", "avg", "max");
623  }
624  else if(!is_array($a_measure))
625  {
626  $a_measure = array($a_measure);
627  }
628 
629  $colors_map = array("min" => "#00cc00",
630  "avg" => "#0000cc",
631  "max" => "#cc00cc");
632 
633  $colors = $act_line = array();
634  foreach($a_measure as $measure)
635  {
636  $act_line[$measure] = new ilChartData("lines");
637  $act_line[$measure]->setLineSteps(true);
638  $act_line[$measure]->setLabel($lng->txt("trac_session_active_".$measure));
639  $colors[] = $colors_map[$measure];
640  }
641 
642  if($a_scale != self::SCALE_PERIODIC_WEEK)
643  {
644  $max_line = new ilChartData("lines");
645  $max_line->setLabel($lng->txt("session_max_count"));
646  $colors[] = "#cc0000";
647  }
648 
649  $chart->setColors($colors);
650 
651  $chart_data = $this->adaptDataToScale($a_scale, $a_data, 700);
652  unset($a_data);
653 
654  $scale = ceil(sizeof($chart_data)/5);
655  $labels = array();
656  foreach($chart_data as $idx => $item)
657  {
658  $date = $item["slot_begin"];
659 
660  if($a_scale == self::SCALE_PERIODIC_WEEK || !($idx % ceil($scale)))
661  {
662  switch($a_scale)
663  {
664  case self::SCALE_DAY:
665  $labels[$date] = date("H:i", $date);
666  break;
667 
668  case self::SCALE_WEEK:
669  $labels[$date] = date("d.m. H", $date)."h";
670  break;
671 
672  case self::SCALE_MONTH:
673  $labels[$date] = date("d.m.", $date);
674  break;
675 
676  case self::SCALE_YEAR:
677  $labels[$date] = date("Y-m", $date);
678  break;
679 
680  case self::SCALE_PERIODIC_WEEK:
681  $day = substr($date, 0, 1);
682  $hour = substr($date, 1, 2);
683  $min = substr($date, 3, 2);
684 
685  // build ascending scale from day values
686  $day_value = ($day-1)*60*60*24;
687  $date = $day_value+$hour*60*60+$min*60;
688 
689  // 6-hour interval labels
690  if($hour != $old_hour && $hour && $hour%6 == 0)
691  {
692  $labels[$date] = $hour;
693  $old_hour = $hour;
694  }
695  // day label
696  if($day != $old_day)
697  {
698  $labels[$date] = ilCalendarUtil::_numericDayToString($day, false);
699  $old_day = $day;
700  }
701  break;
702  }
703  }
704 
705  foreach($a_measure as $measure)
706  {
707  $value = (int)$item["active_".$measure];
708  $act_line[$measure]->addPoint($date, $value);
709  }
710 
711  if($a_scale != self::SCALE_PERIODIC_WEEK)
712  {
713  $max_line->addPoint($date, (int)$item["max_sessions"]);
714  }
715  }
716 
717  foreach($act_line as $line)
718  {
719  $chart->addData($line);
720  }
721  if($a_scale != self::SCALE_PERIODIC_WEEK)
722  {
723  $chart->addData($max_line);
724  }
725 
726  $chart->setTicks($labels, null, true);
727 
728  return $chart->getHTML();
729  }
730 
731  protected function adaptDataToScale($a_scale, array $a_data)
732  {
733  // can we use original data?
734  switch($a_scale)
735  {
736  case self::SCALE_DAY:
737  // 96 values => ok
738  // fallthrough
739 
740  case self::SCALE_WEEK:
741  // 672 values => ok
742  return $a_data;
743  }
744 
745  $tmp = array();
746  foreach($a_data as $item)
747  {
748  $date_parts = getdate($item["slot_begin"]);
749 
750  // aggregate slots for scale
751  switch($a_scale)
752  {
753  case self::SCALE_MONTH:
754  // aggregate to hours => 720 values
755  $slot = mktime($date_parts["hours"], 0, 0, $date_parts["mon"], $date_parts["mday"], $date_parts["year"]);
756  break;
757 
758  case self::SCALE_YEAR:
759  // aggregate to days => 365 values
760  $slot = mktime(0, 0, 1, $date_parts["mon"], $date_parts["mday"], $date_parts["year"]);
761  break;
762 
763  case self::SCALE_PERIODIC_WEEK:
764  // aggregate to weekdays => 672 values
765  $day = $date_parts["wday"];
766  if(!$day)
767  {
768  $day = 7;
769  }
770  $slot = $day.date("His", $item["slot_begin"]);
771  break;
772  }
773 
774  // process minx/max, prepare avg
775  foreach($item as $id => $value)
776  {
777  switch(substr($id, -3))
778  {
779  case "min":
780  if(!$tmp[$slot][$id] || $value < $tmp[$slot][$id])
781  {
782  $tmp[$slot][$id] = $value;
783  }
784  break;
785 
786  case "max":
787  if(!$tmp[$slot][$id] || $value > $tmp[$slot][$id])
788  {
789  $tmp[$slot][$id] = $value;
790  }
791  break;
792 
793  case "avg":
794  $tmp[$slot][$id][] = $value;
795  break;
796  }
797  }
798  }
799 
800  foreach($tmp as $slot => $attr)
801  {
802  $tmp[$slot]["active_avg"] = (int)round(array_sum($attr["active_avg"])/sizeof($attr["active_avg"]));
803  $tmp[$slot]["slot_begin"] = $slot;
804  }
805  ksort($tmp);
806  return array_values($tmp);
807  }
808 
809  protected function adminSync()
810  {
811  global $ilCtrl, $lng;
812 
813  // see ilSession::_writeData()
814  $now = time();
817 
818  ilUtil::sendSuccess($lng->txt("trac_sync_session_stats_success"), true);
819  $ilCtrl->redirect($this);
820  }
821 
822  protected function exportCSV(array $a_data, $a_scale)
823  {
824  global $lng, $ilClientIniFile, $ilUser;
825 
827  include_once './Services/Link/classes/class.ilLink.php';
828 
829  include_once "./Services/Utilities/classes/class.ilCSVWriter.php";
830  $csv = new ilCSVWriter();
831  $csv->setSeparator(";");
832 
833  $now = time();
834 
835  // meta
836  $meta = array(
837  $lng->txt("trac_name_of_installation") => $ilClientIniFile->readVariable('client', 'name'),
838  $lng->txt("trac_report_date") =>
840  $lng->txt("trac_report_owner") => $ilUser->getFullName(),
841  );
842  foreach($a_data as $idx => $item)
843  {
844  switch($idx)
845  {
846  case "title":
847  $meta[$lng->txt("title")] = $item;
848  break;
849 
850  case "active":
851  // nothing to do
852  break;
853 
854  case "closed_details":
855  foreach($item as $detail)
856  {
857  $meta[$a_data["closed"][0]." - ".$detail[0]] = $detail[1];
858  }
859  break;
860 
861  default:
862  $meta[$item[0]] = $item[1];
863  break;
864  }
865  }
866  foreach($meta as $caption => $value)
867  {
868  $csv->addColumn(strip_tags($caption));
869  $csv->addColumn(strip_tags($value));
870  $csv->addRow();
871  }
872  $csv->addRow();
873 
874  // aggregate data
875  $aggr_data = $this->adaptDataToScale($a_scale, $a_data["active"], 700);
876  unset($a_data);
877 
878  // header
879  $first = $aggr_data;
880  $first = array_keys(array_shift($first));
881  foreach ($first as $column)
882  {
883  // split weekday and time slot again
884  if($a_scale == self::SCALE_PERIODIC_WEEK && $column == "slot_begin")
885  {
886  $csv->addColumn("weekday");
887  $csv->addColumn("time");
888  }
889  else
890  {
891  $csv->addColumn(strip_tags($column));
892  }
893  }
894  $csv->addRow();
895 
896  // data
897  foreach($aggr_data as $row)
898  {
899  foreach ($row as $column => $value)
900  {
901  if(is_array($value))
902  {
903  $value = implode(', ', $value);
904  }
905  switch($column)
906  {
907  case "slot_begin":
908  // split weekday and time slot again
909  if($a_scale == self::SCALE_PERIODIC_WEEK)
910  {
911  $csv->addColumn(ilCalendarUtil::_numericDayToString(substr($value, 0, 1)));
912  $value = substr($value, 1, 2).":".substr($value, 3, 2);
913  break;
914  }
915  // fallthrough
916 
917  case "slot_end":
918  $value = date("d.m.Y H:i", $value);
919  break;
920  }
921  $csv->addColumn(strip_tags($value));
922  }
923  $csv->addRow();
924  }
925 
926  // send
927  $filename .= "session_statistics_".date("Ymd", $now).".csv";
928  header("Content-type: text/comma-separated-values");
929  header("Content-Disposition: attachment; filename=\"".$filename."\"");
930  header("Expires: 0");
931  header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
932  header("Pragma: public");
933  echo $csv->getCSVString();
934  exit();
935  }
936 }
937 
938 ?>