pandorafms/pandora_console/operation/reporting/graph_viewer.php

584 lines
19 KiB
PHP

<?php
/**
* Graph viewer.
*
* @category Reporting
* @package Pandora FMS
* @subpackage Community
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2005-2023 Pandora FMS
* Please see https://pandorafms.com/community/ for full contribution list
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation for version 2.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* ============================================================================
*/
// Begin.
global $config;
check_login();
require_once 'include/functions_custom_graphs.php';
$delete_graph = (bool) get_parameter('delete_graph');
$view_graph = (bool) get_parameter('view_graph');
$id_graph = (int) get_parameter('id');
if ($id_graph !== 0) {
$sql = "SELECT * FROM tgraph
WHERE (private = 0 OR (private = 1 AND id_user = '".$config['id_user']."'))
AND id_graph = ".$id_graph;
$control = db_process_sql($sql);
if (!$control) {
header('Location: index.php?sec=reporting&sec2=godmode/reporting/graphs');
}
}
// Delete module SQL code.
if ($delete_graph) {
if (check_acl($config['id_user'], 0, 'AW')) {
$res = db_process_sql_delete('tgraph_source', ['id_graph' => $id_graph]);
if ($res) {
$result = ui_print_success_message(__('Successfully deleted'), '', true);
} else {
$result = ui_print_error_message(__('Not deleted. Error deleting data'), '', true);
}
$res = db_process_sql_delete('tgraph', ['id_graph' => $id_graph]);
if ($res) {
$result = ui_print_success_message(__('Successfully deleted'), '', true);
} else {
$result = ui_print_error_message(__('Not deleted. Error deleting data'), '', true);
}
echo $result;
} else {
db_pandora_audit(
AUDIT_LOG_ACL_VIOLATION,
'Trying to delete a graph from access graph builder'
);
include 'general/noaccess.php';
exit;
}
}
if ($view_graph) {
$sql = "SELECT * FROM tgraph_source WHERE id_graph = $id_graph";
$sources = db_get_all_rows_sql($sql);
if ($sources === false) {
$sources = [];
}
$sql = "SELECT * FROM tgraph WHERE id_graph = $id_graph";
$graph = db_get_row_sql($sql);
$id_user = $graph['id_user'];
$private = $graph['private'];
$width = $graph['width'];
$height = ($graph['height'] + count($sources) * 10);
$zoom = (int) get_parameter('zoom', 0);
// Increase the height to fix the leyend rise
if ($zoom > 0) {
switch ($zoom) {
case 1:
$width = 500;
$height = (200 + count($sources) * 15);
break;
case 2:
$width = 650;
$height = (300 + count($sources) * 10);
break;
case 3:
$width = 770;
$height = (400 + count($sources) * 5);
break;
}
}
// Get different date to search the report.
$date = (string) get_parameter('date', date(DATE_FORMAT));
$time = (string) get_parameter('time', date(TIME_FORMAT));
$unixdate = strtotime($date.' '.$time);
$period = (int) get_parameter('period');
if (! $period) {
$period = $graph['period'];
} else {
$period = $period;
}
$events = $graph['events'];
$description = $graph['description'];
$stacked = (int) get_parameter('stacked', -1);
$percentil = ($graph['percentil']) ? 1 : null;
$check = get_parameter('threshold', false);
$fullscale = ($graph['fullscale']) ? 1 : null;
if ($check == CUSTOM_GRAPH_BULLET_CHART_THRESHOLD) {
$check = true;
$stacked = CUSTOM_GRAPH_BULLET_CHART_THRESHOLD;
}
if ($stacked == -1) {
$stacked = $graph['stacked'];
}
if ($stacked == CUSTOM_GRAPH_BULLET_CHART || $stacked == CUSTOM_GRAPH_BULLET_CHART_THRESHOLD) {
$height = 50;
}
if ($stacked == CUSTOM_GRAPH_GAUGE) {
// Use the defined graph height, that's why
// the user can setup graph height.
$height = $graph['height'];
}
$name = $graph['name'];
if (($graph['private'] == 1) && ($graph['id_user'] != $id_user)) {
db_pandora_audit(
AUDIT_LOG_ACL_VIOLATION,
'Trying to access to a custom graph not allowed'
);
include 'general/noaccess.php';
exit;
}
html_print_input_hidden('line_width_graph', $config['custom_graph_width']);
html_print_input_hidden('custom_graph', 1);
$url = 'index.php?'.'sec=reporting&'.'sec2=operation/reporting/graph_viewer&'."id=$id_graph&".'view_graph=1';
$options = [];
if (check_acl_restricted_all($config['id_user'], $graph['id_group'], 'RW')
|| check_acl_restricted_all($config['id_user'], $graph['id_group'], 'RM')
) {
$options = [
'graph_list' => [
'active' => false,
'text' => '<a href="index.php?sec=reporting&sec2=godmode/reporting/graphs">'.html_print_image(
'images/logs@svg.svg',
true,
[
'title' => __('Graph list'),
'class' => 'main_menu_icon invert_filter',
]
).'</a>',
],
'main' => [
'active' => false,
'text' => '<a href="index.php?sec=reporting&sec2=godmode/reporting/graph_builder&tab=main&edit_graph=1&id='.$id_graph.'">'.html_print_image(
'images/graph@svg.svg',
true,
[
'title' => __('Main data'),
'class' => 'invert_filter',
]
).'</a>',
],
'graph_editor' => [
'active' => false,
'text' => '<a href="index.php?sec=reporting&sec2=godmode/reporting/graph_builder&tab=graph_editor&edit_graph=1&id='.$id_graph.'">'.html_print_image(
'images/builder@svg.svg',
true,
[
'title' => __('Graph editor'),
'class' => 'main_menu_icon invert_filter',
]
).'</a>',
],
];
} else {
$options = [
'graph_list' => [
'active' => false,
'text' => '<a href="index.php?sec=reporting&sec2=godmode/reporting/graphs">'.html_print_image('images/logs@svg.svg', true, ['title' => __('Graph list'), 'class' => 'main_menu_icon invert_filter']).'</a>',
],
];
}
$options['view']['text'] = '<a href="index.php?sec=reporting&sec2=operation/reporting/graph_viewer&view_graph=1&id='.$id_graph.'">'.html_print_image(
'images/enable.svg',
true,
[
'title' => __('View graph'),
'class' => 'main_menu_icon invert_filter',
]
).'</a>';
$options['view']['active'] = true;
if ($config['pure'] == 0) {
$options['screen']['text'] = "<a href='$url&pure=1'>".html_print_image(
'images/fullscreen@svg.svg',
true,
[
'title' => __('Full screen mode'),
'class' => 'main_menu_icon invert_filter',
]
).'</a>';
} else {
$options['screen']['text'] = "<a href='$url&pure=0'>".html_print_image(
'images/exit_fullscreen@svg.svg',
true,
[
'title' => __('Back to normal mode'),
'class' => 'main_menu_icon invert_filter',
]
).'</a>';
// In full screen, the manage options are not available.
$options = [
'view' => $options['view'],
'screen' => $options['screen'],
];
}
if (!is_ajax()) {
// Header.
ui_print_standard_header(
$graph['name'],
'images/chart.png',
false,
'',
false,
$options,
[
[
'link' => '',
'label' => __('Reporting'),
],
[
'link' => '',
'label' => __('Custom graphs'),
],
]
);
}
$width = null;
$height = null;
$params = [
'period' => $period,
'width' => $width,
'height' => $height,
'date' => $unixdate,
'percentil' => $percentil,
'fullscale' => $fullscale,
];
if ($stacked === CUSTOM_GRAPH_AREA || $stacked === CUSTOM_GRAPH_STACKED_AREA) {
$params['type_graph'] = 'area';
} else if ($stacked === CUSTOM_GRAPH_LINE || $stacked === CUSTOM_GRAPH_STACKED_LINE) {
$params['type_graph'] = 'line';
}
$params_combined = [
'stacked' => $stacked,
'id_graph' => $id_graph,
];
$graph_return = graphic_combined_module(
false,
$params,
$params_combined
);
if (is_ajax()) {
echo $graph_return;
return;
}
if ($stacked == CUSTOM_GRAPH_BULLET_CHART_THRESHOLD) {
$stacked = 4;
}
$period_label = human_time_description_raw($period);
$searchForm = '<form method="POST" action="index.php?sec=reporting&sec2=operation/reporting/graph_viewer&view_graph=1&id='.$id_graph.'">';
$searchForm .= "<table class='filter-table-adv w100p' cellpadding='4' cellspacing='4'>";
$searchForm .= '<tr>';
$searchForm .= '<td class="w30p">';
$searchForm .= html_print_label_input_block(
__('Date'),
html_print_input_text(
'date',
$date,
'',
'',
10,
true
)
);
$searchForm .= '</td><td class="datos w30p">';
$searchForm .= html_print_label_input_block(
__('Time'),
html_print_input_text(
'time',
$time,
'',
'',
7,
true
)
);
$searchForm .= '</td>';
$searchForm .= "<td class='datos w30p'>";
$searchForm .= html_print_label_input_block(
__('Time range'),
html_print_extended_select_for_time('period', (string) $period, '', '', 0, 10, true, 'width:100%')
);
$searchForm .= '</td>';
$searchForm .= '</tr><tr>';
$searchForm .= "<td class='datos w30p'>";
$stackeds = [];
$stackeds[0] = __('Graph defined');
$stackeds[CUSTOM_GRAPH_AREA] = __('Area');
$stackeds[CUSTOM_GRAPH_STACKED_AREA] = __('Stacked area');
$stackeds[CUSTOM_GRAPH_LINE] = __('Line');
$stackeds[CUSTOM_GRAPH_STACKED_LINE] = __('Stacked line');
$stackeds[CUSTOM_GRAPH_BULLET_CHART] = __('Bullet chart');
$stackeds[CUSTOM_GRAPH_GAUGE] = __('Gauge');
$stackeds[CUSTOM_GRAPH_HBARS] = __('Horizontal Bars');
$stackeds[CUSTOM_GRAPH_VBARS] = __('Vertical Bars');
$stackeds[CUSTOM_GRAPH_PIE] = __('Pie');
$searchForm .= html_print_label_input_block(__('Type'), html_print_select($stackeds, 'stacked', $stacked, '', '', -1, true, false, true, '', false, 'width:100%'));
$searchForm .= '</td>';
$searchForm .= "<td class='datos w30p'>";
$searchForm .= html_print_label_input_block(
__('Equalize maxiddmum thresholds').ui_print_help_tip(
__('If an option is selected, all graphs will have the highest value from all modules included in the graph as a maximum threshold'),
true
),
html_print_checkbox(
'threshold',
CUSTOM_GRAPH_BULLET_CHART_THRESHOLD,
$check,
true,
false,
'',
false
),
['div_id' => 'thresholdDiv']
);
$searchForm .= '</td>';
$searchForm .= "<td class='datos w30p'>";
$zooms = [];
$zooms[0] = __('Graph defined');
$zooms[1] = __('Zoom x1');
$zooms[2] = __('Zoom x2');
$zooms[3] = __('Zoom x3');
$searchForm .= html_print_label_input_block(__('Zoom'), html_print_select($zooms, 'zoom', $zoom, '', '', 0, true, false, true, '', false, 'width:100%'));
$searchForm .= '</td>';
$searchForm .= '</tr>';
$searchForm .= '</table>';
$searchForm .= html_print_div(
[
'class' => 'action-buttons',
'content' => html_print_submit_button(
__('Filter'),
'submit-refresh',
false,
[
'mode' => 'mini',
'icon' => 'search',
],
true
),
],
true
);
$searchForm .= '</form>';
ui_toggle(
$searchForm,
'<span class="subsection_header_title">'.__('Filters').'</span>',
'filter_form',
'',
true,
false,
'',
'white-box-content',
'box-flat white_table_graph fixed_filter_bar'
);
if ($graph_return) {
echo '<div class="container-custom-graph">';
if (!is_ajax()) {
echo '<div id="spinner_loading" class="loading invisible" style="display:flex;flex-direction:column-reverse;justify-content:center;align-items:center">';
echo html_print_image('images/spinner.gif', true, ['width' => '20px']);
echo __('Loading').'&hellip;';
echo '</div>';
}
echo '<div id="div-container" class="w100p" style="height:100%;">';
echo '<div style="position: relative; display: flex; flex-direction:row; justify-content: center; align-items: center; align-content: center; width:100%; height:50vh;">';
echo '<div style="flex: 0 0 auto; width:99%; height:100%;">';
echo $graph_return;
echo '</div>';
echo '</div>';
echo '</div>';
echo '</div>';
} else {
ui_print_info_message([ 'no_close' => true, 'message' => __('No data.') ]);
}
/*
We must add javascript here. Otherwise, the date picker won't
work if the date is not correct because php is returning.
*/
ui_include_time_picker();
ui_require_jquery_file('ui.datepicker-'.get_user_language(), 'include/javascript/i18n/');
ui_require_jquery_file('');
?>
<script language="javascript" type="text/javascript">
$(document).ready (function () {
$("#spinner_loading").hide();
$("#loading").slideUp ();
$("#text-time").timepicker({
showSecond: true,
timeFormat: '<?php echo TIME_FORMAT_JS; ?>',
timeOnlyTitle: '<?php echo __('Choose time'); ?>',
timeText: '<?php echo __('Time'); ?>',
hourText: '<?php echo __('Hour'); ?>',
minuteText: '<?php echo __('Minute'); ?>',
secondText: '<?php echo __('Second'); ?>',
currentText: '<?php echo __('Now'); ?>',
closeText: '<?php echo __('Close'); ?>'});
$.datepicker.setDefaults($.datepicker.regional[ "<?php echo get_user_language(); ?>"]);
$("#text-date").datepicker({
dateFormat: "<?php echo DATE_FORMAT_JS; ?>",
changeMonth: true,
changeYear: true,
showAnim: "slideDown"});
if ($("#stacked").val() == '4') {
$("#thresholdDiv").show();
}else{
$("#thresholdDiv").hide();
}
$("#submit-refresh").click(function(e) {
e.preventDefault();
$("#spinner_loading").show();
var data = {
page: "operation/reporting/graph_viewer",
view_graph: 1,
id: '<?php echo $id_graph; ?>',
zoom: $('#zoom').val(),
date: $('#text-date').val(),
time: $('#text-time').val(),
period: $('select[id^=period][id$=select]').val(),
stacked: $('#stacked').val(),
}
if (data['stacked'] == 4 && $('#checkbox-threshold').is(':checked')) {
data['threshold'] = 1;
}
(function (stacked) {
$.ajax({
type: "POST",
url: "ajax.php",
dataType: "html",
data: data,
success: function (data) {
if (stacked === "<?php echo CUSTOM_GRAPH_VBARS; ?>") {
document.getElementById("div-container").classList.add('w100p', 'height_600px');
}
document.getElementById("div-container").innerHTML = "";
$("#spinner_loading").hide();
$("#div-container").append(data);
},
error: function (data) {
console.error("Fatal error")
}
});
})(data['stacked']);
});
});
$("#stacked").change(function(){
if ($(this).val() == '4') {
$("#thresholdDiv").show();
$(".stacked").show();
} else {
$("[name=threshold]").prop("checked", false);
$(".stacked").show();
$("#thresholdDiv").hide();
}
});
</script>
<?php
$datetime = strtotime($date.' '.$time);
$report['datetime'] = $datetime;
if ($datetime === false || $datetime == -1) {
ui_print_error_message(__('Invalid date selected'));
return;
}
return;
}
// Header.
ui_print_page_header(__('Reporting').' &raquo; '.__('Custom graph viewer'), 'images/op_reporting.png', false, '', false, '');
$graphs = custom_graphs_get_user();
if (! empty($graphs)) {
$table = new stdClass();
$table->width = '100%';
$tale->class = 'databox_frame';
$table->align = [];
$table->align[2] = 'center';
$table->head = [];
$table->head[0] = __('Graph name');
$table->head[1] = __('Description');
$table->data = [];
foreach ($graphs as $graph) {
$data = [];
$data[0] = '<a href="index.php?sec=reporting&sec2=operation/reporting/graph_viewer&view_graph=1&id='.$graph['id_graph'].'">'.$graph['name'].'</a>';
$data[1] = $graph['description'];
array_push($table->data, $data);
}
html_print_table($table);
} else {
echo "<div class='nf'>".__('There are no defined reportings').'</div>';
}