1 <?php
defined('SYSPATH') OR die('No direct access allowed.');
5 * This particular reports controller is meant as a base controller for both
6 * SLA and Availability reports, mostly for hysterical reasons.
8 * op5, and the op5 logo are trademarks, servicemarks, registered servicemarks
9 * or registered trademarks of op5 AB.
10 * All other trademarks, servicemarks, registered trademarks, and registered
11 * servicemarks mentioned herein may be the property of their respective owner(s).
12 * The information contained herein is provided AS IS with NO WARRANTY OF ANY
13 * KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A
16 class Reports_Controller
extends Base_reports_Controller
18 private $status_link = "status/service/";
19 private $history_link = "alert_history/generate";
22 private static $sla_field_names = array(
23 'hosts' => 'PERCENT_TOTAL_TIME_UP',
24 'hostgroups' => 'PERCENT_TOTAL_TIME_UP',
25 'services' => 'PERCENT_TOTAL_TIME_OK',
26 'servicegroups' => 'PERCENT_TOTAL_TIME_OK'
30 * Display report selection/setup page
32 public function index($input=false)
34 $this->setup_options_obj($input);
35 $reports_model = new Status_Reports_Model($this->options
);
37 # check if we have all required parts installed
38 if (!$reports_model->_self_check()) {
39 return url
::redirect(Router
::$controller.'/invalid_setup');
42 $type_str = $this->type
== 'avail'
45 $this->template
->content
= $this->add_view('reports/setup');
46 $template = $this->template
->content
;
48 if(isset($_SESSION['report_err_msg'])) {
49 $template->error_msg
= $_SESSION['report_err_msg'];
50 unset($_SESSION['report_err_msg']);
53 # we should set the required js-files
54 $this->template
->js
[] = $this->add_path('reports/js/tgraph.js');
55 $this->template
->js
[] = 'application/media/js/jquery.datePicker.js';
56 $this->template
->js
[] = 'application/media/js/jquery.timePicker.js';
57 $this->template
->js
[] = $this->add_path('reports/js/common.js');
58 $this->template
->js
[] = $this->add_path('reports/js/reports.js');
60 $this->template
->js
[] = 'application/media/js/lib.set.js';
61 $this->template
->js
[] = 'application/media/js/jquery.filterable.js';
63 # this makes anything in application/media be imported before
64 # application/views before modules/whatever, so op5reports can
65 # put random crap here as well.
68 sort($this->template
->js
);
69 $this->template
->js
= array_unique($this->template
->js
);
71 $this->template
->css
[] = 'application/media/css/jquery.filterable.css';
72 $this->template
->css
[] = $this->add_path('reports/css/tgraph.css');
73 $this->template
->css
[] = $this->add_path('reports/css/datePicker.css');
75 # what scheduled reports are there?
76 $scheduled_periods = null;
77 $scheduled_res = Scheduled_reports_Model
::get_scheduled_reports($this->type
);
78 if ($scheduled_res && count($scheduled_res)!=0) {
79 foreach ($scheduled_res as $sched_row) {
80 $scheduled_periods[$sched_row->report_id
] = $sched_row->periodname
;
84 $template->report_options
= $this->add_view('reports/options');
86 $this->js_strings
.= "var _reports_propagate = '"._('Would you like to propagate this value to all months?')."';\n";
87 $this->js_strings
.= "var _reports_propagate_remove = '"._("Would you like to remove all values from all months?")."';\n";
89 $this->js_strings
.= reports
::js_strings();
91 $this->js_strings
.= "var _reports_name_empty = '"._("Please give your report a meaningful name.")."';\n";
93 $template->report_options
->months
= date
::abbr_month_names();
95 $template->scheduled_info
= Scheduled_reports_Model
::report_is_scheduled($this->type
, $this->options
['report_id']);
97 $saved_reports = $this->options
->get_all_saved();
98 $template->report_options
->saved_reports
= $saved_reports;
99 $template->saved_reports
= $saved_reports;
100 $template->scheduled_periods
= $scheduled_periods;
102 $this->js_strings
.= "var _reports_no_sla_str = '"._('Please enter at least one SLA value')."';\n";
103 $this->js_strings
.= "var _reports_sla_err_str = '"._('Please check SLA values in fields marked red below and try again')."';\n";
105 $this->template
->js_strings
= $this->js_strings
;
107 $this->template
->toolbar
= new Toolbar_Controller($this->type
== 'avail' ?
_('Availability report') : _('SLA report'));
109 if ( $this->type
== 'avail' ) {
110 $this->template
->toolbar
->info( '<a id="switch_report_type" href="' . url
::base(true) . 'sla' . '">' );
111 $this->template
->toolbar
->info(
112 html
::image($this->add_path('icons/16x16/sla.png'), array('alt' => _('SLA'), 'title' => _('SLA'), 'ID' => 'switcher_image'))
114 $this->template
->toolbar
->info( ' <span id="switch_report_type_txt">' . _('Switch to SLA report') . '</span>' );
115 $this->template
->toolbar
->info( '</a>' );
117 $this->template
->toolbar
->info( '<a id="switch_report_type" href="' . url
::base(true) . 'avail' . '">' );
118 $this->template
->toolbar
->info(
119 html
::image($this->add_path('icons/16x16/availability.png'), array('alt' => _('Availability'), 'title' => _('Availability'), 'ID' => 'switcher_image'))
121 $this->template
->toolbar
->info( ' <span id="switch_report_type_txt">' . _('Switch to Availability report') . '</span>' );
122 $this->template
->toolbar
->info( '</a>' );
125 $this->template
->title
= _('Reporting » ').($this->type
== 'avail' ?
_('Availability Report') : _('SLA Report')).(' » Setup');
129 * Create the same data as generate, but dump it as json
131 public function debug($input=false)
133 $this->setup_options_obj($input);
134 $reports_model = new Status_Reports_Model($this->options
);
135 $data_arr = $reports_model->get_uptime();
136 header('Content-Type: text/plain');
137 header('Content-Disposition: attachment; filename="debug.json"');
138 print json_encode($data_arr);
143 * Generate (availability) report from parameters set in index()
145 * @param $input array = false
147 public function generate($input=false)
149 $this->setup_options_obj($input);
151 $reports_model = new Status_Reports_Model($this->options
);
153 # check if we have all required parts installed
154 if (!$reports_model->_self_check()) {
155 return url
::redirect(Router
::$controller.'/invalid_setup');
158 $this->template
->js
[] = 'application/media/js/jquery.datePicker.js';
159 $this->template
->js
[] = 'application/media/js/jquery.timePicker.js';
160 $this->template
->js
[] = $this->add_path('reports/js/tgraph.js');
161 $this->template
->js
[] = $this->add_path('reports/js/common.js');
162 $this->template
->js
[] = $this->add_path('reports/js/reports.js');
164 if ($this->options
['skin']) {
165 if (substr($this->options
['skin'], -1, 1) != '/') {
166 $this->options
['skin'] .= '/';
168 $this->template
->current_skin
= $this->options
['skin'];
171 $this->template
->css
[] = $this->add_path('reports/css/tgraph.css');
172 $this->template
->css
[] = $this->add_path('reports/css/datePicker.css');
174 $this->template
->content
= $this->add_view('reports/index'); # base template with placeholders for all parts
175 $template = $this->template
->content
;
179 $date_format = $this->type
== 'sla' ? cal
::get_calendar_format(true) : nagstat
::date_format();
181 switch ($this->options
['report_type']) {
186 case 'servicegroups':
187 $sub_type = "service";
195 $sub_type = "service";
199 return url
::redirect(Router
::$controller.'/index');
202 $report_members = $this->options
->get_report_members();
203 if (empty($report_members)) {
205 $_SESSION['report_err_msg'] = _("You didn't select any objects to include in the report");
207 $_SESSION['report_err_msg'] = sprintf(_("The groups you selected (%s) had no members, so cannot create a report from them"), implode(', ', $this->options
['objects']));
208 return url
::redirect(Router
::$controller.'/index?' . http_build_query($this->options
->options
));
212 if ($this->type
== 'avail') {
213 $data_arr = $reports_model->get_uptime();
215 $data_arr = $this->get_sla_data($this->options
['months']);
218 if ($this->options
['output_format'] == 'csv') {
219 csv
::csv_http_headers($this->type
, $this->options
);
220 $this->template
= $this->add_view('reports/'.$this->type
.'csv');
221 $this->template
->data_arr
= $data_arr;
225 $template->title
= $this->type
== 'avail' ?
_('Availability Report') : _('SLA Report');
227 # ==========================================
228 # ========= REPORT STARTS HERE =============
229 # ==========================================
231 $template->report_options
= $this->add_view('reports/options');
233 $tpl_options = $template->report_options
;
234 $saved_reports = $this->options
->get_all_saved();
235 $tpl_options->saved_reports
= $saved_reports;
236 $tpl_options->months
= date
::abbr_month_names();
238 $this->js_strings
.= "var _reports_propagate = '"._('Would you like to propagate this value to all months?')."';\n";
239 $this->js_strings
.= "var _reports_propagate_remove = '"._("Would you like to remove all values from all months?")."';\n";
241 $this->js_strings
.= reports
::js_strings();
242 $this->js_strings
.= "var _reports_name_empty = '"._("Please give your report a meaningful name.")."';\n";
244 $host_graph_items = array('TOTAL_TIME_UP' => _('Up'),
245 'TOTAL_TIME_DOWN' => _('Down'),
246 'TOTAL_TIME_UNREACHABLE' => _('Unreachable'),
247 'TOTAL_TIME_UNDETERMINED' => _('Undetermined'),
248 'TOTAL_TIME_EXCLUDED' => 'EXCLUDE',
250 $service_graph_items = array('TOTAL_TIME_OK' => _('Ok'),
251 'TOTAL_TIME_WARNING' => _('Warning'),
252 'TOTAL_TIME_UNKNOWN' => _('Unknown'),
253 'TOTAL_TIME_CRITICAL' => _('Critical'),
254 'TOTAL_TIME_UNDETERMINED' => _('Undetermined'),
255 'TOTAL_TIME_EXCLUDED' => 'EXCLUDE',
257 $graph_filter = $
{$sub_type.'_graph_items'};
259 $template->header
= $this->add_view('reports/header');
260 $template->header
->title
= $template->title
;
261 $template->header
->report_time_formatted
= $this->format_report_time($date_format);
263 # avail, more than one object
264 if ($this->type
== 'avail' && ($is_group ||
count($this->options
['objects']) > 1)) {
265 $template_values = array();
266 $template->content
= $this->add_view('reports/multiple_'.$sub_type.'_states');
267 $template->content
->multiple_states
= $data_arr;
268 $template->content
->hide_host
= false;
270 if($is_group) # actual hostgroup/servicegroup.
271 $tmp_title = ucfirst($sub_type)._('group breakdown');
273 $tmp_title = ucfirst($sub_type).' '._('state breakdown');
274 $template->header
->title
= $tmp_title;
276 // ===== SETUP PIECHART VALUES =====
278 if( $this->options
['include_pie_charts'] ) {
279 $template->pie
= $this->add_view('reports/pie_chart');
282 foreach($data_arr as $data) { # for every group
283 if (!is_array($data) ||
!isset($data['states']))
286 foreach ($graph_filter as $key => $val) {
287 if ($data['states'][$key]!=0)
288 $image[strtoupper($val)] = $data['states'][$key];
291 'img' => http_build_query($image),
292 'host' => isset($data['groupname'])?
implode(', ', $data['groupname']):'',
296 $template->pie
->data_str
= $data_str;
298 } else { # single avail host/service, or any sla
299 $image_data = array();
301 if (!empty($data_arr)) {
302 $template->content
= $this->add_view('reports/'.$this->type
);
304 if ($this->type
== 'avail') {
306 foreach ($data_arr as $grouplist) {
307 if (!is_array($grouplist) ||
!isset($grouplist['states']))
309 foreach ($grouplist as $host) {
310 if (!is_array($host) ||
!isset($host['states']))
312 $sources[] = $host['source'];
315 $avail = $template->content
;
316 $avail->report_data
= $data_arr;
318 $avail->header_string
= ucfirst($this->options
['report_type'])." "._('state breakdown');
320 # Will break epically
321 if( $this->options
['include_pie_charts'] ) {
323 foreach ($data_arr as $data) {
324 if (!is_array($data) ||
!isset($data['states']))
326 $pie = $this->add_view('reports/pie_chart');
328 // ===== SETUP PIECHART VALUES =====
329 if (is_array($data['states'])) {
330 foreach ($graph_filter as $key => $val) {
331 if ($data['states'][$key]!=0)
332 $image_data[strtoupper($val)] = $data['states'][$key];
337 $data_str = http_build_query($image_data);
338 $pie->data_str
= $data_str;
339 $pie->source
= $data['source'];
343 $avail->pies
= $pies;
346 if ($sub_type=='host') {
347 $service_states = $this->_print_states_for_services($sources);
349 if ($service_states !== false) {
350 $header_str = _("Service state breakdown");
351 $template->svc_content
= $this->add_view('reports/multiple_service_states');
352 $content = $template->svc_content
;
353 $content->header_string
= $header_str;
354 $content->multiple_states
= $service_states;
355 $content->hide_host
= true;
356 $content->source
= $sources;
361 # links - only for HTML reports
362 switch($this->options
['report_type']) {
364 $host = $this->options
['objects'][0];
365 $template->header
->title
= sprintf(_('Host details for %s'), $host);
367 $links[$this->histogram_link
. "?" . $this->options
->as_keyval_string()] = _('Alert histogram');
368 $links[$this->status_link
.$host] = _('Status detail');
369 $links[$this->history_link
. '?' . $this->options
->as_keyval_string()] = _('Alert history');
370 $links[listview
::link('notifications', array('host_name' => $host))] = _('Notifications');
374 list($host, $service) = explode(';', $this->options
['objects'][0]);
375 $template->header
->title
= sprintf(_('Service details for %s on host %s'), $service, $host);
377 $links[$this->histogram_link
. "?" . $this->options
->as_keyval_string()] = _('Alert histogram');
378 $links[$this->history_link
. "?" . $this->options
->as_keyval_string()] = _('Alert history');
379 $links[listview
::link('notifications', array('host_name' => $host, 'service_description' => $service))] = _('Notifications');
384 $template->links
= $links;
385 $template->source
= $sources;
386 $template->header_string
= sprintf(_("State breakdown for %s"), implode(', ', $sources));
389 $template->header
->title
= _('SLA breakdown');
390 $sla = $template->content
;
391 $sla->report_data
= $data_arr;
394 } # end if not empty. Display message to user?
395 # ^ no, that sounds like a terrible idea, don't inform the user about anything, ever!
398 if($this->options
['include_trends']) {
401 $graph_data = array();
402 foreach ($data_arr as $data) {
403 if (!is_array($data) ||
!isset($data['states']))
405 foreach ($data as $obj) {
406 if (!is_array($obj) ||
!isset($obj['log']))
408 if ($this->options
['collapse_green_trends'] && (($sub_type == 'host' && $obj['states']['PERCENT_TOTAL_TIME_UP'] == 100) ||
($sub_type == 'service' && $obj['states']['PERCENT_TOTAL_TIME_OK'] == 100))) {
412 $graph_data[$obj['source']] = $obj['log'];
417 $template->trends_graph
= $this->add_view('trends/new_report');
419 /* New JS trend graph */
421 $template->trends_graph
->skipped
= $skipped;
422 $template->trends_graph
->included
= $included;
423 $template->trends_graph
->graph_start_date
= $this->options
['start_time'];
424 $template->trends_graph
->graph_end_date
= $this->options
['end_time'];
425 $template->trends_graph
->use_scaling
= $this->options
['include_trends_scaling'];
426 $template->trends_graph
->obj_type
= $sub_type;
427 $template->trends_graph
->graph_pure_data
= Trends_graph_Model
::format_graph_data($graph_data);
430 $this->template
->js_strings
= $this->js_strings
;
432 $this->template
->title
= _('Reporting » ').($this->type
== 'avail' ?
_('Availability Report') : _('SLA Report')).(' » Report');
434 $this->template
->js
[] = $this->add_path('summary/js/summary.js');
435 if ($this->options
['include_alerts']) {
436 $alrt_opts = new Alert_history_options($this->options
);
437 $alrt_opts['summary_items'] = 0; // we want *every* line in this time range
438 $alrt_opts['include_downtime'] = true; // and we want downtime messages
440 $alerts = new Alert_history_Controller();
441 $alerts->set_options($alrt_opts);
442 $alerts->auto_render
= false;
444 $this->template
->content
->log_content
= $alerts->template
->content
->content
;
447 if(ninja
::has_module('synergy') && $this->options
['include_synergy_events']) {
448 $synergy_report_model = new Synergy_report_Model($this->options
);
449 $synergy_content = $this->add_view('reports/synergy');
450 $synergy_content->synergy_events
= $synergy_report_model->get_data();
451 $this->template
->content
->synergy_content
= $synergy_content;
453 sort($this->template
->js
);
454 $scheduled_info = Scheduled_reports_Model
::report_is_scheduled($this->type
, $this->options
['report_id']);
455 if($scheduled_info) {
456 $schedule_id = $this->input
->get('schedule_id', null);
458 $le_schedule = current(array_filter($scheduled_info, function($item) use ($schedule_id) {
459 return $item['id'] == $schedule_id && $item['attach_description'] && $item['description'];
462 $template->header
->description
= $this->options
['description'] ?
$this->options
['description']."\n".$le_schedule['description'] : $le_schedule['description'];
467 if ($this->options
['output_format'] == 'pdf') {
468 return $this->generate_pdf();
473 * Print message to user about invalid setup.
474 * This could be because of missing database or
477 public function invalid_setup()
479 $this->template
->content
= $this->add_view('reports/reports_module');
480 $template = $this->template
->content
;
481 $template->error_msg
= _('Some parts in your setup is apparently missing.');
482 $template->info
= _("make sure you install the latest version of merlin");
485 private function _print_states_for_services($host_name=false)
487 $res = Livestatus
::instance()->getServices(array('columns' => array('host_name', 'description'), 'filter' => array('host_name' => $host_name)));
489 $service_arr = array();
491 $classname = get_class($this->options
);
492 $opts = new $classname($this->options
);
493 $opts['report_type'] = 'services';
494 foreach ($res as $row)
495 $service_arr[] = $row['host_name'] . ';' . $row['description'];
496 $opts['objects'] = $service_arr;
497 $report_class = new Status_Reports_Model($opts);
499 $data_arr = $report_class->get_uptime();
506 * Fetch data from report_class
507 * Uses split_month_data() to split start- and end_time
510 * @param $months = false
513 private function get_sla_data($months)
515 if (empty($months)) {
519 // OK, we have start and end but we will have to split
520 // this time into parts according to sla_periods (months)
521 $time_arr = $this->_split_month_data($this->options
['start_time'], $this->options
['end_time']);
522 // only use month entered by the user regardless of start- or endtime
524 $opts = new Avail_options($this->options
);
525 $opts['report_period'] = 'custom';
526 foreach ($time_arr as $mnr => $dates) {
527 $opts['start_time'] = $dates['start'];
528 $opts['end_time'] = $dates['end'];
529 $report_class = new Status_Reports_Model($opts);
530 $data_tmp = $report_class->get_uptime();
531 # So, all this does is to remove the summary for all reports?
532 # That's anti-clever!
533 foreach ($data_tmp as $group => $val) {
534 if (!is_array($val) ||
!isset($val['states']))
536 $data[$group][$mnr] = $val;
539 return $this->_sla_group_data($data);
543 * Mangle SLA data for host- and servicegroups
545 private function _sla_group_data($sla_data)
547 if (empty($sla_data))
549 $report_data = array();
550 foreach ($sla_data as $period_data) {
551 $table_data = array();
554 // loop over whole period for current group
555 foreach ($period_data as $period_start => $tmp_data) {
556 if (!is_array($tmp_data) ||
!isset($tmp_data['states']))
558 $month_idx = date('n', $period_start);
559 if (array_key_exists($month_idx, $this->options
['months'])) {
560 if (arr
::search($tmp_data, 'states')) {
562 # $tmp_data['states']['PERCENT_TOTAL_TIME_{UP,OK}']
563 $real_val = $tmp_data['states'][self
::$sla_field_names[$this->options
['report_type']]];
565 # control colour of bar depending on value
566 # true = green, false = red
567 $sla_ok = $this->options
['months'][$month_idx] > $real_val ?
true : false;
569 // create empty 'real' values
574 $data[date('M', $period_start)] = array($real_val, $this->options
['months'][$month_idx], $sla_ok);
575 if ($this->options
['scheduleddowntimeasuptime'] == 2)
576 $table_data[$period_start] = array($real_val, $this->options
['months'][$month_idx], $tmp_data['states']['PERCENT_TIME_DOWN_COUNTED_AS_UP']);
578 $table_data[$period_start] = array($real_val, $this->options
['months'][$month_idx]);
581 foreach ($tmp_data as $subobj) {
582 if (!is_array($subobj) ||
!isset($subobj['states']))
584 $source[] = $subobj['source'];
586 $name = isset($tmp_data['groupname']) ?
$tmp_data['groupname'] : false;
589 if (!$name && count($source) == 1)
592 $report_data[] = array(
594 'table_data' => $table_data,
595 'data_str' => http_build_query($data),
597 'avail_link' => $this->_generate_avail_member_link(),
604 * @param string $members
605 * @return string A link to an Availability report for all members
607 private function _generate_avail_member_link()
610 $return = url
::site().'avail/generate?';
611 $return .= $this->options
->as_keyval_string(false);
616 * @desc Splits a span of unixtime(start_time, end_time) into slices for every month number in $months.
617 * @param $start_time int start timestamp of the first month
618 * @param $end_time int end timestamp of the last month
619 * @return array of start/end timestamps for every timestamp gives the start and end of the month
621 private function _split_month_data($start_time, $end_time)
625 while ($date < $end_time) {
626 $end = strtotime('+1 month', $date);
627 $months[$date] = array('start' => $date, 'end' => $end);
634 * Translated helptexts for this controller
636 public static function _helptexts($id)
639 'scheduled_downtime' => _("Select if downtime that occurred during scheduled downtime should be counted as the actual state, as uptime, or if it should be counted as uptime but also showing the difference that makes."),
640 'stated_during_downtime' => _("If the application is not running for some time during a report period we can by this ".
641 "option decide to assume states for hosts and services during the downtime."),
642 'includesoftstates' => _("A problem is classified as a SOFT problem until the number of checks has reached the ".
643 "configured max_check_attempts value. When max_check_attempts is reached the problem is reclassified as HARD."),
644 'sla_mode' => _("What calculation method to use for the report summary.<br/>".
645 "Depending on how your network is configured, your SLA might be the group availability (worst state at any point in time) or cluster mode availability (best state at any point time). You can also choose to use average values instead for ".
646 "the group or object in question.<br/>Note that calculating the summary incorrectly could mislead users."),
647 'use_alias' => _("Select if you would like to see host aliases in the generated reports instead of just the host_name"),
648 'csv_format' => _("The CSV (comma-separated values) format is a file format that stores tabular data. This format is supported ".
649 "by many applications such as MS Excel, OpenOffice and Google Spreadsheets."),
650 'save_report' => _("Check this box if you want to save the configured report for later use."),
651 'enter-sla' => _("Enter the selected SLA values for each month. Percent values (0.00-100.00) are assumed."),
652 'report_settings_sml' => _("Here you can modify the report settings for the report you are currently viewing."),
653 'log_entries' => _("Shows the actual log messages that this report was created of."),
654 'hostgroup_breakdown' => _("Here you have a list of all hosts that are member of this hostgroup and their states."),
655 'servicegroup_breakdown' => _("Here you have a list of all services that are member of this servicegroup and their states."),
656 'average_and_sla' => _("Shows the Average and SLA values for all selected services above."), // text ok?
657 'availability' => _("This table shows a breakdown of the different states. How much time that was ok, warning, unknown, critical or undetermined in both actual time and percent. Time is also divied between uncheduled and scheduled which helps you to separate unplanned and planned events."),
658 'piechart' => _("Pie chart that displays how much time in percent that was ok, warning, unknown, critical or undetermined."),
659 'sla_graph' => _("Graphical report of the SLA. Green bars meens that the SLA was fulfilled and red that it was not fulfilled."),
660 'sla_breakdown' => _("Breakdown of the SLA report in actual figures."),
661 'sla_group_members' => _("Members of the selected group that the report is generated for. All members are links to individual reports."),
662 'trends' => _("Shows trends during selected report period, lines above the main line are upscaled statechanges from the blacked out section below."),
663 'trends_scaling' => _("Scale up rapid state changes into a line above the main line."),
664 'collapse_green_trends' => _("Hide trends that are 100% Up/OK during the report period. This reduces visual noise to help you correlate events."),
665 'use-sla-values' => _("Load SLA-values from previously saved reports. Just select a report in the list and it will autoload."),
666 'include_pie_charts' => _('If you include this, your availability percentages will be graphed in pie charts'),
668 // new scheduled report
669 'report-type-save' => _("Select what type of report you would like to schedule the creation of"),
670 'select-report' => _("Select which report you want to you want to schedule"), // text ok?
671 'report' => _("Select the saved report to schedule"),
672 'interval' => _("Select how often the report is to be produced and delivered"),
673 'recipents' => _("Enter the email addresses of the recipients of the report. To enter multiple addresses, separate them by commas"),
674 'filename' => _("This field lets you select a custom filename for the report. If the name ends in <strong>.csv</strong>, a CSV file will be generated - otherwise a PDF will be generated."),
675 'start-date' => _("Enter the start date for the report (or use the pop-up calendar)."),
676 'end-date' => _("Enter the end date for the report (or use the pop-up calendar)."),
677 'local_persistent_filepath' => _("Specify an absolute path on the local disk, where you want the report to be saved in PDF format.").'<br />'._("This should be the location of a folder, for example /tmp"),
678 'attach_description' => _("Append this description inside the report's header to the general description given for the report"),
679 'include_trends' => _("Check this to include a trends graph in your report.<br>Warning: This can make your reports slow!"),
680 'include_trends_scaling' => _("Check this to get upscaled values on your trends graph for small segments of time that would otherwise be hidden."),
681 'include_alerts' => _('Include a log of all alerts for all objects in your report.<br>Warning: This can make your reports slow!'),
682 'synergy_events' => _('Include a detailed history of what happened to BSM objects'),
684 if (array_key_exists($id, $helptexts))
685 echo $helptexts[$id];
687 parent
::_helptexts($id);