__('Delete'), 2 => __('Duplicate'), 3 => __('Change Settings'), 4 => __('Full Sync Graphs'), 5 => __('Quick Sync Graphs') ]; // set default action set_default_action(); switch (grv('action')) { case 'save': form_save(); break; case 'actions': form_actions(); break; case 'ajax_data_sources': $data_template_id = gfrv('data_template_id'); $task_item_id = gfrv('task_item_id'); $orig_task_item_id = gfrv('_task_item_id'); $data_sources = db_fetch_assoc_prepared("SELECT dtr.id, CONCAT_WS('', dt.name,' - ',' (', dtr.data_source_name,')') AS name FROM data_template_rrd AS dtr INNER JOIN data_template AS dt ON dtr.data_template_id = dt.id WHERE dtr.local_data_id = 0 AND (dtr.data_template_id = ? OR dtr.id = ?) ORDER BY dt.name, dtr.data_source_name", [$data_template_id, $task_item_id] ); $output = ''; if (cacti_sizeof($data_sources)) { foreach ($data_sources as $ds) { if ($orig_task_item_id == $ds['id']) { $output .= ''; } elseif ($task_item_id == $ds['id']) { $output .= ''; } else { $output .= ''; } } } else { $output .= ''; } print $output; break; case 'ajax_dnd': $graph_template_id = gfrv('id'); $sequences = gnrv('item_ids'); if (cacti_sizeof($sequences)) { foreach ($sequences as $index => $s) { $new_seq = $index++; // graph template first db_execute_prepared('UPDATE graph_templates_item SET sequence = ? WHERE local_graph_template_item_id = ? AND graph_template_id = ?', [$new_seq, $s, $graph_template_id]); // graphs next db_execute_prepared('UPDATE graph_templates_item SET sequence = ? WHERE id = ? AND local_graph_id = 0 AND graph_template_id = ?', [$new_seq, $s, $graph_template_id]); } } header('Location: graph_templates.php?action=template_edit&id=' . gfrv('id')); break; case 'item_remove': gfrv('graph_template_id'); item_remove(); header('Location: graph_templates.php?action=template_edit&id=' . grv('graph_template_id')); break; case 'item_movedown': gfrv('graph_template_id'); item_movedown(); header('Location: graph_templates.php?action=template_edit&id=' . grv('graph_template_id')); break; case 'item_moveup': gfrv('graph_template_id'); item_moveup(); header('Location: graph_templates.php?action=template_edit&id=' . grv('graph_template_id')); break; case 'item_edit': top_header(); item_edit(); bottom_footer(); break; case 'item': top_header(); item(); bottom_footer(); break; case 'input_remove': gfrv('graph_template_id'); input_remove(); header('Location: graph_templates.php?action=template_edit&id=' . grv('graph_template_id')); break; case 'input_edit': top_header(); input_edit(); bottom_footer(); break; case 'template_edit': top_header(); template_edit(); bottom_footer(); break; default: top_header(); graph_templates(); bottom_footer(); break; } function form_save() : void { // sanitize ids if (isrv('graph_template_id') && !is_numeric(gnrv('graph_template_id'))) { $graph_template_id = 0; } else { $graph_template_id = gfrv('graph_template_id'); } if (isrv('save_component_template')) { // ================= input validation ================= gfrv('graph_template_graph_id'); // ==================================================== $push_title = true; if ($graph_template_id > 0) { $prev_title = db_fetch_cell_prepared('SELECT title FROM graph_templates_graph WHERE graph_template_id = ? AND local_graph_id = 0', [$graph_template_id]); if ($prev_title == gnrv('title')) { $push_title = false; } } $save1['id'] = $graph_template_id; $save1['hash'] = get_hash_graph_template($graph_template_id); $save1['name'] = CactiValidator::validateInput(gnrv('name'), 'name', [new Assert\NotBlank()], 3); $save1['class'] = CactiValidator::validateInput(gnrv('class'), 'class', [], 3); $save1['version'] = CactiValidator::validateInput(gnrv('version'), 'version', [], 3); $save1['multiple'] = isrv('multiple') ? 'on' : ''; $save1['test_source'] = isrv('test_source') ? 'on' : ''; $save2['id'] = gnrv('graph_template_graph_id'); $save2['local_graph_template_graph_id'] = 0; $save2['local_graph_id'] = 0; $save2['t_image_format_id'] = (isrv('t_image_format_id') ? gnrv('t_image_format_id') : ''); $save2['image_format_id'] = CactiValidator::validateInput(gnrv('image_format_id'), 'image_format_id', [new Assert\Regex('/^[0-9]+$/')], 3); $save2['t_title'] = CactiValidator::validateInput((isrv('t_title') ? gnrv('t_title') : ''), 't_title', [], 3); $save2['title'] = CactiValidator::validateInput(gnrv('title'), 'title', (isrv('t_title') ? [] : [new Assert\NotBlank()]), 3); $save2['t_height'] = CactiValidator::validateInput((isrv('t_height') ? gnrv('t_height') : ''), 't_height', [], 3); $save2['height'] = CactiValidator::validateInput(gnrv('height'), 'height', [new Assert\Regex('/^[0-9]+$/')], 3); $save2['t_width'] = CactiValidator::validateInput((isrv('t_width') ? gnrv('t_width') : ''), 't_width', [], 3); $save2['width'] = CactiValidator::validateInput(gnrv('width'), 'width', [new Assert\Regex('/^[0-9]+$/')], 3); $save2['t_upper_limit'] = CactiValidator::validateInput((isrv('t_upper_limit') ? gnrv('t_upper_limit') : ''), 't_upper_limit', [], 3); $save2['upper_limit'] = CactiValidator::validateInput(gnrv('upper_limit'), 'upper_limit', [new Assert\Regex('/^(-?([0-9]+(\.[0-9]*)?|[0-9]*\.[0-9]+)([eE][+\-]?[0-9]+)?|U)\z/')], 3); $save2['t_lower_limit'] = CactiValidator::validateInput((isrv('t_lower_limit') ? gnrv('t_lower_limit') : ''), 't_lower_limit', [], 3); $save2['lower_limit'] = CactiValidator::validateInput(gnrv('lower_limit'), 'lower_limit', [new Assert\Regex('/^(-?([0-9]+(\.[0-9]*)?|[0-9]*\.[0-9]+)([eE][+\-]?[0-9]+)?|U)\z/')], 3); $save2['t_vertical_label'] = CactiValidator::validateInput((isrv('t_vertical_label') ? gnrv('t_vertical_label') : ''), 't_vertical_label', [], 3); $save2['vertical_label'] = CactiValidator::validateInput(gnrv('vertical_label'), 'vertical_label', [], 3); $save2['t_vertical_label_angle'] = CactiValidator::validateInput((isrv('t_vertical_label_angle') ? gnrv('t_vertical_label_angle') : ''), 't_vertical_label_angle', [new Assert\Choice(['', 'on'])], 3); $save2['vertical_label_angle'] = CactiValidator::validateRrdGraphAxisInput((isrv('vertical_label_angle') ? gnrv('vertical_label_angle') : ''), 'vertical_label_angle'); $save2['t_right_axis_label_angle'] = CactiValidator::validateInput((isrv('t_right_axis_label_angle') ? gnrv('t_right_axis_label_angle') : ''), 't_right_axis_label_angle', [new Assert\Choice(['', 'on'])], 3); $save2['right_axis_label_angle'] = CactiValidator::validateRrdGraphAxisInput((isrv('right_axis_label_angle') ? gnrv('right_axis_label_angle') : ''), 'right_axis_label_angle'); $save2['t_right_axis_range'] = CactiValidator::validateInput((isrv('t_right_axis_range') ? gnrv('t_right_axis_range') : ''), 't_right_axis_range', [new Assert\Choice(['', 'on'])], 3); $save2['right_axis_range'] = CactiValidator::validateRrdGraphAxisInput((isrv('right_axis_range') ? gnrv('right_axis_range') : ''), 'right_axis_range'); $save2['t_slope_mode'] = CactiValidator::validateInput((isrv('t_slope_mode') ? gnrv('t_slope_mode') : ''), 't_slope_mode', [], 3); $save2['slope_mode'] = CactiValidator::validateInput((isrv('slope_mode') ? gnrv('slope_mode') : ''), 'slope_mode', [], 3); $save2['t_auto_scale'] = CactiValidator::validateInput((isrv('t_auto_scale') ? gnrv('t_auto_scale') : ''), 't_auto_scale', [], 3); $save2['auto_scale'] = CactiValidator::validateInput((isrv('auto_scale') ? gnrv('auto_scale') : ''), 'auto_scale', [], 3); $save2['t_auto_scale_opts'] = CactiValidator::validateInput((isrv('t_auto_scale_opts') ? gnrv('t_auto_scale_opts') : ''), 't_auto_scale_opts', [], 3); $save2['auto_scale_opts'] = CactiValidator::validateInput(gnrv('auto_scale_opts'), 'auto_scale_opts', [], 3); $save2['t_auto_scale_log'] = CactiValidator::validateInput((isrv('t_auto_scale_log') ? gnrv('t_auto_scale_log') : ''), 't_auto_scale_log', [], 3); $save2['auto_scale_log'] = CactiValidator::validateInput((isrv('auto_scale_log') ? gnrv('auto_scale_log') : ''), 'auto_scale_log', [], 3); $save2['t_scale_log_units'] = CactiValidator::validateInput((isrv('t_scale_log_units') ? gnrv('t_scale_log_units') : ''), 't_scale_log_units', [], 3); $save2['scale_log_units'] = CactiValidator::validateInput((isrv('scale_log_units') ? gnrv('scale_log_units') : ''), 'scale_log_units', [], 3); $save2['t_auto_scale_rigid'] = CactiValidator::validateInput((isrv('t_auto_scale_rigid') ? gnrv('t_auto_scale_rigid') : ''), 't_auto_scale_rigid', [], 3); $save2['auto_scale_rigid'] = CactiValidator::validateInput((isrv('auto_scale_rigid') ? gnrv('auto_scale_rigid') : ''), 'auto_scale_rigid', [], 3); $save2['t_auto_padding'] = CactiValidator::validateInput((isrv('t_auto_padding') ? gnrv('t_auto_padding') : ''), 't_auto_padding', [], 3); $save2['auto_padding'] = CactiValidator::validateInput((isrv('auto_padding') ? gnrv('auto_padding') : ''), 'auto_padding', [], 3); $save2['t_base_value'] = CactiValidator::validateInput((isrv('t_base_value') ? gnrv('t_base_value') : ''), 't_base_value', [], 3); $save2['base_value'] = CactiValidator::validateInput(gnrv('base_value'), 'base_value', [new Assert\Regex('/^[0-9]+$/')], 3); $save2['t_unit_value'] = CactiValidator::validateInput((isrv('t_unit_value') ? gnrv('t_unit_value') : ''), 't_unit_value', [], 3); $save2['unit_value'] = CactiValidator::validateInput(gnrv('unit_value'), 'unit_value', [], 3); $save2['t_unit_exponent_value'] = CactiValidator::validateInput((isrv('t_unit_exponent_value') ? gnrv('t_unit_exponent_value') : ''), 't_unit_exponent_value', [], 3); $save2['unit_exponent_value'] = CactiValidator::validateInput(gnrv('unit_exponent_value'), 'unit_exponent_value', [new Assert\Regex('/^-?[0-9]+$/')], 3); $save2['t_alt_y_grid'] = CactiValidator::validateInput((isrv('t_alt_y_grid') ? gnrv('t_alt_y_grid') : ''), 't_alt_y_grid', [], 3); $save2['alt_y_grid'] = CactiValidator::validateInput((isrv('alt_y_grid') ? gnrv('alt_y_grid') : ''), 'alt_y_grid', [], 3); $save2['t_right_axis'] = CactiValidator::validateInput((isrv('t_right_axis') ? gnrv('t_right_axis') : ''), 't_right_axis', [], 3); $save2['right_axis'] = CactiValidator::validateInput((isrv('right_axis') ? gnrv('right_axis') : ''), 'right_axis', [new Assert\Regex('/^-?([0-9]+(\.[0-9]*)?|\.[0-9]+):-?([0-9]+(\.[0-9]*)?|\.[0-9]+)$/')], 3); $save2['t_right_axis_label'] = CactiValidator::validateInput((isrv('t_right_axis_label') ? gnrv('t_right_axis_label') : ''), 't_right_axis_label', [], 3); $save2['right_axis_label'] = CactiValidator::validateInput((isrv('right_axis_label') ? gnrv('right_axis_label') : ''), 'right_axis_label', [], 3); $save2['t_right_axis_format'] = CactiValidator::validateInput((isrv('t_right_axis_format') ? gnrv('t_right_axis_format') : ''), 't_right_axis_format', [], 3); $save2['right_axis_format'] = CactiValidator::validateInput((isrv('right_axis_format') ? gnrv('right_axis_format') : ''), 'right_axis_format', [new Assert\Regex('/^[0-9]+$/')], 3); $save2['t_no_gridfit'] = CactiValidator::validateInput((isrv('t_no_gridfit') ? gnrv('t_no_gridfit') : ''), 't_no_gridfit', [], 3); $save2['no_gridfit'] = CactiValidator::validateInput((isrv('no_gridfit') ? gnrv('no_gridfit') : ''), 'no_gridfit', [], 3); $save2['t_unit_length'] = CactiValidator::validateInput((isrv('t_unit_length') ? gnrv('t_unit_length') : ''), 't_unit_length', [], 3); $save2['unit_length'] = CactiValidator::validateInput((isrv('unit_length') ? gnrv('unit_length') : ''), 'unit_length', [new Assert\Regex('/^[0-9]+$/')], 3); $save2['t_tab_width'] = CactiValidator::validateInput((isrv('t_tab_width') ? gnrv('t_tab_width') : ''), 't_tab_width', [], 3); $save2['tab_width'] = CactiValidator::validateInput((isrv('tab_width') ? gnrv('tab_width') : ''), 'tab_width', [new Assert\Regex('/^[0-9]*$/')], 3); $save2['t_dynamic_labels'] = CactiValidator::validateInput((isrv('t_dynamic_labels') ? gnrv('t_dynamic_labels') : ''), 't_dynamic_labels', [], 3); $save2['dynamic_labels'] = CactiValidator::validateInput((isrv('dynamic_labels') ? gnrv('dynamic_labels') : ''), 'dynamic_labels', [], 3); $save2['t_force_rules_legend'] = CactiValidator::validateInput((isrv('t_force_rules_legend') ? gnrv('t_force_rules_legend') : ''), 't_force_rules_legend', [], 3); $save2['force_rules_legend'] = CactiValidator::validateInput((isrv('force_rules_legend') ? gnrv('force_rules_legend') : ''), 'force_rules_legend', [], 3); $save2['t_legend_position'] = CactiValidator::validateInput((isrv('t_legend_position') ? gnrv('t_legend_position') : ''), 't_legend_position', [], 3); $save2['legend_position'] = CactiValidator::validateInput((isrv('legend_position') ? gnrv('legend_position') : ''), 'legend_position', [], 3); $save2['t_legend_direction'] = CactiValidator::validateInput((isrv('t_legend_direction') ? gnrv('t_legend_direction') : ''), 't_legend_direction', [], 3); $save2['legend_direction'] = CactiValidator::validateInput((isrv('legend_direction') ? gnrv('legend_direction') : ''), 'legend_direction', [], 3); $save2['t_right_axis_formatter'] = CactiValidator::validateInput((isrv('t_right_axis_formatter') ? gnrv('t_right_axis_formatter') : ''), 't_right_axis_formatter', [], 3); $save2['right_axis_formatter'] = CactiValidator::validateInput((isrv('right_axis_formatter') ? gnrv('right_axis_formatter') : ''), 'right_axis_formatter', [], 3); $save2['t_left_axis_format'] = CactiValidator::validateInput((isrv('t_left_axis_format') ? gnrv('t_left_axis_format') : ''), 't_left_axis_format', [], 3); $save2['left_axis_format'] = CactiValidator::validateInput((isrv('left_axis_format') ? gnrv('left_axis_format') : ''), 'left_axis_format', [new Assert\Regex('/^[0-9]+$/')], 3); $save2['t_left_axis_formatter'] = CactiValidator::validateInput((isrv('t_left_axis_formatter') ? gnrv('t_left_axis_formatter') : ''), 't_left_axis_formatter', [], 3); $save2['left_axis_formatter'] = CactiValidator::validateInput((isrv('left_axis_formatter') ? gnrv('left_axis_formatter') : ''), 'left_axis_formatter', [], 3); if (!is_error_message()) { $save1['last_updated'] = date('Y-m-d H:i:s'); $graph_template_id = sql_save($save1, 'graph_templates'); if ($graph_template_id) { raise_message(1); } else { raise_message(2); } } if (!is_error_message()) { $save2['graph_template_id'] = $graph_template_id; $graph_template_graph_id = sql_save($save2, 'graph_templates_graph'); if ($graph_template_graph_id) { raise_message(1); push_out_graph($graph_template_graph_id, $push_title); } else { raise_message(2); } } } elseif (isrv('save_component_item')) { // ================= input validation ================= gfrv('graph_template_id'); gfrv('task_item_id'); gfrv('sequence'); gfrv('color_id'); gfrv('color2_id'); gfrv('gradheight'); gfrv('graph_template_item_id'); // ==================================================== global $graph_item_types; $items[0] = []; if ($graph_item_types[gnrv('graph_type_id')] == 'LEGEND') { /* this can be a major time saver when creating lots of graphs with the typical GPRINT LAST/AVERAGE/MAX legends */ $items = [ 0 => [ 'color_id' => '0', 'color2_id' => '0', 'alpha' => '0', 'alpha2' => '0', 'line_width' => '1', 'legend' => '', 'gradheight' => '0', 'graph_type_id' => '9', 'consolidation_function_id' => '4', 'text_format' => __('Cur:'), 'hard_return' => '' ], 1 => [ 'color_id' => '0', 'color2_id' => '0', 'alpha' => '0', 'alpha2' => '0', 'line_width' => '1', 'legend' => '', 'gradheight' => '0', 'graph_type_id' => '9', 'consolidation_function_id' => '1', 'text_format' => __('Avg:'), 'hard_return' => '' ], 2 => [ 'color_id' => '0', 'color2_id' => '0', 'alpha' => '0', 'alpha2' => '0', 'line_width' => '1', 'legend' => '', 'gradheight' => '0', 'graph_type_id' => '9', 'consolidation_function_id' => '3', 'text_format' => __('Max:'), 'hard_return' => 'on' ] ]; } elseif ($graph_item_types[gnrv('graph_type_id')] == 'LEGEND_CAMM') { /* this can be a major time saver when creating lots of graphs with the typical GPRINT LAST/AVERAGE/MAX legends */ $items = [ 0 => [ 'color_id' => '0', 'color2_id' => '0', 'alpha' => '0', 'alpha2' => '0', 'line_width' => '1', 'legend' => '', 'gradheight' => '0', 'graph_type_id' => '9', 'consolidation_function_id' => '4', 'text_format' => __('Cur:'), 'hard_return' => '' ], 1 => [ 'color_id' => '0', 'color2_id' => '0', 'alpha' => '0', 'alpha2' => '0', 'line_width' => '1', 'legend' => '', 'gradheight' => '0', 'graph_type_id' => '9', 'consolidation_function_id' => '1', 'text_format' => __('Avg:'), 'hard_return' => '' ], 2 => [ 'color_id' => '0', 'color2_id' => '0', 'alpha' => '0', 'alpha2' => '0', 'line_width' => '1', 'legend' => '', 'gradheight' => '0', 'graph_type_id' => '9', 'consolidation_function_id' => '2', 'text_format' => __('Min:'), 'hard_return' => '' ], 3 => [ 'color_id' => '0', 'color2_id' => '0', 'alpha' => '0', 'alpha2' => '0', 'line_width' => '1', 'legend' => '', 'gradheight' => '0', 'graph_type_id' => '9', 'consolidation_function_id' => '3', 'text_format' => __('Max:'), 'hard_return' => 'on' ] ]; } $sequence = grv('sequence'); $graph_template_item_id = null; foreach ($items as $item) { // generate a new sequence if needed if (empty($sequence)) { $sequence = get_sequence(0, 'sequence', 'graph_templates_item', 'graph_template_id=' . grv('graph_template_id') . ' AND local_graph_id=0'); } $task_item_changed = true; if (grv('graph_template_item_id') > 0) { $task_item_id = db_fetch_cell_prepared('SELECT task_item_id FROM graph_templates_item WHERE id = ?', [grv('graph_template_item_id')] ); if (gnrv('task_item_id') == gnrv('_task_item_id')) { $task_item_changed = false; } } $save['id'] = grv('graph_template_item_id'); $save['hash'] = get_hash_graph_template(grv('graph_template_item_id'), 'graph_template_item'); $save['graph_template_id'] = grv('graph_template_id'); $save['local_graph_id'] = 0; $save['task_item_id'] = CactiValidator::validateInput(grv('task_item_id'), 'task_item_id', [new Assert\Regex('/^[0-9]+$/')], 3); $save['color_id'] = CactiValidator::validateInput((isset($item['color_id']) ? $item['color_id'] : grv('color_id')), 'color_id', [], 3); $save['color2_id'] = CactiValidator::validateInput((isset($item['color2_id']) ? $item['color2_id'] : grv('color2_id')), 'color2_id', [], 3); // if alpha is disabled, use invisible_alpha instead if (!isrv('alpha')) { srv('alpha', gnrv('invisible_alpha')); } if (!isrv('alpha2')) { srv('alpha2', gnrv('invisible_alpha')); } $save['alpha'] = CactiValidator::validateInput((isset($item['alpha']) ? $item['alpha'] : gnrv('alpha')), 'alpha', [], 3); $save['alpha2'] = CactiValidator::validateInput((isset($item['alpha2']) ? $item['alpha2'] : gnrv('alpha2')), 'alpha2', [], 3); $save['gradheight'] = CactiValidator::validateInput((isset($item['gradheight']) ? $item['gradheight'] : gnrv('gradheight')), 'gradheight', [], 3); $save['graph_type_id'] = CactiValidator::validateInput((isset($item['graph_type_id']) ? $item['graph_type_id'] : gfrv('graph_type_id')), 'graph_type_id', [new Assert\Regex('/^[0-9]+$/')], 3); if (isrv('line_width') || isset($item['line_width'])) { $save['line_width'] = CactiValidator::validateInput((isset($item['line_width']) ? $item['line_width'] : gnrv('line_width')), 'line_width', [new Assert\Regex('/(^[0-9]+[\.,0-9]+$|^[0-9]+$)/')], 3); } else { // make sure to transfer old LINEx style into line_width on save switch ($save['graph_type_id']) { case GRAPH_ITEM_TYPE_LINE1: $save['line_width'] = 1; break; case GRAPH_ITEM_TYPE_LINE2: $save['line_width'] = 2; break; case GRAPH_ITEM_TYPE_LINE3: $save['line_width'] = 3; break; default: $save['line_width'] = 0; } } $save['dashes'] = CactiValidator::validateInput((isrv('dashes') ? gnrv('dashes') : ''), 'dashes', [new Assert\Regex('/^[0-9]+[,0-9]*$/')], 3); $save['dash_offset'] = CactiValidator::validateInput((isrv('dash_offset') ? gnrv('dash_offset') : ''), 'dash_offset', [new Assert\Regex('/^[0-9]+$/')], 3); $save['cdef_id'] = CactiValidator::validateInput(gnrv('cdef_id'), 'cdef_id', [new Assert\Regex('/^[0-9]+$/')], 3); $save['vdef_id'] = CactiValidator::validateInput(gnrv('vdef_id'), 'vdef_id', [new Assert\Regex('/^[0-9]+$/')], 3); $save['shift'] = CactiValidator::validateInput((isrv('shift') ? gnrv('shift') : ''), 'shift', [new Assert\Regex('/^((on)|)$/')], 3); $save['consolidation_function_id'] = CactiValidator::validateInput((isset($item['consolidation_function_id']) ? $item['consolidation_function_id'] : gnrv('consolidation_function_id')), 'consolidation_function_id', [new Assert\Regex('/^[0-9]+$/')], 3); $save['textalign'] = CactiValidator::validateInput((isrv('textalign') ? gnrv('textalign') : ''), 'textalign', [new Assert\Regex('/^[a-z]+$/')], 3); $save['text_format'] = CactiValidator::validateInput((isset($item['text_format']) ? $item['text_format'] : gnrv('text_format')), 'text_format', [], 3); $save['legend'] = CactiValidator::validateInput((isset($item['legend']) ? $item['legend'] : gnrv('legend')), 'legend', [], 3); $save['value'] = CactiValidator::validateInput(gnrv('value'), 'value', [], 3); $save['hard_return'] = CactiValidator::validateInput(((isset($item['hard_return']) ? $item['hard_return'] : (isrv('hard_return') ? gnrv('hard_return') : ''))), 'hard_return', [], 3); $save['gprint_id'] = CactiValidator::validateInput(gnrv('gprint_id'), 'gprint_id', [new Assert\Regex('/^[0-9]+$/')], 3); $save['sequence'] = $sequence; if (!is_error_message()) { // Before we save the item, let's get a look at task_item_id <-> input associations $orig_data_source_graph_inputs = db_fetch_assoc_prepared("SELECT gtin.id, gtin.name, gti.task_item_id FROM graph_template_input AS gtin INNER JOIN graph_template_input_defs AS gtid ON gtin.id = gtid.graph_template_input_id INNER JOIN graph_templates_item AS gti ON gtid.graph_template_item_id = gti.id WHERE gtin.graph_template_id = ? AND gtin.column_name = 'task_item_id' GROUP BY gti.task_item_id", [$save['graph_template_id']]); $orig_data_source_to_input = array_rekey($orig_data_source_graph_inputs, 'task_item_id', 'id'); $graph_template_item_id = sql_save($save, 'graph_templates_item'); if ($graph_template_item_id) { raise_message(1); if (!empty($save['task_item_id'])) { // old item clean-up. Don't delete anything if the item <-> task_item_id association remains the same. if (gnrv('_task_item_id') != gnrv('task_item_id')) { // It changed. Delete any old associations db_execute_prepared('DELETE FROM graph_template_input_defs WHERE graph_template_item_id = ?', [$graph_template_item_id] ); // Input for current data source exists and has changed. Update the association if (isset($orig_data_source_to_input[$save['task_item_id']])) { db_execute_prepared('REPLACE INTO graph_template_input_defs (graph_template_input_id, graph_template_item_id) VALUES (?, ?)', [$orig_data_source_to_input[$save['task_item_id']], $graph_template_item_id] ); } } // an input for the current data source does NOT currently exist, let's create one if (!isset($orig_data_source_to_input[$save['task_item_id']])) { $ds_name = db_fetch_cell_prepared('SELECT data_source_name FROM data_template_rrd WHERE id = ?', [gnrv('task_item_id')] ); db_execute_prepared("REPLACE INTO graph_template_input (hash, graph_template_id, name, column_name) VALUES (?, ?, ?, 'task_item_id')", [get_hash_graph_template(0, 'graph_template_input'), $save['graph_template_id'], "Data Source [$ds_name]"] ); $graph_template_input_id = db_fetch_insert_id(); $graph_items = db_fetch_assoc_prepared('SELECT id FROM graph_templates_item WHERE graph_template_id = ? AND task_item_id = ?', [$save['graph_template_id'], gnrv('task_item_id')] ); if (cacti_sizeof($graph_items)) { foreach ($graph_items as $graph_item) { db_execute_prepared('REPLACE INTO graph_template_input_defs (graph_template_input_id, graph_template_item_id) VALUES (?, ?)', [$graph_template_input_id, $graph_item['id']] ); } } } } push_out_graph_item($graph_template_item_id, $task_item_changed); if (isset($orig_data_source_to_input[gnrv('task_item_id')])) { // make sure all current graphs using this graph input are aware of this change push_out_graph_input($orig_data_source_to_input[gnrv('task_item_id')], $graph_template_item_id, [$graph_template_item_id => $graph_template_item_id]); } } else { raise_message(2); } } $sequence = 0; } if (is_error_message()) { cacti_redirect('graph_templates.php', [ 'action' => 'item_edit', 'graph_template_item_id' => $graph_template_item_id === null ? gnrv('graph_template_item_id') : $graph_template_item_id, 'id' => gnrv('graph_template_id'), ]); } else { db_execute_prepared('UPDATE graph_templates SET last_updated = NOW() WHERE id = ?', [gnrv('graph_template_id')]); cacti_redirect('graph_templates.php', [ 'action' => 'template_edit', 'id' => gnrv('graph_template_id'), ]); } } elseif ((isrv('save_component_input')) && (!is_error_message())) { $graph_input_values = []; $selected_graph_items = []; // ================= input validation ================= gfrv('graph_template_input_id'); gfrv('graph_template_id'); // ==================================================== $save['id'] = gnrv('graph_template_input_id'); $save['hash'] = get_hash_graph_template(gnrv('graph_template_input_id'), 'graph_template_input'); $save['graph_template_id'] = gnrv('graph_template_id'); $save['name'] = CactiValidator::validateInput(gnrv('name'), 'name', [new Assert\NotBlank()], 3); $save['description'] = CactiValidator::validateInput(gnrv('description'), 'description', [], 3); $save['column_name'] = CactiValidator::validateInput(gnrv('column_name'), 'column_name', [], 3); if (!graph_template_input_column_is_allowed($save['column_name'])) { raise_message('column_name_invalid', __('The selected Field Type is not a valid Graph Item field.'), MESSAGE_LEVEL_ERROR); $_SESSION['sess_error_fields']['column_name'] = 'column_name'; } foreach ($_POST as $var => $val) { if (preg_match('/^i_(\d+)$/', $var, $matches)) { input_validate_input_number($matches[1], 'i[1]'); $selected_graph_items[$matches[1]] = intval($matches[1]); } } if (!graph_template_input_relationships_are_valid((int) $save['id'], (int) $save['graph_template_id'], array_values($selected_graph_items))) { cacti_log('ERROR: Graph input save refused a cross-template relationship', false, 'SECURITY'); raise_message('graph_input_relationship_invalid', __('The Graph Item Input relationship is invalid.'), MESSAGE_LEVEL_ERROR); } if (is_error_message() === false) { $transaction_started = db_begin_transaction(); $mutation_failed = !$transaction_started; $graph_template_input_id = $mutation_failed ? false : sql_save($save, 'graph_template_input'); if ($graph_template_input_id) { // list all graph items from the db so we can compare them with the current form $db_selected_graph_item = array_rekey( db_fetch_assoc_prepared('SELECT graph_template_item_id FROM graph_template_input_defs WHERE graph_template_input_id = ?', [$graph_template_input_id]), 'graph_template_item_id', 'graph_template_item_id' ); foreach ($selected_graph_items as $graph_template_item_id) { if (!isset($db_selected_graph_item[$graph_template_item_id])) { $new_members[$graph_template_item_id] = $graph_template_item_id; } } if ((isset($new_members)) && (cacti_sizeof($new_members) > 0)) { foreach ($new_members as $item_id) { push_out_graph_input($graph_template_input_id, $item_id, $new_members); } } $mutation_failed = !db_execute_prepared('DELETE FROM graph_template_input_defs WHERE graph_template_input_id = ?', [$graph_template_input_id]); if (!$mutation_failed && cacti_sizeof($selected_graph_items) > 0) { foreach ($selected_graph_items as $graph_template_item_id) { if (!db_execute_prepared('INSERT INTO graph_template_input_defs (graph_template_input_id, graph_template_item_id) VALUES (?, ?)', [$graph_template_input_id, $graph_template_item_id])) { $mutation_failed = true; break; } } } } else { $mutation_failed = true; } if ($mutation_failed) { if ($transaction_started) { db_rollback_transaction(); } raise_message(2); } else { db_commit_transaction(); raise_message(1); } } if (is_error_message()) { cacti_redirect('graph_templates.php', [ 'action' => 'input_edit', 'graph_template_input_id' => empty($graph_template_input_id) ? gnrv('graph_template_input_id') : $graph_template_input_id, 'graph_template_id' => gnrv('graph_template_id'), ]); } else { db_execute_prepared('UPDATE graph_templates SET last_updated = NOW() WHERE id = ?', [gnrv('graph_template_id')]); cacti_redirect('graph_templates.php', [ 'action' => 'template_edit', 'id' => gnrv('graph_template_id'), ]); } } cacti_redirect('graph_templates.php', [ 'action' => 'template_edit', 'id' => empty($graph_template_id) ? gnrv('graph_template_id') : $graph_template_id, ]); } function item_movedown() : void { // ================= input validation ================= gfrv('id'); gfrv('graph_template_id'); // ==================================================== global $graph_item_types; $arr = get_graph_group(grv('id')); $next_id = get_graph_parent(grv('id'), 'next'); $graph_type = db_fetch_cell_prepared('SELECT graph_type_id FROM graph_templates_item WHERE id = ?', [grv('id')] ); $text_type = $graph_item_types[$graph_type]; if (!empty($next_id) && isset($arr[grv('id')])) { move_graph_group(grv('id'), $arr, $next_id, 'next'); } elseif (!preg_match('/(AREA|STACK|LINE)/', $text_type)) { // this is so we know the "other" graph item to propagate the changes to $next_item = get_item('graph_templates_item', 'sequence', grv('id'), 'graph_template_id=' . grv('graph_template_id') . ' AND local_graph_id=0', 'next'); move_item_down('graph_templates_item', grv('id'), 'graph_template_id=' . grv('graph_template_id') . ' AND local_graph_id=0'); } if (!ierv('graph_template_id')) { resequence_graphs_simple(grv('graph_template_id')); } } function item_moveup() : void { // ================= input validation ================= gfrv('id'); gfrv('graph_template_id'); // ==================================================== global $graph_item_types; $arr = get_graph_group(grv('id')); $next_id = get_graph_parent(grv('id'), 'previous'); $graph_type = db_fetch_cell_prepared('SELECT graph_type_id FROM graph_templates_item WHERE id = ?', [grv('id')] ); $text_type = $graph_item_types[$graph_type]; if (!empty($next_id) && isset($arr[grv('id')])) { move_graph_group(grv('id'), $arr, $next_id, 'previous'); } elseif (!preg_match('/(AREA|STACK|LINE)/', $text_type)) { // this is so we know the "other" graph item to propagate the changes to $last_item = get_item('graph_templates_item', 'sequence', grv('id'), 'graph_template_id=' . grv('graph_template_id') . ' AND local_graph_id=0', 'previous'); move_item_up('graph_templates_item', grv('id'), 'graph_template_id=' . grv('graph_template_id') . ' AND local_graph_id=0'); } if (!ierv('graph_template_id')) { resequence_graphs_simple(grv('graph_template_id')); } } function item_remove() : void { // ================= input validation ================= gfrv('id'); gfrv('graph_template_id'); // ==================================================== db_execute_prepared('DELETE FROM graph_templates_item WHERE id = ?', [grv('id')]); db_execute_prepared('DELETE FROM graph_templates_item WHERE local_graph_template_item_id = ?', [grv('id')]); // delete the graph item input if it is empty $graph_item_inputs = db_fetch_assoc_prepared('SELECT graph_template_input.id FROM (graph_template_input, graph_template_input_defs) WHERE graph_template_input.id = graph_template_input_defs.graph_template_input_id AND graph_template_input.graph_template_id = ? AND graph_template_input_defs.graph_template_item_id = ? GROUP BY graph_template_input.id', [grv('graph_template_id'), grv('id')]); if (cacti_sizeof($graph_item_inputs) > 0) { foreach ($graph_item_inputs as $graph_item_input) { if (cacti_sizeof(db_fetch_assoc_prepared('SELECT graph_template_input_id FROM graph_template_input_defs WHERE graph_template_input_id = ?', [$graph_item_input['id']])) == 1) { db_execute_prepared('DELETE FROM graph_template_input WHERE id = ?', [$graph_item_input['id']]); } } } db_execute_prepared('DELETE FROM graph_template_input_defs WHERE graph_template_item_id = ?', [grv('id')]); } function item_edit() : void { global $struct_graph_item, $graph_item_types, $consolidation_functions; // ================= input validation ================= gfrv('id'); gfrv('graph_template_id'); gfrv('data_template_id'); // ==================================================== // ================= input validation and session storage ================= $filters = [ 'data_template_id' => [ 'filter' => FILTER_VALIDATE_INT, 'pageset' => true, 'default' => '0' ], ]; validate_store_request_vars($filters, 'sess_gti_' . gfrv('graph_template_id')); // ================= input validation ================= if (grv('graph_template_id') > 0 || isrv('id')) { $sql_where = ''; $sql_params = []; if (grv('id') > 0) { $sql_where .= ' AND gti.id = ?'; $sql_params[] = grv('id'); } if (grv('graph_template_id') > 0) { $sql_where .= ' AND gti.graph_template_id = ?'; $sql_params[] = grv('graph_template_id'); } $data_templates = array_rekey( db_fetch_assoc_prepared("SELECT DISTINCT dtr.data_template_id FROM data_template_rrd AS dtr INNER JOIN graph_templates_item AS gti ON dtr.id = gti.task_item_id WHERE dtr.local_data_id = 0 $sql_where ORDER BY dtr.data_template_id", $sql_params ), 'data_template_id', 'data_template_id' ); if (cacti_sizeof($data_templates)) { if (!isset($data_templates[grv('data_template_id')])) { foreach ($data_templates as $dt) { srv('data_template_id', $dt); break; } } } } form_start('graph_templates.php', 'graph_items'); $header_label = __esc('Graph Template Items [edit graph: %s]', db_fetch_cell_prepared('SELECT name FROM graph_templates WHERE id = ?', [grv('graph_template_id')])); html_start_box($header_label, '100%', true, 3, 'center', ''); if (!ierv('id')) { $template_item = db_fetch_row_prepared('SELECT * FROM graph_templates_item WHERE id = ?', [grv('id')] ); } // by default, select the LAST DS chosen to make everyone's lives easier if (!ierv('graph_template_id')) { $default = db_fetch_row_prepared('SELECT task_item_id FROM graph_templates_item WHERE graph_template_id = ? AND local_graph_id = 0 ORDER BY sequence DESC', [grv('graph_template_id')] ); if (cacti_sizeof($default) > 0) { $struct_graph_item['task_item_id']['default'] = $default['task_item_id']; } else { $struct_graph_item['task_item_id']['default'] = 0; } } if (isrv('data_template_id')) { $sql_where = ' AND dtr.data_template_id = ' . gfrv('data_template_id'); } else { $sql_where = ''; } $data_template_helper = [ 'data_template_id' => [ 'friendly_name' => __('Data Template Filter'), 'method' => 'drop_sql', 'sql' => 'SELECT id, name FROM data_template ORDER BY name', 'default' => '0', 'value' => (isrv('data_template_id') ? gfrv('data_template_id') : '0'), 'none_value' => __('Any'), 'description' => __('This filter will limit the Data Sources visible in the Data Source dropdown.') ] ]; // modifications to the default graph items array $struct_graph_item['task_item_id']['sql'] = "SELECT dtr.id, CONCAT_WS('', dt.name,' - ',' (', dtr.data_source_name,')') AS name FROM data_template_rrd AS dtr INNER JOIN data_template AS dt ON dtr.data_template_id = dt.id WHERE dtr.local_data_id = 0 $sql_where ORDER BY dt.name, dtr.data_source_name"; $mystruct_graph_item = array_merge($data_template_helper, $struct_graph_item); $form_array = []; foreach ($mystruct_graph_item as $field_name => $field_array) { $form_array += [$field_name => $mystruct_graph_item[$field_name]]; if ($field_name != 'data_template_id') { $form_array[$field_name]['value'] = (isset($template_item) ? $template_item[$field_name] : ''); $form_array[$field_name]['form_id'] = (isset($template_item) ? $template_item['id'] : '0'); } else { $form_array[$field_name]['value'] = grv('data_template_id'); $form_array[$field_name]['form_id'] = (isset($template_item) ? $template_item['id'] : '0'); } } if (isset($template_item) && cacti_sizeof($template_item) && $template_item['legend'] == '') { switch ($template_item['graph_type_id']) { case 7: case 8: case 2: case 4: case 5: case 6: case 20: $data_source = db_fetch_cell_prepared('SELECT data_source_name FROM data_template_rrd WHERE id = ? AND local_data_id = 0', [$template_item['task_item_id']]); if ($data_source != '') { switch($template_item['consolidation_function_id']) { case 1: $data_source .= ' (AVG)'; break; case 2: $data_source .= ' (MIN)'; break; case 3: $data_source .= ' (MAX)'; break; case 4: $data_source .= ' (LAST)'; break; } $form_array['legend']['value'] = $data_source; } } } draw_edit_form( [ 'config' => ['no_form_tag' => true], 'fields' => $form_array ] ); html_end_box(true, true); form_hidden_box('graph_template_item_id', (isset($template_item) ? $template_item['id'] : '0'), ''); form_hidden_box('graph_template_id', grv('graph_template_id'), '0'); form_hidden_box('_graph_type_id', (isset($template_item) ? $template_item['graph_type_id'] : '0'), ''); form_hidden_box('_task_item_id', (isset($template_item) ? $template_item['task_item_id'] : '0'), ''); form_hidden_box('save_component_item', '1', ''); form_hidden_box('invisible_alpha', $form_array['alpha']['value'], 'FF'); form_hidden_box('rrdtool_version', get_rrdtool_version(), ''); form_save_button('graph_templates.php?action=template_edit&id=' . grv('graph_template_id')); ?> ['regexp' => '/^([a-zA-Z0-9_]+)$/']]); // ==================================================== // if we are to save this form, instead of display it if (isrv('selected_items')) { $selected_items = sanitize_unserialize_selected_items(gnrv('selected_items')); if ($selected_items != false) { if (grv('drp_action') == '1') { // delete db_execute('DELETE FROM graph_templates WHERE ' . array_to_sql_or($selected_items, 'id')); $snmp_graph_ids = array_rekey( db_fetch_assoc('SELECT id FROM snmp_query_graph WHERE ' . array_to_sql_or($selected_items, 'graph_template_id')), 'id', 'id' ); if (cacti_sizeof($snmp_graph_ids)) { db_execute('DELETE FROM snmp_query_graph WHERE ' . array_to_sql_or($selected_items, 'graph_template_id')); db_execute('DELETE FROM snmp_query_graph_rrd WHERE snmp_query_graph_id IN (' . implode(', ', $snmp_graph_ids) . ')'); db_execute('DELETE FROM snmp_query_graph_rrd_sv WHERE snmp_query_graph_id IN (' . implode(', ', $snmp_graph_ids) . ')'); db_execute('DELETE FROM snmp_query_graph_sv WHERE snmp_query_graph_id IN (' . implode(', ', $snmp_graph_ids) . ')'); } $graph_template_input = db_fetch_assoc('SELECT id FROM graph_template_input WHERE ' . array_to_sql_or($selected_items, 'graph_template_id')); if (cacti_sizeof($graph_template_input) > 0) { foreach ($graph_template_input as $item) { db_execute_prepared('DELETE FROM graph_template_input_defs WHERE graph_template_input_id = ?', [$item['id']]); } } db_execute('DELETE FROM graph_template_input WHERE ' . array_to_sql_or($selected_items, 'graph_template_id')); db_execute('DELETE FROM graph_templates_graph WHERE ' . array_to_sql_or($selected_items, 'graph_template_id') . ' AND local_graph_id=0'); db_execute('DELETE FROM graph_templates_item WHERE ' . array_to_sql_or($selected_items, 'graph_template_id') . ' AND local_graph_id=0'); db_execute('DELETE FROM host_template_graph WHERE ' . array_to_sql_or($selected_items, 'graph_template_id')); // 'undo' any graph that is currently using this template db_execute('UPDATE graph_templates_graph SET local_graph_template_graph_id=0, graph_template_id=0 WHERE ' . array_to_sql_or($selected_items, 'graph_template_id')); db_execute('UPDATE graph_templates_item SET local_graph_template_item_id=0, graph_template_id=0 WHERE ' . array_to_sql_or($selected_items, 'graph_template_id')); db_execute('UPDATE graph_local SET graph_template_id=0 WHERE ' . array_to_sql_or($selected_items, 'graph_template_id')); } elseif (grv('drp_action') == '2') { // duplicate for ($i = 0; ($i < cacti_count($selected_items)); $i++) { api_duplicate_graph(0, $selected_items[$i], gnrv('title_format')); } } elseif (grv('drp_action') == '3') { // change settings gfrv('graph_width'); gfrv('graph_height'); gfrv('image_format_id'); foreach ($selected_items as $graph_template_id) { $variables = ['height', 'width', 'image_format_id']; foreach ($variables as $v) { if (isrv($v) && isrv("t_$v")) { db_execute_prepared("UPDATE graph_templates_graph SET $v = ? WHERE graph_template_id = ?", [ gnrv($v), $graph_template_id ] ); } } if (isrv('class') && isrv('t_class')) { db_execute_prepared('UPDATE graph_templates SET class = ? WHERE id = ?', [ gnrv('class'), $graph_template_id ] ); } } } elseif (grv('drp_action') == '4') { // retemplate for ($i = 0; ($i < cacti_count($selected_items)); $i++) { retemplate_graphs($selected_items[$i]); $graph_template_name = db_fetch_cell_prepared('SELECT name FROM graph_templates WHERE id = ?', [$selected_items[$i]]); if (isset($_SESSION['sess_gt_repairs']) && $_SESSION['sess_gt_repairs'] > 0) { raise_message('gt_repair' . $selected_items[$i], __esc('Sync of Graph Template \'%s\' Resulted in %s Repairs!', $graph_template_name, $_SESSION['sess_gt_repairs']), MESSAGE_LEVEL_WARN); } else { raise_message('gt_repair' . $selected_items[$i], __esc('Sync of Graph Template \'%s\' Resulted in no Repairs.', $graph_template_name), MESSAGE_LEVEL_INFO); } } } elseif (grv('drp_action') == '5') { // resequence graphs with sequences off for ($i = 0; ($i < cacti_count($selected_items)); $i++) { retemplate_graphs($selected_items[$i], 0, true); $graph_template_name = db_fetch_cell_prepared('SELECT name FROM graph_templates WHERE id = ?', [$selected_items[$i]]); if (isset($_SESSION['sess_gt_repairs']) && $_SESSION['sess_gt_repairs'] > 0) { raise_message('gt_repair' . $selected_items[$i], __esc('Sync of Graph Template \'%s\' Resulted in %s Repairs!', $graph_template_name, $_SESSION['sess_gt_repairs']), MESSAGE_LEVEL_WARN); } else { raise_message('gt_repair' . $selected_items[$i], __esc('Sync of Graph Template \'%s\' Resulted in no Repairs.', $graph_template_name), MESSAGE_LEVEL_INFO); } } } } header('Location: graph_templates.php'); exit; } else { $ilist = ''; $iarray = []; // loop through each of the graphs selected on the previous page and get more info about them foreach ($_POST as $var => $val) { if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) { // ================= input validation ================= input_validate_input_number($matches[1], 'chk[1]'); // ==================================================== $ilist .= '
  • ' . htmle(db_fetch_cell_prepared('SELECT name FROM graph_templates WHERE id = ?', [$matches[1]])) . '
  • '; $iarray[] = $matches[1]; } } $form_data = [ 'general' => [ 'page' => 'graph_templates.php', 'actions' => $actions, 'optvar' => 'drp_action', 'item_array' => $iarray, 'item_list' => $ilist ], 'options' => [ 1 => [ 'smessage' => __('Click \'Continue\' to Delete the following Graph Template.'), 'pmessage' => __('Click \'Continue\' to Delete following Graph Templates.'), 'scont' => __('Delete Graph Template'), 'pcont' => __('Delete Graph Templates') ], 2 => [ 'smessage' => __('Click \'Continue\' to Duplicate the following Graph Template.'), 'pmessage' => __('Click \'Continue\' to Duplicate following Graph Templates.'), 'scont' => __('Duplicate Graph Template'), 'pcont' => __('Duplicate Graph Templates'), 'extra' => [ 'title_format' => [ 'method' => 'textbox', 'title' => __('Title Format'), 'default' => ' (1)', 'width' => 45 ] ] ], 3 => [ 'smessage' => __('Click \'Continue\' to Resize the following Graph Template.'), 'pmessage' => __('Click \'Continue\' to Resize following Graph Templates.'), 'scont' => __('Resize Graph Template'), 'pcont' => __('Resize Graph Templates'), 'extra' => [ 'class' => [ 'method' => 'drop_array', 'title' => __('Template Class'), 'default' => 'unspecified', 'array' => $graph_template_classes, 'confirm' => true ], 'height' => [ 'method' => 'textbox', 'title' => __('Graph Height'), 'default' => read_config_option('default_graph_height'), 'width' => 5, 'size' => 5, 'confirm' => true ], 'width' => [ 'method' => 'textbox', 'title' => __('Graph Width'), 'default' => read_config_option('default_graph_width'), 'width' => 5, 'size' => 5, 'confirm' => true ], 'image_format_id' => [ 'method' => 'drop_array', 'title' => __('Image Format'), 'array' => $image_types, 'default' => read_config_option('default_image_format'), 'confirm' => true ] ] ], 4 => [ 'smessage' => __('Click \'Continue\' to perform a Full Synchronization between your Graphs and the chosen Graph Template. If you simply have a situation where the Graph Items don\'t match the Graph Template, try the Quick Sync Graphs option first as it will take much less time. This function is important if you have Graphs that exist with multiple versions of a Graph Template and wish to make them all common in appearance.'), 'pmessage' => __('Click \'Continue\' to perform a Full Synchronization between your Graphs and the chosen Graph Templates. If you simply have a situation where the Graph Items don\'t match the Graph Template, try the Quick Sync Graphs option first as it will take much less time. This function is important if you have Graphs that exist with multiple versions of a Graph Template and wish to make them all common in appearance.'), 'scont' => __('Synchronize Graphs to Graph Template'), 'pcont' => __('Synchronize Graphs to Graph Templates'), ], 5 => [ 'smessage' => __('Click \'Continue\' to perform a Quick Synchronization of your Graphs for the following Graph Template. Use this option if your Graphs have Graph Items that do not match your Graph Template. If this option does not work, use the Full Sync Graphs option, which will take more time to complete.'), 'pmessage' => __('Click \'Continue\' to perform a Quick Synchronization of your Graphs for the following Graph Templates. Use this option if your Graphs have Graph Items that do not match your Graph Template. If this option does not work, use the Full Sync Graphs option, which will take more time to complete.'), 'scont' => __('Synchronize Graphs to Graph Template'), 'pcont' => __('Synchronize Graphs to Graph Templates'), ] ] ]; form_continue_confirmation($form_data); } } function item() : void { global $consolidation_functions, $graph_item_types; // ================= input validation ================= gfrv('id'); // ==================================================== if (ierv('id')) { $template_item_list = []; $header_label = 'Graph Template Items [new]'; } else { $template_item_list = db_fetch_assoc_prepared("SELECT gti.id, gti.sequence, gti.text_format, gti.alpha, gti.alpha2, gti.value, gti.hard_return, gti.graph_type_id, gti.consolidation_function_id, gti.textalign, gti.legend, CONCAT(IFNULL(dt.name, ''), ' (', dtr.data_source_name, ')') AS data_source_name, cdef.name AS cdef_name, vdef.name as vdef_name, colors.hex, colors2.hex AS hex2, gtgp.name as gprint_name FROM graph_templates_item AS gti LEFT JOIN data_template_rrd AS dtr ON gti.task_item_id=dtr.id LEFT JOIN data_local AS dl ON dtr.local_data_id=dl.id LEFT JOIN data_template AS dt ON dt.id=dtr.data_template_id LEFT JOIN data_template_data AS dtd ON dl.id=dtd.local_data_id LEFT JOIN graph_templates_gprint as gtgp ON gtgp.id=gti.gprint_id LEFT JOIN cdef ON cdef_id=cdef.id LEFT JOIN vdef ON vdef_id=vdef.id LEFT JOIN colors ON color_id = colors.id LEFT JOIN colors AS colors2 ON color2_id = colors2.id WHERE gti.graph_template_id = ? AND gti.local_graph_id = 0 ORDER BY gti.sequence", [grv('id')]); $header_label = __esc('Graph Template Items [edit: %s]', db_fetch_cell_prepared('SELECT name FROM graph_templates WHERE id = ?', [grv('id')])); } html_start_box($header_label, '100%', false, 3, 'center', 'graph_templates.php?action=item_edit&graph_template_id=' . grv('id')); draw_graph_items_list($template_item_list, 'graph_templates.php', 'graph_template_id=' . grv('id'), false); html_end_box(); html_start_box(__('Graph Item Inputs'), '100%', false, 3, 'center', 'graph_templates.php?action=input_edit&graph_template_id=' . grv('id')); print ""; DrawMatrixHeaderItem(__('Name'),'',2); print ''; $database = get_mysql_info(); $sql_order = 'ORDER BY name'; if ($database['database'] == 'MariaDB') { if (cacti_version_compare($database['version'], '10.7', '>')) { $sql_order = 'ORDER BY NATURAL_SORT_KEY(name)'; } } $template_item_list = db_fetch_assoc_prepared("SELECT id, name FROM graph_template_input WHERE graph_template_id = ? $sql_order", [grv('id')]); $i = 0; if (cacti_sizeof($template_item_list) > 0) { foreach ($template_item_list as $item) { form_alternate_row('', true); ?> '> ' href=''> " . __('No Inputs') . ''; } ?> ['no_form_tag' => true], 'fields' => inject_form_variables($fields_graph_template_template_edit, (isset($template) ? $template : []), (isset($template_graph) ? $template_graph : [])) ] ); html_end_box(true, true); html_start_box(__('Graph Template Options'), '100%', true, 3, 'center', ''); $form_array = []; foreach ($struct_graph as $field_name => $field_array) { $form_array += [$field_name => $struct_graph[$field_name]]; if ($form_array[$field_name]['method'] != 'spacer') { $form_array[$field_name]['value'] = (isset($template_graph[$field_name]) ? $template_graph[$field_name] : ''); } $form_array[$field_name]['form_id'] = (isset($template_graph['id']) ? $template_graph['id'] : '0'); if ($form_array[$field_name]['method'] != 'spacer') { $form_array[$field_name]['sub_checkbox'] = [ 'name' => 't_' . $field_name, 'friendly_name' => __esc('Check this checkbox if you wish to allow the user to override the value on the right during Graph creation.'), 'value' => (isset($template_graph['t_' . $field_name]) ? $template_graph['t_' . $field_name] : '') ]; } } draw_edit_form( [ 'config' => ['no_form_tag' => true], 'fields' => $form_array ] ); form_hidden_box('rrdtool_version', get_rrdtool_version(), ''); html_end_box(true, true); form_save_button('graph_templates.php', 'return'); // Now we need some javascript to make it dynamic ?> '0') { $sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . ' gti.vdef_id = ?'; $sql_params[] = grv('vdef_id'); } if (grv('cdef_id') > '0') { $sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . ' gti.cdef_id = ?'; $sql_params[] = grv('cdef_id'); } if (grv('class') != '-1') { $sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . ' gt.class = ?'; $sql_params[] = grv('class'); } if (grv('has_graphs') == 'true') { $sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . ' gt.graphs > 0'; } $total_rows = db_fetch_cell_prepared("SELECT COUNT(DISTINCT gt.id) FROM graph_templates AS gt LEFT JOIN graph_templates_item AS gti ON gti.graph_template_id = gt.id AND gti.local_graph_id = 0 $sql_where", $sql_params); $cacti_version = CACTI_VERSION; $sql_order = get_order_string(); $sql_limit = ' LIMIT ' . ($rows * (grv('page') - 1)) . ',' . $rows; $template_list = db_fetch_assoc_prepared("SELECT DISTINCT gt.id, gt.name, gt.graphs, IF(gt.version = '', '$cacti_version', gt.version) AS version, IF(gt.class = '', 'unassigned', gt.class) AS class, graph_items, last_updated, CONCAT(gtg.height, 'x', gtg.width) AS size, gtg.vertical_label, gtg.image_format_id FROM graph_templates AS gt INNER JOIN graph_templates_graph AS gtg ON gtg.graph_template_id = gt.id AND gtg.local_graph_id = 0 LEFT JOIN graph_templates_item AS gti ON gti.graph_template_id = gt.id AND gti.local_graph_id = 0 LEFT JOIN ( SELECT graph_template_id, COUNT(*) AS graph_items FROM graph_templates_item WHERE local_graph_id = 0 GROUP BY graph_template_id ) AS items ON gt.id = items.graph_template_id $sql_where $sql_order $sql_limit", $sql_params); $display_text = [ 'name' => [ 'display' => __('Graph Template Name'), 'align' => 'left', 'sort' => 'ASC', 'tip' => __('The name of this Graph Template.') ], 'gt.id' => [ 'display' => __('ID'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The internal ID for this Graph Template. Useful when performing automation or debugging.') ], 'class' => [ 'display' => __('Class'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The Class of this Graph Template') ], 'version' => [ 'display' => __('Version'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The Version of this Graph Template') ], 'nosort3' => [ 'display' => __('Deletable'), 'align' => 'right', 'tip' => __('Graph Templates that are in use cannot be Deleted. In use is defined as being referenced by a Graph.') ], 'graph_items' => [ 'display' => __('Graph Items'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The number of Graph Items in this Graph Template.') ], 'graphs' => [ 'display' => __('Graphs Using'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The number of Graphs using this Graph Template.') ], 'image_format_id' => [ 'display' => __('Image Format'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The default image format for the resulting Graphs.') ], 'size' => [ 'display' => __('Size'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The default size of the resulting Graphs.') ], 'vertical_label' => [ 'display' => __('Vertical Label'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The vertical label for the resulting Graphs.') ], 'last_updated' => [ 'display' => __('Last Updated'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The last time this Template was updated.') ] ]; $nav = html_nav_bar('graph_templates.php?filter=' . rawurlencode(grv('filter')), MAX_DISPLAY_PAGES, (int) grv('page'), $rows, $total_rows, cacti_sizeof($display_text) + 1, __('Graph Templates'), 'page', 'main'); form_start('graph_templates.php', 'chk'); print $nav; html_start_box('', '100%', false, 3, 'center', ''); html_header_sort_checkbox($display_text, grv('sort_column'), grv('sort_direction'), false); $i = 0; if (cacti_sizeof($template_list)) { foreach ($template_list as $template) { if ($template['graphs'] > 0) { $disabled = true; } else { $disabled = false; } form_alternate_row('line' . $template['id'], true, $disabled); form_selectable_cell(filter_value($template['name'], grv('filter'), 'graph_templates.php?action=template_edit&id=' . $template['id']), $template['id']); form_selectable_cell($template['id'], $template['id'], '', 'right'); form_selectable_cell($graph_template_classes[$template['class']], $template['id'], '', 'right'); form_selectable_ecell($template['version'], $template['id'], '', 'right'); form_selectable_cell($disabled ? __('No') : __('Yes'), $template['id'], '', 'right'); form_selectable_cell(number_format_i18n($template['graph_items'], -1), $template['id'], '', 'right'); form_selectable_cell(number_format_i18n($template['graphs'], -1), $template['id'], '', 'right'); form_selectable_cell($image_types[$template['image_format_id']], $template['id'], '', 'right'); form_selectable_ecell($template['size'], $template['id'], '', 'right'); form_selectable_ecell($template['vertical_label'], $template['id'], '', 'right'); form_selectable_ecell($template['last_updated'], $template['id'], '', 'right'); form_checkbox_cell($template['name'], $template['id'], $disabled); form_end_row(); } } else { print "" . __('No Graph Templates Found') . "\n"; } html_end_box(false); if (cacti_sizeof($template_list)) { print $nav; } // draw the dropdown containing a list of available actions for this form draw_actions_dropdown($actions); form_end(); } function input_remove() : void { // ================= input validation ================= gfrv('id'); gfrv('graph_template_id'); // ==================================================== if (!graph_template_input_relationships_are_valid((int) grv('id'), (int) grv('graph_template_id'), [])) { cacti_log('ERROR: Graph input delete refused a cross-template relationship', false, 'SECURITY'); return; } if (db_begin_transaction()) { $deleted_defs = db_execute_prepared('DELETE FROM graph_template_input_defs WHERE graph_template_input_id = ?', [grv('id')]); $deleted_input = $deleted_defs && db_execute_prepared('DELETE FROM graph_template_input WHERE id = ? AND graph_template_id = ?', [grv('id'), grv('graph_template_id')]); if ($deleted_input) { db_commit_transaction(); } else { db_rollback_transaction(); } } } function input_edit() : void { global $consolidation_functions, $graph_item_types, $struct_graph_item, $fields_graph_template_input_edit; // Remove filter item unset($struct_graph_item['data_template_id']); // ================= input validation ================= gfrv('id'); gfrv('graph_template_id'); // ==================================================== $header_label = __esc('Graph Item Inputs [edit graph: %s]', db_fetch_cell_prepared('SELECT name FROM graph_templates WHERE id = ?', [grv('graph_template_id')])); // get a list of all graph item field names and populate an array for user display foreach ($struct_graph_item as $field_name => $field_array) { if ($field_array['method'] != 'view') { $graph_template_items[$field_name] = $field_array['friendly_name']; } } if (!ierv('id')) { $graph_template_input = db_fetch_row_prepared('SELECT * FROM graph_template_input WHERE id = ?', [grv('id')]); } form_start('graph_templates.php'); html_start_box($header_label, '100%', true, 3, 'center', ''); draw_edit_form( [ 'config' => ['no_form_tag' => true], 'fields' => inject_form_variables($fields_graph_template_input_edit, (isset($graph_template_input) ? $graph_template_input : []), (isset($graph_template_items) ? $graph_template_items : []), $_REQUEST) ] ); if (!isrv('id')) { srv('id', 0); } html_end_box(true, true); $item_list = db_fetch_assoc_prepared("SELECT CONCAT_WS(' - ', dtd.name, dtr.data_source_name) AS data_source_name, gti.text_format, gti.id AS graph_templates_item_id, gti.graph_type_id, gti.consolidation_function_id, gtid.graph_template_input_id FROM graph_templates_item AS gti LEFT JOIN graph_template_input_defs AS gtid ON gtid.graph_template_item_id = gti.id AND gtid.graph_template_input_id = ? LEFT JOIN data_template_rrd AS dtr ON gti.task_item_id = dtr.id LEFT JOIN data_local AS dl ON dtr.local_data_id = dl.id LEFT JOIN data_template_data AS dtd ON dl.id = dtd.local_data_id WHERE gti.local_graph_id = 0 AND gti.graph_template_id = ? ORDER BY gti.sequence", [grv('id'), grv('graph_template_id')]); html_start_box(__('Associated Graph Items'), '100%', false, 3, 'center', ''); $i = 0; $any_selected_item = ''; if (cacti_sizeof($item_list)) { foreach ($item_list as $item) { form_alternate_row(); if ($item['graph_template_input_id'] == '') { $old_value = ''; } else { $old_value = 'on'; $any_selected_item = $item['graph_templates_item_id']; } if ($graph_item_types[$item['graph_type_id']] == 'GPRINT') { $start_bold = ''; $end_bold = ''; } else { $start_bold = ''; $end_bold = ''; } print ''; $name = $start_bold . __esc('Item #%s', $i + 1) . ': ' . htmle($graph_item_types[$item['graph_type_id']]) . ' (' . htmle($consolidation_functions[$item['consolidation_function_id']]) . ')' . $end_bold; form_checkbox('i_' . $item['graph_templates_item_id'], $old_value, '', '', '', grv('graph_template_id')); print "'; print ''; $i++; form_end_row(); } } else { print '' . __('No Items') . ''; } form_hidden_box('any_selected_item', $any_selected_item, ''); html_end_box(true, true); form_save_button('graph_templates.php?action=template_edit&id=' . grv('graph_template_id')); } function create_graph_templates_filter() : array { global $item_rows, $graph_template_classes; $all = ['-1' => __('All')]; $any = ['-1' => __('Any')]; $none = ['0' => __('None')]; if (isrv('has_graphs')) { $value = gnrv('has_graphs'); } else { $value = read_config_option('default_has') == 'on' ? 'true' : 'false'; } $graph_template_classes = $all + $graph_template_classes; if ($value == 'false') { $cdefs = array_rekey( db_fetch_assoc('SELECT DISTINCT c.id, c.name FROM cdef AS c INNER JOIN (SELECT DISTINCT cdef_id FROM graph_templates_item WHERE cdef_id > 0 AND local_graph_id = 0) AS gti ON c.id = gti.cdef_id ORDER BY name'), 'id', 'name' ); } else { $cdefs = array_rekey( db_fetch_assoc('SELECT DISTINCT c.id, c.name FROM cdef AS c INNER JOIN (SELECT DISTINCT cdef_id FROM graph_templates_item WHERE cdef_id > 0 AND local_graph_id > 0) AS gti ON c.id = gti.cdef_id ORDER BY name'), 'id', 'name' ); } $cdefs = $all + $cdefs; if ($value == 'false') { $vdefs = array_rekey( db_fetch_assoc('SELECT DISTINCT v.id, v.name FROM vdef AS v INNER JOIN (SELECT DISTINCT vdef_id FROM graph_templates_item WHERE vdef_id > 0 AND local_graph_id = 0) AS gti ON gti.vdef_id = v.id ORDER BY name'), 'id', 'name' ); } else { $vdefs = array_rekey( db_fetch_assoc('SELECT DISTINCT v.id, v.name FROM vdef AS v INNER JOIN (SELECT DISTINCT vdef_id FROM graph_templates_item WHERE vdef_id > 0 AND local_graph_id > 0) AS gti ON gti.vdef_id = v.id ORDER BY name'), 'id', 'name' ); } $vdefs = $all + $vdefs; return [ 'rows' => [ [ 'class' => [ 'method' => 'drop_array', 'friendly_name' => __('Class'), 'filter' => FILTER_CALLBACK, 'filter_options' => ['options' => 'sanitize_search_string'], 'default' => '-1', 'pageset' => true, 'array' => $graph_template_classes, 'value' => '-1' ], 'cdef_id' => [ 'method' => 'drop_array', 'friendly_name' => __('CDEFs'), 'filter' => FILTER_VALIDATE_INT, 'default' => '-1', 'pageset' => true, 'array' => $cdefs, 'value' => '-1' ], 'vdef_id' => [ 'method' => 'drop_array', 'friendly_name' => __('VDEFs'), 'filter' => FILTER_VALIDATE_INT, 'default' => '-1', 'pageset' => true, 'array' => $vdefs, 'value' => '-1' ], 'has_graphs' => [ 'method' => 'filter_checkbox', 'friendly_name' => __('Has Graphs'), 'filter' => FILTER_VALIDATE_REGEXP, 'filter_options' => ['options' => ['regexp' => '(true|false)']], 'default' => '', 'pageset' => true, 'value' => $value ] ], [ 'filter' => [ 'method' => 'textbox', 'friendly_name' => __('Search'), 'filter' => FILTER_CALLBACK, 'filter_options' => ['options' => 'sanitize_search_string'], 'placeholder' => __('Enter a search term'), 'size' => '30', 'default' => '', 'pageset' => true, 'max_length' => '120', 'value' => '' ], 'rows' => [ 'method' => 'drop_array', 'friendly_name' => __('Graph Templates'), 'filter' => FILTER_VALIDATE_INT, 'default' => '-1', 'pageset' => true, 'array' => $item_rows, 'value' => '-1' ] ] ], 'buttons' => [ 'go' => [ 'method' => 'submit', 'display' => __('Go'), 'title' => __('Apply filter to table'), ], 'clear' => [ 'method' => 'button', 'display' => __('Clear'), 'title' => __('Reset filter to default values'), ] ], 'sort' => [ 'sort_column' => 'name', 'sort_direction' => 'ASC' ] ]; } function draw_graph_templates_filter(bool $render = false) : void { $filters = create_graph_templates_filter(); // create the page filter $pageFilter = new CactiTableFilter(__('Graph Templates'), 'graph_templates.php', 'form_graphs', 'sess_gt', 'graph_templates.php?action=template_edit'); $pageFilter->rows_label = __('Graph Templates'); $pageFilter->set_filter_array($filters); if ($render) { $pageFilter->render(); } else { $pageFilter->sanitize(); } }