1<?php
2/*
3 +-------------------------------------------------------------------------+
4 | Copyright (C) 2004-2021 The Cacti Group                                 |
5 |                                                                         |
6 | This program is free software; you can redistribute it and/or           |
7 | modify it under the terms of the GNU General Public License             |
8 | as published by the Free Software Foundation; either version 2          |
9 | of the License, or (at your option) any later version.                  |
10 |                                                                         |
11 | This program is distributed in the hope that it will be useful,         |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
14 | GNU General Public License for more details.                            |
15 +-------------------------------------------------------------------------+
16 | Cacti: The Complete RRDtool-based Graphing Solution                     |
17 +-------------------------------------------------------------------------+
18 | This code is designed, written, and maintained by the Cacti Group. See  |
19 | about.php and/or the AUTHORS file for specific developer information.   |
20 +-------------------------------------------------------------------------+
21 | http://www.cacti.net/                                                   |
22 +-------------------------------------------------------------------------+
23*/
24
25include('./include/auth.php');
26include_once('./lib/api_aggregate.php');
27include_once('./lib/api_automation.php');
28include_once('./lib/api_data_source.php');
29include_once('./lib/api_graph.php');
30include_once('./lib/api_tree.php');
31include_once('./lib/data_query.php');
32include_once('./lib/graphs.php');
33include_once('./lib/html_graph.php');
34include_once('./lib/html_form_template.php');
35include_once('./lib/html_tree.php');
36include_once('./lib/poller.php');
37include_once('./lib/reports.php');
38include_once('./lib/rrd.php');
39include_once('./lib/template.php');
40include_once('./lib/utility.php');
41
42/* set default action */
43set_default_action();
44
45$graph_actions = array(
46	1  => __('Delete'),
47);
48
49if ((get_nfilter_request_var('template_id') != '' && get_nfilter_request_var('template_id') != '-1' && get_nfilter_request_var('template_id') != '0') || get_nfilter_request_var('drp_action') == 2) {
50	$graph_actions += array(
51		2  => __('Change Graph Template'),
52	);
53}
54
55$graph_actions += array(
56	5  => __('Change Device'),
57	6  => __('Reapply Suggested Names'),
58	11 => __('Place Graphs on Report'),
59	9  => __('Create Aggregate Graph'),
60	10 => __('Create Aggregate from Template'),
61	8  => __('Apply Automation Rules')
62);
63
64if (read_config_option('grds_creation_method') == 1) {
65	$graph_actions += array(
66		3 => __('Duplicate'),
67		4 => __('Convert to Graph Template')
68	);
69}
70
71$graph_actions = api_plugin_hook_function('graphs_action_array', $graph_actions);
72
73switch (get_request_var('action')) {
74	case 'save':
75		form_save();
76
77		break;
78	case 'actions':
79		form_actions();
80
81		break;
82	case 'item':
83		top_header();
84		item();
85		bottom_footer();
86
87		break;
88	case 'ajax_graph_items':
89		get_ajax_graph_items();
90
91		break;
92	case 'ajax_hosts':
93		$sql_where = '';
94		if (get_request_var('site_id') > 0) {
95			$sql_where = 'site_id = ' . get_request_var('site_id');
96		}
97
98		get_allowed_ajax_hosts(true, 'applyFilter', $sql_where);
99
100		break;
101	case 'ajax_hosts_noany':
102		$sql_where = '';
103		if (get_request_var('site_id') > 0) {
104			$sql_where = 'site_id = ' . get_request_var('site_id');
105		}
106
107		get_allowed_ajax_hosts(false, 'applyFilter', $sql_where);
108
109		break;
110	case 'lock':
111	case 'unlock':
112		$_SESSION['sess_graph_lock_id'] = get_filter_request_var('id');
113		$_SESSION['sess_graph_locked']  = (get_request_var('action') == 'lock' ? true:false);
114	case 'graph_edit':
115		top_header();
116		graph_edit();
117		bottom_footer();
118
119		break;
120	default:
121		top_header();
122		validate_graph_request_vars();
123		graph_management();
124		bottom_footer();
125
126		break;
127}
128
129/* --------------------------
130    Global Form Functions
131   -------------------------- */
132
133function get_ajax_graph_items() {
134	$rrd_id  = get_filter_request_var('rrd_id');
135	$host_id = get_filter_request_var('host_id');
136
137	if ($host_id > 0) {
138		$sql_where = ' AND data_local.host_id=' . $host_id;
139	} else {
140		$sql_where = '';
141	}
142
143	if (get_request_var('term') != '') {
144		$sql_where .= ' HAVING name LIKE "%' . trim(db_qstr(get_request_var('term')),"'") . '%"';
145	}
146
147	$items  = db_fetch_assoc_prepared("SELECT *
148		FROM (SELECT data_template_rrd.id AS id,
149			CONCAT_WS('',
150			CASE
151			WHEN host.description IS NULL THEN '" . __esc('No Device - ') . "'
152			WHEN host.description IS NOT NULL THEN ''
153			END,
154			data_template_data.name_cache,' (',data_template_rrd.data_source_name,')') AS name
155			FROM (data_template_data,data_template_rrd,data_local)
156			LEFT JOIN host ON (data_local.host_id=host.id)
157			WHERE data_template_rrd.local_data_id=data_local.id
158			AND data_template_data.local_data_id=data_local.id
159			AND data_template_rrd.id = ?
160		) AS a
161		UNION
162		SELECT *
163		FROM (SELECT data_template_rrd.id AS id,
164			CONCAT_WS('',
165			CASE
166			WHEN host.description IS NULL THEN '" . __esc('No Device - ') . "'
167			WHEN host.description IS NOT NULL THEN ''
168			END,
169			data_template_data.name_cache,' (',data_template_rrd.data_source_name,')') AS name
170			FROM (data_template_data,data_template_rrd,data_local)
171			LEFT JOIN host ON (data_local.host_id=host.id)
172			WHERE data_template_rrd.local_data_id=data_local.id
173			AND data_template_data.local_data_id=data_local.id
174			$sql_where
175			ORDER BY name
176		) AS b
177		LIMIT " . read_config_option('autocomplete_rows'),
178		array($rrd_id));
179
180	foreach($items as $key => $item) {
181		$items[$key]['label'] = $item['name'];
182	}
183
184	print json_encode($items);
185}
186
187function add_tree_names_to_actions_array() {
188	global $graph_actions;
189
190	/* add a list of tree names to the actions dropdown */
191	$trees = db_fetch_assoc('SELECT id, name
192		FROM graph_tree
193		ORDER BY name');
194
195	if (cacti_sizeof($trees)) {
196		foreach ($trees as $tree) {
197			$graph_actions['tr_' . $tree['id']] = __esc('Place on a Tree (%s)', $tree['name']);
198		}
199	}
200}
201
202/* --------------------------
203    The Save Function
204   -------------------------- */
205
206function parse_validate_graph_template_id($variable) {
207	$output_type_id = 0;
208	if (strpos(get_nfilter_request_var($variable), '_') !== false) {
209		$template_parts = explode('_', get_nfilter_request_var($variable));
210		if (is_numeric($template_parts[0]) && is_numeric($template_parts[1])) {
211			set_request_var('graph_template_id', $template_parts[0]);
212			$output_type_id = $template_parts[1];
213		} else {
214			cacti_log('ERROR: Unable to parse graph_template_id with value ' . get_nfilter_request_var($variable), false, 'WEBUI');
215			exit;
216		}
217	} else {
218		get_filter_request_var($variable);
219	}
220
221	return $output_type_id;
222}
223
224function form_save() {
225	/* ================= input validation ================= */
226	get_filter_request_var('local_graph_id');
227	get_filter_request_var('host_id_prev');
228	get_filter_request_var('graph_template_graph_id');
229	get_filter_request_var('local_graph_template_graph_id');
230	/* ==================================================== */
231
232	/* handle special case of callback on host_id */
233	if (!is_numeric(get_nfilter_request_var('host_id'))) {
234		set_request_var('host_id', get_request_var('host_id_prev'));
235	} else {
236		get_filter_request_var('host_id');
237	}
238
239	$gt_id_unparsed      = get_nfilter_request_var('graph_template_id');
240	$gt_id_prev_unparsed = get_nfilter_request_var('graph_template_id_prev');
241	parse_validate_graph_template_id('graph_template_id');
242
243	if (isset_request_var('save_component_graph_new') && !isempty_request_var('graph_template_id')) {
244		$snmp_query_array  = array();
245		$suggested_values  = array();
246		$graph_template_id = get_request_var('graph_template_id');
247		$host_id           = get_request_var('host_id');
248
249		$return_array = create_complete_graph_from_template($graph_template_id, $host_id, $snmp_query_array, $suggested_values);
250
251		if ($return_array !== false) {
252			debug_log_insert('new_graphs', __('Created graph: %s', get_graph_title($return_array['local_graph_id'])));
253
254			/* lastly push host-specific information to our data sources */
255			if (cacti_sizeof($return_array['local_data_id'])) { # we expect at least one data source associated
256				foreach($return_array['local_data_id'] as $item) {
257					push_out_host($host_id, $item);
258				}
259			} else {
260				debug_log_insert('new_graphs', __('ERROR: No Data Source associated. Check Template'));
261			}
262		}
263
264		if (isset($return_array['local_graph_id'])) {
265			$local_graph_id = $return_array['local_graph_id'];
266			header('Location: graphs.php?action=graph_edit&header=false&id=' . $local_graph_id);
267		} else {
268			header('Location: graphs.php?header=false');
269		}
270
271		exit;
272	}
273
274	if (isset_request_var('save_component_graph')) {
275		if (get_filter_request_var('host_id') == '-1') {
276			set_request_var('host_id', '0');
277		}
278
279		$save1['id']                   = get_nfilter_request_var('local_graph_id');
280		$save1['host_id']              = get_request_var('host_id');
281		$save1['graph_template_id']    = get_nfilter_request_var('graph_template_id');
282
283		$save2['id']                   = get_nfilter_request_var('graph_template_graph_id');
284		$save2['local_graph_template_graph_id'] = get_nfilter_request_var('local_graph_template_graph_id');
285		$save2['graph_template_id']    = get_nfilter_request_var('graph_template_id');
286		$save2['image_format_id']      = form_input_validate(get_nfilter_request_var('image_format_id'), 'image_format_id', '^[0-9]+$', true, 3);
287		$save2['title']                = form_input_validate(get_nfilter_request_var('title'), 'title', '', false, 3);
288		$save2['height']               = form_input_validate(get_nfilter_request_var('height'), 'height', '^[0-9]+$', false, 3);
289		$save2['width']                = form_input_validate(get_nfilter_request_var('width'), 'width', '^[0-9]+$', false, 3);
290		$save2['upper_limit']          = form_input_validate(get_nfilter_request_var('upper_limit'), 'upper_limit', "^(-?([0-9]+(\.[0-9]*)?|[0-9]*\.[0-9]+)([eE][+\-]?[0-9]+)?)|U$", ((strlen(get_nfilter_request_var('upper_limit')) === 0) ? true : false), 3);
291		$save2['lower_limit']          = form_input_validate(get_nfilter_request_var('lower_limit'), 'lower_limit', "^(-?([0-9]+(\.[0-9]*)?|[0-9]*\.[0-9]+)([eE][+\-]?[0-9]+)?)|U$", ((strlen(get_nfilter_request_var('lower_limit')) === 0) ? true : false), 3);
292		$save2['vertical_label']       = form_input_validate(get_nfilter_request_var('vertical_label'), 'vertical_label', '', true, 3);
293		$save2['slope_mode']           = form_input_validate((isset_request_var('slope_mode') ? get_nfilter_request_var('slope_mode') : ''), 'slope_mode', '', true, 3);
294		$save2['auto_scale']           = form_input_validate((isset_request_var('auto_scale') ? get_nfilter_request_var('auto_scale') : ''), 'auto_scale', '', true, 3);
295		$save2['auto_scale_opts']      = form_input_validate(get_nfilter_request_var('auto_scale_opts'), 'auto_scale_opts', '', true, 3);
296		$save2['auto_scale_log']       = form_input_validate((isset_request_var('auto_scale_log') ? get_nfilter_request_var('auto_scale_log') : ''), 'auto_scale_log', '', true, 3);
297		$save2['scale_log_units']      = form_input_validate((isset_request_var('scale_log_units') ? get_nfilter_request_var('scale_log_units') : ''), 'scale_log_units', '', true, 3);
298		$save2['auto_scale_rigid']     = form_input_validate((isset_request_var('auto_scale_rigid') ? get_nfilter_request_var('auto_scale_rigid') : ''), 'auto_scale_rigid', '', true, 3);
299		$save2['auto_padding']         = form_input_validate((isset_request_var('auto_padding') ? get_nfilter_request_var('auto_padding') : ''), 'auto_padding', '', true, 3);
300		$save2['base_value']           = form_input_validate(get_nfilter_request_var('base_value'), 'base_value', '^[0-9]+$', false, 3);
301		$save2['unit_value']           = form_input_validate(get_nfilter_request_var('unit_value'), 'unit_value', '', true, 3);
302		$save2['unit_exponent_value']  = form_input_validate(get_nfilter_request_var('unit_exponent_value'), 'unit_exponent_value', '^-?[0-9]+$', true, 3);
303		$save2['alt_y_grid']           = form_input_validate((isset_request_var('alt_y_grid') ? get_nfilter_request_var('alt_y_grid') : ''), 'alt_y_grid', '', true, 3);
304		$save2['right_axis']           = form_input_validate((isset_request_var('right_axis') ? get_nfilter_request_var('right_axis') : ''), 'right_axis', '^-?([0-9]+(\.[0-9]*)?|\.[0-9]+):-?([0-9]+(\.[0-9]*)?|\.[0-9]+)$', true, 3);
305		$save2['right_axis_label']     = form_input_validate((isset_request_var('right_axis_label') ? get_nfilter_request_var('right_axis_label') : ''), 'right_axis_label', '', true, 3);
306		$save2['right_axis_format']    = form_input_validate((isset_request_var('right_axis_format') ? get_nfilter_request_var('right_axis_format') : ''), 'right_axis_format', '^[0-9]+$', true, 3);
307		$save2['no_gridfit']           = form_input_validate((isset_request_var('no_gridfit') ? get_nfilter_request_var('no_gridfit') : ''), 'no_gridfit', '', true, 3);
308		$save2['unit_length']          = form_input_validate((isset_request_var('unit_length') ? get_nfilter_request_var('unit_length') : ''), 'unit_length', '^[0-9]+$', true, 3);
309		$save2['tab_width']            = form_input_validate((isset_request_var('tab_width') ? get_nfilter_request_var('tab_width') : ''), 'tab_width', '^[0-9]*$', true, 3);
310		$save2['dynamic_labels']       = form_input_validate((isset_request_var('dynamic_labels') ? get_nfilter_request_var('dynamic_labels') : ''), 'dynamic_labels', '', true, 3);
311		$save2['force_rules_legend']   = form_input_validate((isset_request_var('force_rules_legend') ? get_nfilter_request_var('force_rules_legend') : ''), 'force_rules_legend', '', true, 3);
312		$save2['legend_position']      = form_input_validate((isset_request_var('legend_position') ? get_nfilter_request_var('legend_position') : ''), 'legend_position', '', true, 3);
313		$save2['legend_direction']     = form_input_validate((isset_request_var('legend_direction') ? get_nfilter_request_var('legend_direction') : ''), 'legend_direction', '', true, 3);
314		$save2['right_axis_formatter'] = form_input_validate((isset_request_var('right_axis_formatter') ? get_nfilter_request_var('right_axis_formatter') : ''), 'right_axis_formatter', '', true, 3);
315		$save2['left_axis_formatter']  = form_input_validate((isset_request_var('left_axis_formatter') ? get_nfilter_request_var('left_axis_formatter') : ''), 'left_axis_formatter', '', true, 3);
316
317		if (!is_error_message()) {
318			$local_graph_id = sql_save($save1, 'graph_local');
319		}
320
321		if (!is_error_message()) {
322			$save2['local_graph_id'] = $local_graph_id;
323			$graph_templates_graph_id = sql_save($save2, 'graph_templates_graph');
324
325			if ($graph_templates_graph_id) {
326				raise_message(1);
327			} else {
328				raise_message(2);
329			}
330
331			/* update the title cache */
332			update_graph_title_cache($local_graph_id);
333
334			/* if the host id changes, then update the graph items association too */
335			if (get_request_var('host_id') != get_request_var('host_id_prev')) {
336				if (!api_graph_change_device($local_graph_id, get_request_var('host_id'))) {
337					raise_message(34);
338				}
339			}
340		}
341
342		if (!is_error_message()) {
343			$lg_template_id = db_fetch_cell_prepared('SELECT graph_template_id
344				FROM graph_local
345				WHERE id = ?',
346				array($local_graph_id)
347			);
348
349			if ($lg_template_id > 0) {
350				change_graph_template($local_graph_id, $gt_id_unparsed);
351
352				$lg_dq_id = db_fetch_cell_prepared('SELECT snmp_query_id
353					FROM graph_local
354					WHERE id = ?',
355					array($local_graph_id)
356				);
357
358				if ($lg_dq_id > 0) {
359					update_graph_data_query_cache($local_graph_id);
360				}
361			}
362		}
363	}
364
365	if (isset_request_var('save_component_input')) {
366		/* ================= input validation ================= */
367		get_filter_request_var('local_graph_id');
368		/* ==================================================== */
369
370		/* first; get the current graph template id */
371		$graph_template_id = db_fetch_cell_prepared('SELECT graph_template_id
372			FROM graph_local
373			WHERE id = ?',
374			array(get_nfilter_request_var('local_graph_id')));
375
376		/* get all inputs that go along with this graph template, if templated */
377		if ($graph_template_id > 0) {
378			$input_list = db_fetch_assoc_prepared('SELECT id, column_name
379				FROM graph_template_input
380				WHERE graph_template_id = ?',
381				array($graph_template_id));
382
383			if (cacti_sizeof($input_list)) {
384				foreach ($input_list as $input) {
385					/* we need to find out which graph items will be affected by saving this particular item */
386					$item_list = db_fetch_assoc_prepared('SELECT gti.id
387						FROM graph_template_input_defs AS gtid
388						INNER JOIN graph_templates_item AS gti
389						ON gtid.graph_template_item_id=gti.local_graph_template_item_id
390						WHERE gti.local_graph_id = ?
391						AND gtid.graph_template_input_id = ?',
392						array(get_nfilter_request_var('local_graph_id'), $input['id']));
393
394					/* loop through each item affected and update column data */
395					if (cacti_sizeof($item_list)) {
396						foreach ($item_list as $item) {
397							/* if we are changing templates, the POST vars we are searching for here will not exist.
398							 this is because the db and form are out of sync here, but it is ok to just skip over saving
399							 the inputs in this case. */
400							if (isset_request_var($input['column_name'] . '_' . $input['id'])) {
401								db_execute_prepared('UPDATE graph_templates_item
402									SET ' . $input['column_name'] . ' = ?
403									WHERE id = ?',
404									array(get_nfilter_request_var($input['column_name'] . '_' . $input['id']), $item['id']));
405							}
406						}
407					}
408				}
409			}
410		}
411	}
412
413	if ((isset_request_var('save_component_graph_new')) && (isempty_request_var('graph_template_id'))) {
414		header('Location: graphs.php?action=graph_edit&header=false&host_id=' . get_nfilter_request_var('host_id') . '&new=1');
415	} elseif ((is_error_message()) || (isempty_request_var('local_graph_id')) || (get_nfilter_request_var('graph_template_id') != get_nfilter_request_var('graph_template_id_prev')) || (get_nfilter_request_var('host_id') != get_nfilter_request_var('host_id_prev'))) {
416		header('Location: graphs.php?action=graph_edit&header=false&id=' . (empty($local_graph_id) ? get_nfilter_request_var('local_graph_id') : $local_graph_id) . (isset_request_var('host_id') ? '&host_id=' . get_nfilter_request_var('host_id') : ''));
417	} elseif (!empty($local_graph_id)) {
418		header('Location: graphs.php?action=graph_edit&header=false&id=' . $local_graph_id);
419	} else {
420		header('Location: graphs.php?header=false');
421	}
422
423	exit;
424}
425
426/* ------------------------
427    The "actions" function
428   ------------------------ */
429
430function get_current_graph_template($local_graph_id) {
431	$graph_local = db_fetch_row_prepared('SELECT *
432		FROM graph_local
433		WHERE id = ?',
434		array($local_graph_id));
435
436	$task_items = db_fetch_cell_prepared('SELECT GROUP_CONCAT(DISTINCT task_item_id) AS items
437		FROM graph_templates_item
438		WHERE local_graph_id = ?',
439		array($local_graph_id));
440
441	if ($task_items != '') {
442		$local_data_id = db_fetch_cell("SELECT DISTINCT local_data_id
443			FROM data_template_rrd
444			WHERE id IN($task_items)");
445	} else {
446		$local_data_id = 0;
447	}
448
449	if ($local_data_id > 0) {
450		$data = db_fetch_row_prepared('SELECT id, data_input_id, data_template_id, name, local_data_id
451			FROM data_template_data
452			WHERE local_data_id = ?',
453			array($local_data_id));
454
455		/* get each INPUT field for this data input source */
456		$output_type_field_id = db_fetch_cell_prepared('SELECT id
457			FROM data_input_fields
458			WHERE data_input_id = ?
459			AND input_output="in"
460			AND type_code="output_type"
461			ORDER BY sequence',
462			array($data['data_input_id']));
463
464		$snmp_query_graph_id = db_fetch_cell_prepared('SELECT value
465			FROM data_input_data
466			WHERE data_template_data_id = ?
467			AND data_input_field_id = ?',
468			array($data['id'], $output_type_field_id));
469
470		if (!empty($snmp_query_graph_id)) {
471			return $graph_local['graph_template_id'] . '_' . $snmp_query_graph_id;
472		} else {
473			return $graph_local['graph_template_id'];
474		}
475	} else {
476		return $graph_local['graph_template_id'];
477	}
478}
479
480function get_common_graph_templates(&$graph) {
481	$dqid = 0;
482
483	if (cacti_sizeof($graph)) {
484		$dqid = db_fetch_cell_prepared('SELECT snmp_query_id
485			FROM graph_local
486			WHERE id = ?',
487			array($graph['local_graph_id']));
488	}
489
490	// Default in worst case
491	$gtsql = 'SELECT gt.id, gt.name FROM graph_templates AS gt ORDER BY name';
492
493	if ($dqid > 0) {
494		$sqgi = db_fetch_cell_prepared('SELECT GROUP_CONCAT(id) AS id
495			FROM snmp_query_graph
496			WHERE snmp_query_id = ?
497			AND graph_template_id = ?',
498			array($dqid, $graph['graph_template_id']));
499
500		if ($sqgi != '') {
501			$query_fields = array_rekey(db_fetch_assoc_prepared('SELECT snmp_query_graph_id,
502				GROUP_CONCAT(snmp_field_name ORDER BY snmp_field_name) AS columns
503				FROM snmp_query_graph_rrd
504				WHERE snmp_query_graph_id IN (' . $sqgi . ')
505				GROUP BY snmp_query_graph_id'), 'snmp_query_graph_id', 'columns');
506
507			if (cacti_sizeof($query_fields)) {
508				$ids = array_to_sql_or(array_values($query_fields), 'columns');
509
510				$common_graph_ids = array_rekey(db_fetch_assoc_prepared('SELECT
511					snmp_query_graph_id, GROUP_CONCAT(snmp_field_name ORDER BY snmp_field_name) AS columns
512					FROM snmp_query_graph_rrd
513					GROUP BY snmp_query_graph_id
514					HAVING ' . $ids), 'snmp_query_graph_id', 'columns');
515
516				if (cacti_sizeof($common_graph_ids)) {
517					$ids = implode(',', array_keys($common_graph_ids));
518
519					$gtids = db_fetch_cell_prepared('SELECT GROUP_CONCAT(DISTINCT graph_template_id) AS gtids
520						FROM snmp_query_graph
521						WHERE snmp_query_id = ?
522						AND id IN (' . $ids . ')',
523						array($dqid));
524
525					if ($gtids != '') {
526						$gtsql = "SELECT CONCAT_WS('', graph_template_id, '_', id, '') AS id, name
527							FROM snmp_query_graph
528							WHERE (snmp_query_id = $dqid AND id IN ($ids))
529							OR graph_template_id IN ($gtids) ORDER BY name";
530					} else {
531						$gtsql = "SELECT CONCAT_WS('', graph_template_id, '_', id, '') AS id, name
532							FROM snmp_query_graph
533							WHERE (snmp_query_id = $dqid AND id IN ($ids))
534							ORDER BY name";
535					}
536				}
537			}
538		}
539	}
540
541	return $gtsql;
542}
543
544function form_actions() {
545	global $graph_actions, $struct_aggregate;
546
547	/* ================= input validation ================= */
548	get_filter_request_var('drp_action', FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^([a-zA-Z0-9_]+)$/')));
549	/* ==================================================== */
550
551	/* if we are to save this form, instead of display it */
552	if (isset_request_var('selected_items')) {
553		$selected_items = sanitize_unserialize_selected_items(get_nfilter_request_var('selected_items'));
554
555		if ($selected_items != false) {
556			if (get_request_var('drp_action') == '1') { // delete
557				if (!isset_request_var('delete_type')) {
558					set_request_var('delete_type', 1);
559				}
560
561				api_delete_graphs($selected_items, get_filter_request_var('delete_type'));
562			} elseif (get_request_var('drp_action') == '2') { // change graph template
563				$gt_id_unparsed      = get_nfilter_request_var('graph_template_id');
564				$gt_id_prev_unparsed = get_nfilter_request_var('graph_template_id_prev');
565				parse_validate_graph_template_id('graph_template_id');
566
567				for ($i=0;($i<cacti_count($selected_items));$i++) {
568					change_graph_template($selected_items[$i], $gt_id_unparsed, true);
569				}
570			} elseif (get_request_var('drp_action') == '3') { // duplicate
571				for ($i=0;($i<cacti_count($selected_items));$i++) {
572					api_duplicate_graph($selected_items[$i], 0, get_nfilter_request_var('title_format'));
573				}
574			} elseif (get_request_var('drp_action') == '4') { // graph -> graph template
575				for ($i=0;($i<cacti_count($selected_items));$i++) {
576					graph_to_graph_template($selected_items[$i], get_nfilter_request_var('title_format'));
577				}
578			} elseif (preg_match('/^tr_([0-9]+)$/', get_request_var('drp_action'), $matches)) { // place on tree
579				get_filter_request_var('tree_id');
580				get_filter_request_var('tree_item_id');
581				for ($i=0;($i<cacti_count($selected_items));$i++) {
582					api_tree_item_save(0, get_nfilter_request_var('tree_id'), TREE_ITEM_TYPE_GRAPH, get_nfilter_request_var('tree_item_id'), '', $selected_items[$i], 0, 0, 0, 0, false);
583				}
584			} elseif (get_request_var('drp_action') == '5') { // change host
585				get_filter_request_var('host_id');
586				$failures = false;
587				for ($i=0;($i<cacti_count($selected_items));$i++) {
588					if (!api_graph_change_device($selected_items[$i], get_request_var('host_id'))) {
589						$failures = true;
590					}
591
592					if ($failures) {
593						raise_message(33);
594					}
595				}
596			} elseif (get_request_var('drp_action') == '6') { // reapply suggested naming
597				for ($i=0;($i<cacti_count($selected_items));$i++) {
598					api_reapply_suggested_graph_title($selected_items[$i]);
599					update_graph_title_cache($selected_items[$i]);
600				}
601			} elseif (get_request_var('drp_action') == '9' || get_request_var('drp_action') == '10') {
602				/* get common info - not dependant on template/no template*/
603				$local_graph_id = 0; // this will be a new graph
604				$member_graphs  = $selected_items;
605				$graph_title    = form_input_validate(get_nfilter_request_var('title_format'), 'title_format', '', true, 3);
606
607				/* future aggregate_graphs entry */
608				$ag_data = array();
609				$ag_data['id'] = 0;
610				$ag_data['title_format'] = $graph_title;
611				$ag_data['user_id']      = $_SESSION['sess_user_id'];
612
613				if (get_request_var('drp_action') == '9') {
614					if (!isset_request_var('aggregate_total_type'))   set_request_var('aggregate_total_type', 0);
615					if (!isset_request_var('aggregate_total'))        set_request_var('aggregate_total', 0);
616					if (!isset_request_var('aggregate_total_prefix')) set_request_var('aggregate_total_prefix', '');
617					if (!isset_request_var('aggregate_order_type'))   set_request_var('aggregate_order_type', 0);
618
619					$item_no = form_input_validate(get_nfilter_request_var('item_no'), 'item_no', '^[0-9]+$', true, 3);
620
621					$ag_data['aggregate_template_id'] = 0;
622					$ag_data['template_propogation']  = '';
623					$ag_data['graph_template_id']     = form_input_validate(get_nfilter_request_var('graph_template_id'), 'graph_template_id', '^[0-9]+$', true, 3);
624					$ag_data['gprint_prefix']         = form_input_validate(get_nfilter_request_var('gprint_prefix'), 'gprint_prefix', '', true, 3);
625					$ag_data['graph_type']            = form_input_validate(get_nfilter_request_var('aggregate_graph_type'), 'aggregate_graph_type', '^[0-9]+$', true, 3);
626					$ag_data['total']                 = form_input_validate(get_nfilter_request_var('aggregate_total'), 'aggregate_total', '^[0-9]+$', true, 3);
627					$ag_data['total_type']            = form_input_validate(get_nfilter_request_var('aggregate_total_type'), 'aggregate_total_type', '^[0-9]+$', true, 3);
628					$ag_data['total_prefix']          = form_input_validate(get_nfilter_request_var('aggregate_total_prefix'), 'aggregate_total_prefix', '', true, 3);
629					$ag_data['order_type']            = form_input_validate(get_nfilter_request_var('aggregate_order_type'), 'aggregate_order_type', '^[0-9]+$', true, 3);
630				} else {
631					$template_data = db_fetch_row_prepared('SELECT *
632						FROM aggregate_graph_templates
633						WHERE id = ?',
634						array(get_nfilter_request_var('aggregate_template_id')));
635
636					$item_no = db_fetch_cell_prepared('SELECT COUNT(*)
637						FROM aggregate_graph_templates_item
638						WHERE aggregate_template_id = ?',
639						array(get_nfilter_request_var('aggregate_template_id')));
640
641					$ag_data['aggregate_template_id'] = get_nfilter_request_var('aggregate_template_id');
642					$ag_data['template_propogation']  = 'on';
643					$ag_data['graph_template_id']     = $template_data['graph_template_id'];
644					$ag_data['gprint_prefix']         = $template_data['gprint_prefix'];
645					$ag_data['graph_type']            = $template_data['graph_type'];
646					$ag_data['total']                 = $template_data['total'];
647					$ag_data['total_type']            = $template_data['total_type'];
648					$ag_data['total_prefix']          = $template_data['total_prefix'];
649					$ag_data['order_type']            = $template_data['order_type'];
650				}
651
652				/* create graph in cacti tables */
653				$local_graph_id = aggregate_graph_save(
654					$local_graph_id,
655					$ag_data['graph_template_id'],
656					$graph_title,
657					$ag_data['aggregate_template_id']
658				);
659
660				$ag_data['local_graph_id'] = $local_graph_id;
661				$aggregate_graph_id = sql_save($ag_data, 'aggregate_graphs');
662				$ag_data['aggregate_graph_id'] = $aggregate_graph_id;
663
664				// 	/* save member graph info */
665				// 	$i = 1;
666				// 	foreach($member_graphs as $graph_id) {
667				// 		db_execute("INSERT INTO aggregate_graphs_items
668				// 			(aggregate_graph_id, local_graph_id, sequence)
669				// 			VALUES
670				// 			($aggregate_graph_id, $graph_id, $i)"
671				// 		);
672				// 		$i++;
673				// 	}
674
675				/* save aggregate graph graph items */
676				if (get_request_var('drp_action') == '9') {
677					/* get existing item ids and sequences from graph template */
678					$graph_templates_items = array_rekey(
679						db_fetch_assoc_prepared('SELECT id, sequence
680							FROM graph_templates_item
681							WHERE local_graph_id=0
682							AND graph_template_id = ?',
683							array($ag_data['graph_template_id'])),
684						'id', array('sequence')
685					);
686
687					/* update graph template item values with posted values */
688					aggregate_validate_graph_items($_POST, $graph_templates_items);
689
690					$aggregate_graph_items = array();
691					foreach ($graph_templates_items as $item_id => $data) {
692						$item_new                            = array();
693						$item_new['aggregate_graph_id']      = $aggregate_graph_id;
694						$item_new['graph_templates_item_id'] = $item_id;
695
696						$item_new['color_template']          = isset($data['color_template']) ? $data['color_template'] : 0;
697						$item_new['item_skip']               = isset($data['item_skip']) ? 'on' : '';
698						$item_new['item_total']              = isset($data['item_total']) ? 'on' : '';
699						$item_new['sequence']                = isset($data['sequence']) ? $data['sequence'] : 0;
700
701						$aggregate_graph_items[]             = $item_new;
702					}
703
704					aggregate_graph_items_save($aggregate_graph_items, 'aggregate_graphs_graph_item');
705				} else {
706					$aggregate_graph_items = db_fetch_assoc_prepared('SELECT *
707						FROM aggregate_graph_templates_item
708						WHERE aggregate_template_id = ?',
709						array($ag_data['aggregate_template_id']));
710				}
711
712				$attribs = $ag_data;
713				$attribs['graph_title'] = $ag_data['title_format'];
714				$attribs['reorder'] = $ag_data['order_type'];
715				$attribs['item_no'] = $item_no;
716				$attribs['color_templates'] = array();
717				$attribs['skipped_items']   = array();
718				$attribs['total_items']     = array();
719				$attribs['graph_item_types']= array();
720				$attribs['cdefs']           = array();
721
722				foreach ($aggregate_graph_items as $item) {
723					if (isset($item['color_template']) && $item['color_template'] > 0) {
724						$attribs['color_templates'][ $item['sequence'] ] = $item['color_template'];
725					}
726
727					if (isset($item['item_skip']) && $item['item_skip'] == 'on') {
728						$attribs['skipped_items'][ $item['sequence'] ] = $item['sequence'];
729					}
730
731					if (isset($item['item_total']) && $item['item_total'] == 'on') {
732						$attribs['total_items'][ $item['sequence'] ] = $item['sequence'];
733					}
734
735					if (isset($item['cdef_id']) && isset($item['t_cdef_id']) && $item['t_cdef_id'] == 'on') {
736						$attribs['cdefs'][ $item['sequence'] ] = $item['cdef_id'];
737					}
738
739					if (isset($item['graph_type_id']) && isset($item['t_graph_type_id']) && $item['t_graph_type_id'] == 'on') {
740						$attribs['graph_item_types'][ $item['sequence'] ] = $item['graph_type_id'];
741					}
742				}
743
744				/* create actual graph items */
745				aggregate_create_update($local_graph_id, $member_graphs, $attribs);
746
747				header("Location: aggregate_graphs.php?header=false&action=edit&tab=details&id=$local_graph_id");
748				exit;
749			} elseif (get_request_var('drp_action') == '8') { // automation
750				cacti_log('automation_graph_action_execute called: ' . get_request_var('drp_action'), true, 'AUTM8 TRACE', POLLER_VERBOSITY_MEDIUM);
751
752				/* work on all selected graphs */
753				for ($i=0;($i<cacti_count($selected_items));$i++) {
754					automation_execute_graph_create_tree($selected_items[$i]);
755				}
756			} elseif (get_request_var('drp_action') == '11') {
757				// Add to a report
758				$good = true;
759				for ($i=0;($i<cacti_count($selected_items));$i++) {
760					if (!reports_add_graphs(get_filter_request_var('report_id'), $selected_items[$i], get_request_var('timespan'), get_request_var('align'))) {
761						raise_message('reports_add_error');
762						$good = false;
763						break;
764					}
765				}
766
767				if ($good) {
768					raise_message('reports_graphs_added');
769				}
770			} else {
771				api_plugin_hook_function('graphs_action_execute', get_request_var('drp_action'));
772			}
773
774			/* update snmpcache */
775			snmpagent_graphs_action_bottom(array(get_request_var('drp_action'), $selected_items));
776			api_plugin_hook_function('graphs_action_bottom', array(get_request_var('drp_action'), $selected_items));
777		}
778
779		if (get_request_var('drp_action') == '2') { // change graph template
780			header('Location: graphs.php?header=false&template_id=-1');
781		} else {
782			header('Location: graphs.php?header=false');
783		}
784
785		exit;
786	}
787
788	/* setup some variables */
789	$i          = 0;
790	$graph_list = '';
791	$graph      = array();
792
793	/* loop through each of the graphs selected on the previous page and get more info about them */
794	foreach ($_POST as $var => $val) {
795		if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
796			/* ================= input validation ================= */
797			input_validate_input_number($matches[1]);
798			/* ==================================================== */
799
800			$graph_list .= '<li>' . html_escape(get_graph_title($matches[1])) . '</li>';
801			$graph_array[$i] = $matches[1];
802
803			if ($i == 0) {
804				$graph = db_fetch_row_prepared('SELECT id AS local_graph_id, graph_template_id
805					FROM graph_local
806					WHERE id = ?
807					LIMIT 1',
808					array($matches[1]));
809			}
810
811			$i++;
812		}
813	}
814
815	top_header();
816
817	/* add a list of tree names to the actions dropdown */
818	add_tree_names_to_actions_array();
819
820	form_start('graphs.php');
821
822	html_start_box($graph_actions[get_request_var('drp_action')], '60%', '', '3', 'center', '');
823
824	if (isset($graph_array) && cacti_sizeof($graph_array)) {
825		if (get_request_var('drp_action') == '1') { // delete
826			/* find out which (if any) data sources are being used by this graph, so we can tell the user */
827			if (isset($graph_array) && cacti_sizeof($graph_array)) {
828				$data_sources = array_rekey(
829					db_fetch_assoc('SELECT DISTINCT dtd.local_data_id, dtd.name_cache
830						FROM data_template_data AS dtd
831						INNER JOIN data_template_rrd AS dtr
832						ON dtr.local_data_id=dtd.local_data_id
833						INNER JOIN graph_templates_item AS gti
834						ON dtr.id=gti.task_item_id
835						WHERE ' . array_to_sql_or($graph_array, 'gti.local_graph_id') . '
836						AND dtd.local_data_id > 0'),
837					'local_data_id', array('local_data_id', 'name_cache'));
838
839				/* data sources to delete */
840				$data_array = array_keys($data_sources);
841
842				if (cacti_sizeof($data_array)) {
843					$not_deletable = array_rekey(
844						db_fetch_assoc('SELECT DISTINCT dtd.local_data_id
845							FROM data_template_data AS dtd
846							INNER JOIN data_template_rrd AS dtr
847							ON dtr.local_data_id=dtd.local_data_id
848							INNER JOIN graph_templates_item AS gti
849							ON dtr.id=gti.task_item_id
850							WHERE gti.local_graph_id NOT IN(' . implode(',', $graph_array) . ')
851							AND gti.local_graph_id NOT IN(SELECT local_graph_id FROM aggregate_graphs)
852							AND dtr.local_data_id IN(' . implode(',', $data_array) . ')
853							AND dtd.local_data_id > 0'),
854						'local_data_id', 'local_data_id');
855				} else {
856					$not_deletable = array();
857				}
858
859				if (cacti_sizeof($not_deletable)) {
860					$data_sources = array_rekey(
861						db_fetch_assoc('SELECT DISTINCT dtd.local_data_id, dtd.name_cache
862							FROM data_template_data AS dtd
863							INNER JOIN data_template_rrd AS dtr
864							ON dtr.local_data_id=dtd.local_data_id
865							INNER JOIN graph_templates_item AS gti
866							ON dtr.id=gti.task_item_id
867							WHERE gti.local_graph_id IN (' . implode(',', $graph_array) . ')
868							AND gti.local_graph_id NOT IN(SELECT local_graph_id FROM aggregate_graphs)
869							AND dtr.local_data_id NOT IN (' . implode(',', $not_deletable) . ')
870							AND dtd.local_data_id > 0'),
871						'local_data_id', array('local_data_id', 'name_cache'));
872				}
873			}
874
875			print "<tr>
876				<td class='textArea'>
877					<p>" . __('Click \'Continue\' to delete the following Graph(s).  Note that if you choose to Delete Data Sources, only those Data Sources not in use elsewhere will also be Deleted.') . "</p>
878					<div class='itemlist'><ul>$graph_list</ul></div>";
879
880			if (isset($data_sources) && cacti_sizeof($data_sources)) {
881				print "<tr><td class='textArea'><p>" . __('The following Data Source(s) are in use by these Graph(s).') . "</p>\n";
882
883				print '<div class="itemlist"><ul>';
884				foreach ($data_sources as $data_source) {
885					print '<li>' . html_escape($data_source['name_cache']) . "</li>\n";
886				}
887				print '</ul></div><br>';
888
889				print '<span class="nowrap">';
890
891				$ds_preselected_delete = read_config_option('ds_preselected_delete');
892				if ($ds_preselected_delete == 'on') {
893					$delete_radio_button_1_state = '2';
894					$delete_radio_button_2_state = '1';
895				} else {
896					$delete_radio_button_1_state = '1';
897					$delete_radio_button_2_state = '2';
898				}
899
900				form_radio_button('delete_type', '2', $delete_radio_button_1_state , __('Delete all Data Source(s) referenced by these Graph(s) that are not in use elsewhere.'), '1');
901				print '<br>';
902				form_radio_button('delete_type', '2', $delete_radio_button_2_state , __('Leave the Data Source(s) untouched.'), '1');
903				print '<br>';
904				print '</span>';
905				print '</td></tr>';
906			}
907
908			print "</td></tr>\n";
909
910			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') ."' title='" . __esc('Delete Graph(s)') . "'>";
911		} elseif (get_request_var('drp_action') == '2') { // change graph template
912			print "<tr>
913				<td class='textArea'>
914					<p>" . __('Choose a Graph Template and click \'Continue\' to change the Graph Template for the following Graph(s). Please note, that only compatible Graph Templates will be displayed.  Compatible is identified by those having identical Data Sources.') . "</p>
915					<div class='itemlist'><ul>$graph_list</ul></div>
916					<p>" . __('New Graph Template') . "<br>";
917
918					$gtsql = get_common_graph_templates($graph);
919
920					form_dropdown('graph_template_id', db_fetch_assoc($gtsql), 'name', 'id', '', '', '0');
921
922					print "</p>
923				</td>
924			</tr>\n";
925
926			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Change Graph Template') . "'>";
927		} elseif (get_request_var('drp_action') == '3') { // duplicate
928			print "<tr>
929				<td class='textArea'>
930					<p>" . __('Click \'Continue\' to duplicate the following Graph(s). You can optionally change the title format for the new Graph(s).') . "</p>
931					<div class='itemlist'><ul>$graph_list</ul></div>
932					<p>" . __('Title Format') . "<br>";
933			form_text_box('title_format', __('<graph_title> (1)'), '', '255', '30', 'text');
934			print "</p>
935				</td>
936			</tr>\n";
937			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Duplicate Graph(s)') . "'>";
938		} elseif (get_request_var('drp_action') == '4') { // graph -> graph template
939			print "<tr>
940				<td class='textArea'>
941					<p>" . __('Click \'Continue\' to convert the following Graph(s) into Graph Template(s).  You can optionally change the title format for the new Graph Template(s).') . "</p>
942					<div class='itemlist'><ul>$graph_list</ul></div>
943					<p>" . __('Title Format') . "<br>";
944			form_text_box('title_format', __('<graph_title> Template'), '', '255', '30', 'text');
945			print "</p>
946				</td>
947			</tr>\n";
948			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Convert to Graph Template') . "'>";
949		} elseif (preg_match('/^tr_([0-9]+)$/', get_request_var('drp_action'), $matches)) { // place on tree
950			print "<tr>
951				<td class='textArea'>
952					<p>" . __('Click \'Continue\' to place the following Graph(s) under the Tree Branch selected below.') . "</p>
953					<div class='itemlist'><ul>$graph_list</ul></div>
954					<p>" . __('Destination Branch') . "<br>";
955
956			grow_dropdown_tree($matches[1], '0', 'tree_item_id', '0');
957
958			print "</p>
959				</td>
960				</tr>
961				<input type='hidden' name='tree_id' value='" . html_escape($matches[1]) . "'>\n";
962
963			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Place Graph(s) on Tree') . "'>";
964		} elseif (get_request_var('drp_action') == '5') { // change host
965			print "<tr>
966				<td class='textArea'>
967					<p>" . __('Choose a new Device for these Graph(s) and click \'Continue\'.') . "</p>
968					<div class='itemlist'><ul>$graph_list</ul></div>
969					<p>" . __('New Device'). "<br>";
970
971			form_dropdown('host_id',db_fetch_assoc("SELECT id,CONCAT_WS('',description,' (',hostname,')') as name FROM host ORDER BY description,hostname"),'name','id','','','0');
972
973			print "</p>
974				</td>
975			</tr>\n";
976
977			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Change Graph(s) Associated Device') . "'>";
978		} elseif (get_request_var('drp_action') == '6') { // reapply suggested naming to host
979			print "<tr>
980				<td class='textArea'>
981					<p>" . __('Click \'Continue\' to re-apply suggested naming to the following Graph(s).') . "</p>
982					<div class='itemlist'><ul>$graph_list</ul></div>
983				</td>
984			</tr>\n";
985
986			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Reapply Suggested Naming to Graph(s)') . "'>";
987		} elseif (get_request_var('drp_action') == '9') {
988			include_once('./lib/api_aggregate.php');
989
990			/* initialize return code and graphs array */
991			$return_code    = false;
992			$data_sources   = array();
993			$graph_template = '';
994
995			if (aggregate_get_data_sources($graph_array, $data_sources, $graph_template)) {
996				# provide a new prefix for GPRINT lines
997				$gprint_prefix = '|host_description|';
998
999				/* list affected graphs */
1000				print '<tr>';
1001				print "<td class='textArea'>
1002					<p>" . __('Click \'Continue\' to create an Aggregate Graph from the selected Graph(s).'). "</p>
1003					<div class='itemlist'><ul>" . get_nfilter_request_var('graph_list') . '</ul></div>
1004				</td></tr>';
1005
1006				/* list affected data sources */
1007				print '<tr>';
1008
1009				if (cacti_sizeof($data_sources)) {
1010					print "<td class='textArea'>" .
1011					'<p>' . __('The following Data Sources are in use by these Graphs:') . '</p>
1012					<div class="itemlist"><ul>';
1013					foreach ($data_sources as $data_source) {
1014						print '<li>' . html_escape($data_source['name_cache']) . '</li>';
1015					}
1016					print '</ul></div></td>';
1017				}
1018				print '</tr>';
1019
1020				print '<tr><td>';
1021
1022				$ttitle = $graph_array[0];
1023
1024				/* aggregate form */
1025				$_aggregate_defaults = array(
1026					'title_format'      => auto_title($ttitle),
1027					'graph_template_id' => $graph_template,
1028					'gprint_prefix'     => $gprint_prefix
1029				);
1030
1031				$helper_string = '|host_description|';
1032
1033				if ($graph_template > 0) {
1034					$data_query = db_fetch_cell_prepared('SELECT snmp_query_id
1035						FROM snmp_query_graph
1036						WHERE graph_template_id = ?',
1037						array($graph_template));
1038
1039					if ($data_query > 0) {
1040						$data_query_info = get_data_query_array($data_query);
1041						foreach($data_query_info['fields'] as $field_name => $field_array) {
1042							if ($field_array['direction'] == 'input' || $field_array['direction'] == 'input-output') {
1043								$helper_string .= ($helper_string != '' ? ', ':'') . '|query_' . $field_name . '|';
1044							}
1045						}
1046					}
1047				}
1048
1049				// Append the helper string
1050				$struct_aggregate['suggestions'] = array(
1051					'method' => 'other',
1052					'friendly_name' => __('Prefix Replacement Values'),
1053					'description' => __('You may use these replacement values for the Prefix in the Aggregate Graph'),
1054					'value' => $helper_string
1055				);
1056
1057				draw_edit_form(
1058					array(
1059						'config' => array('no_form_tag' => true),
1060						'fields' => inject_form_variables($struct_aggregate, $_aggregate_defaults)
1061					)
1062				);
1063
1064				# draw all graph items of first graph, including a html_start_box
1065				draw_aggregate_graph_items_list(0, $graph_template);
1066
1067				print '</td></tr>';
1068
1069				# again, a new html_start_box. Using the one from above would yield ugly formatted NO and YES buttons
1070				html_start_box(__('Please confirm'), '100%', '', '3', 'center', '');
1071
1072				?>
1073				<script type='text/javascript'>
1074				function changeTotals() {
1075					switch ($('#aggregate_total').val()) {
1076						case '<?php print AGGREGATE_TOTAL_NONE;?>':
1077							$('#aggregate_total_type').prop('disabled', true);
1078							if ($('#aggregate_total_type').selectmenu('instance')) {
1079								$('#aggregate_total_type').selectmenu('disable');
1080							}
1081
1082							$('#aggregate_total_prefix').prop('disabled', true);
1083							if ($('#aggregate_total_prefix').selectmenu('instance')) {
1084								$('#aggregate_total_prefix').selectmenu('disable');
1085							}
1086
1087							$('#aggregate_order_type').prop('disabled', false);
1088							if ($('#aggregate_order_type').selectmenu('instance')) {
1089								$('#aggregate_order_type').selectmenu('enable');
1090							}
1091
1092							break;
1093						case '<?php print AGGREGATE_TOTAL_ALL;?>':
1094							$('#aggregate_total_type').prop('disabled', false);
1095							if ($('#aggregate_total_type').selectmenu('instance')) {
1096								$('#aggregate_total_type').selectmenu('enable');
1097							}
1098
1099							$('#aggregate_total_prefix').prop('disabled', false);
1100							if ($('#aggregate_total_prefix').selectmenu('instance')) {
1101								$('#aggregate_total_prefix').selectmenu('enable');
1102							}
1103
1104
1105							$('#aggregate_order_type').prop('disabled', false);
1106							if ($('#aggregate_order_type').selectmenu('instance')) {
1107								$('#aggregate_order_type').selectmenu('enable');
1108							}
1109
1110
1111							changeTotalsType();
1112							break;
1113						case '<?php print AGGREGATE_TOTAL_ONLY;?>':
1114							$('#aggregate_total_type').prop('disabled', false);
1115							if ($('#aggregate_total_type').selectmenu('instance')) {
1116								$('#aggregate_total_type').selectmenu('enable');
1117							}
1118							$('#aggregate_total_prefix').prop('disabled', false);
1119							if ($('#aggregate_total_prefix').selectmenu('instance')) {
1120								$('#aggregate_total_prefix').selectmenu('enable');
1121							}
1122
1123							$('#aggregate_order_type').prop('disabled', true);
1124							if ($('#aggregate_order_type').selectmenu('instance')) {
1125								$('#aggregate_order_type').selectmenu('disable');
1126							}
1127
1128							changeTotalsType();
1129							break;
1130					}
1131				}
1132
1133				function changeTotalsType() {
1134					if (($('#aggregate_total_type').val() == <?php print AGGREGATE_TOTAL_TYPE_SIMILAR;?>)) {
1135						$('#aggregate_total_prefix').attr('value', '<?php print __('Total');?>');
1136					} else if (($('#aggregate_total_type').val() == <?php print AGGREGATE_TOTAL_TYPE_ALL;?>)) {
1137						$('#aggregate_total_prefix').attr('value', '<?php print __('All Items');?>');
1138					}
1139				}
1140
1141				function checkSubmit() {
1142					if ($('input[id^="agg_total"]:checked').length == 0) {
1143						$('input[type="submit"]').prop('disable', true).addClass('ui-state-disabled');;
1144					} else {
1145						$('input[type="submit"]').prop('disable', true).removeClass('ui-state-disabled');;
1146					}
1147				}
1148
1149				$(function() {
1150					$('#aggregate_total').change(function() {
1151						changeTotals();
1152					});
1153
1154					$('#aggregate_total_type').change(function() {
1155						changeTotalsType();
1156					});
1157
1158					$('input[id^="agg_total"], input[id^="agg_skip"]').click(function() {
1159						id = $(this).attr('id');
1160
1161						if (id.indexOf('skip') > 0) {
1162							altId = id.replace('skip', 'total');
1163						} else {
1164							altId = id.replace('total', 'skip');
1165						}
1166
1167						if ($('#'+id).is(':checked')) {
1168							$('#'+altId).prop('checked', false);
1169						} else {
1170							$('#'+altId).prop('checked', true);
1171						}
1172
1173						checkSubmit();
1174					});
1175
1176					$('input[id^="agg_skip"]').each(function() {
1177						$(this).prop('checked', true);
1178					});
1179
1180					changeTotals();
1181					checkSubmit();
1182				});
1183				</script>
1184				<?php
1185
1186				$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Create Aggregate Graph') . "'>";
1187			} else {
1188				$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Return') . "' onClick='cactiReturnTo()'>";
1189			}
1190		} elseif (get_request_var('drp_action') == '10') { // aggregate template
1191			include_once('./lib/api_aggregate.php');
1192
1193			/* initialize return code and graphs array */
1194			$data_sources   = array();
1195			$graph_template = '';
1196
1197			/* find out which (if any) data sources are being used by this graph, so we can tell the user */
1198			if (aggregate_get_data_sources($graph_array, $data_sources, $graph_template)) {
1199				$aggregate_templates = db_fetch_assoc_prepared('SELECT id, name
1200					FROM aggregate_graph_templates
1201					WHERE graph_template_id = ?
1202					ORDER BY name', array($graph_template));
1203
1204				if (cacti_sizeof($aggregate_templates)) {
1205					/* list affected graphs */
1206					print "<tr>
1207						<td class='textArea'>
1208							<p>" . __('Select the Aggregate Template to use and press \'Continue\' to create your Aggregate Graph.  Otherwise press \'Cancel\' to return.') . "</p>
1209							<div class='itemlist'><ul>" . $graph_list . "</ul></div>
1210						</td>
1211					</tr>\n";
1212
1213					print "<tr><td><table>
1214						<tr>
1215							<td>" . __('Graph Title') . "</td>
1216							<td><input type='text' class='ui-state-default ui-corner-all' name='title_format' size='40'></td>
1217						</tr>
1218						<tr>
1219							<td>" . __('Aggregate Template') . "</td>
1220							<td>
1221								<select name='aggregate_template_id'>\n";
1222
1223					html_create_list($aggregate_templates, 'name', 'id', $aggregate_templates[0]['id']);
1224
1225					print "</select>
1226						</td>
1227					</tr></table></td></tr>\n";
1228
1229					$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Create Aggregate from Template') . "'>";
1230				} else {
1231					print "<tr>
1232						<td class='textArea'>
1233							<p>" . __('There are presently no Aggregate Templates defined for this Graph Template.  Please either first create an Aggregate Template for the selected Graphs Graph Template and try again, or simply crease an un-templated Aggregate Graph.') . "</p>
1234							<p>" . __('Press \'Return\' to return and select different Graphs.') . "</p>
1235						</td>
1236					</tr>\n";
1237
1238					$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Return') . "' onClick='cactiReturnTo()'>";
1239				}
1240			} else {
1241				$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Return') . "' onClick='cactiReturnTo()'>";
1242			}
1243		} elseif (get_request_var('drp_action') == 8) { // automation
1244			print "<tr>
1245				<td class='textArea'>
1246					<p>" . __('Click \'Continue\' to apply Automation Rules to the following Graphs.') . "</p>
1247					<div class='itemlist'><ul>$graph_list</ul></div>
1248				</td>
1249			</tr>\n";
1250
1251			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Apply Automation Rules') . "'>";
1252		} elseif (get_request_var('drp_action') == '11') {
1253			global $alignment, $graph_timespans;
1254
1255			$reports = db_fetch_assoc_prepared('SELECT id, name
1256				FROM reports
1257				WHERE user_id = ?
1258				ORDER BY name',
1259				array($_SESSION['sess_user_id']));
1260
1261			if (cacti_sizeof($reports)) {
1262				print "<tr>
1263					<td class='textArea'>
1264						<p>" . __('Click \'Continue\' to add the selected Graphs to the Report below.') . "</p>
1265						<div class='itemlist'><ul>$graph_list</ul></div>
1266					</td>
1267				</tr>
1268				<tr><td>" . __('Report Name') . '<br>';
1269				form_dropdown('report_id', $reports, 'name', 'id', '', '', '0');
1270				print '</td></tr>';
1271
1272				print '<tr><td>' . __('Timespan') . '<br>';
1273				form_dropdown('timespan',$graph_timespans, '', '', '', '', read_user_setting('default_timespan'));
1274				print '</td></tr>';
1275
1276				print '<tr><td>' . __('Align') . '<br>';
1277				form_dropdown('align',$alignment, '', '', '', '', REPORTS_ALIGN_CENTER);
1278				print "</td></tr>\n";
1279
1280				$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "' title='" . __esc('Add Graphs to Report') . "'>";
1281			} else {
1282				print "<tr><td class='even'><span class='textError'>" . __('You currently have no reports defined.') . "</span></td></tr>\n";
1283				$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Return') . "' onClick='cactiReturnTo()'>";
1284			}
1285		} else {
1286			$save['drp_action'] = get_nfilter_request_var('drp_action');
1287			$save['graph_list'] = $graph_list;
1288			$save['graph_array'] = (isset($graph_array) ? $graph_array : array());
1289
1290			api_plugin_hook_function('graphs_action_prepare', $save);
1291
1292			$save_html = "<input type='button' class='ui-button ui-corner-all ui-widget' value='" . __esc('Cancel') . "' onClick='cactiReturnTo()'>&nbsp;<input type='submit' class='ui-button ui-corner-all ui-widget' value='" . __esc('Continue') . "'>";
1293		}
1294	} else {
1295		raise_message(40);
1296		header('Location: graphs.php?header=false');
1297		exit;
1298	}
1299
1300	print "<tr>
1301		<td class='saveRow'>
1302			<input type='hidden' name='action' value='actions'>
1303			<input type='hidden' name='selected_items' value='" . (isset($graph_array) ? serialize($graph_array) : '') . "'>
1304			<input type='hidden' name='drp_action' value='" . get_request_var('drp_action') . "'>
1305			$save_html
1306		</td>
1307	</tr>\n";
1308
1309	html_end_box();
1310
1311	form_end();
1312
1313	bottom_footer();
1314}
1315
1316/* -----------------------
1317    item - Graph Items
1318   ----------------------- */
1319
1320function item() {
1321	global $consolidation_functions, $graph_item_types, $struct_graph_item;
1322
1323	/* ================= input validation ================= */
1324	get_filter_request_var('id');
1325	/* ==================================================== */
1326
1327	if (isempty_request_var('id')) {
1328		$template_item_list = array();
1329
1330		$header_label = __('Graph Items [new]');
1331		$add_text     = '';
1332		$anchor_link  = '';
1333	} else {
1334		$template_item_list = db_fetch_assoc_prepared("SELECT
1335			gti.id, gti.text_format, gti.value, gti.hard_return, gti.graph_type_id, gti.alpha, gti.textalign,
1336			gti.consolidation_function_id, gti.sequence,
1337			CONCAT(dtd.name_cache, ' (',  dtr.data_source_name, ')') AS data_source_name,
1338			cd.name AS cdef_name, c.hex,
1339			vd.name AS vdef_name, gtgp.name AS gprint_name
1340			FROM graph_templates_item AS gti
1341			LEFT JOIN data_template_rrd AS dtr
1342			ON (gti.task_item_id = dtr.id)
1343			LEFT JOIN data_local AS dl
1344			ON (dtr.local_data_id = dl.id)
1345			LEFT JOIN data_template_data AS dtd
1346			ON (dl.id = dtd.local_data_id)
1347			LEFT JOIN graph_templates_gprint AS gtgp
1348			ON (gprint_id = gtgp.id)
1349			LEFT JOIN cdef AS cd
1350			ON (cdef_id = cd.id)
1351			LEFT JOIN vdef AS vd
1352			ON (vdef_id = vd.id)
1353			LEFT JOIN colors AS c
1354			ON (color_id = c.id)
1355			WHERE gti.local_graph_id = ?
1356			ORDER BY gti.sequence", array(get_request_var('id')));
1357
1358		$template_item_list = api_plugin_hook_function('graphs_item_array', $template_item_list);
1359
1360		$host_id = db_fetch_cell_prepared('SELECT host_id
1361			FROM graph_local
1362			WHERE id = ?',
1363			array(get_request_var('id')));
1364
1365		$graph_template_id = db_fetch_cell_prepared('SELECT graph_template_id
1366			FROM graph_local
1367			WHERE id = ?',
1368			array(get_request_var('id')));
1369
1370		$header_label = __esc('Graph Items [edit: %s]', get_graph_title(get_request_var('id')));
1371		$add_text     = 'graphs_items.php?action=item_edit' . (!empty($host_id) ? '&host_id=' . $host_id:'') . '&local_graph_id=' . get_request_var('id');
1372		$anchor_link  = 'host_id=' . $host_id . '&local_graph_id=' . get_request_var('id');
1373	}
1374
1375	html_start_box($header_label, '100%', '', '3', 'center', $add_text);
1376
1377	draw_graph_items_list($template_item_list, 'graphs_items.php', $anchor_link, (empty($graph_template_id) || empty($host_id) ? false : true));
1378
1379	?>
1380	<script type='text/javascript'>
1381	$(function() {
1382		$('.deleteMarker, .moveArrow').unbind().click(function(event) {
1383			event.preventDefault();
1384			loadPageNoHeader($(this).attr('href'));
1385		});
1386	});
1387	</script>
1388	<?php
1389
1390	html_end_box();
1391}
1392
1393/* ------------------------------------
1394    graph - Graphs
1395   ------------------------------------ */
1396
1397function is_multi_device_graph($local_graph_id) {
1398	$devices = db_fetch_cell_prepared('SELECT COUNT(DISTINCT host_id)
1399		FROM data_template_rrd AS dtr
1400		INNER JOIN graph_templates_item AS gti
1401		ON gti.task_item_id = dtr.id
1402		INNER JOIN data_local AS dl
1403		ON dl.id = dtr.local_data_id
1404		WHERE gti.local_graph_id = ?',
1405		array($local_graph_id));
1406
1407	return $devices > 1 ? true : false;
1408}
1409
1410function graph_edit() {
1411	global $config, $struct_graph, $image_types, $consolidation_functions, $graph_item_types, $struct_graph_item;
1412
1413	/* ================= input validation ================= */
1414	get_filter_request_var('id');
1415	/* ==================================================== */
1416
1417	$use_graph_template = true;
1418
1419	$locked = 'false';
1420	$graph  = array();
1421
1422	if (!isempty_request_var('id')) {
1423		$_SESSION['sess_graph_lock_id'] = get_request_var('id');
1424
1425		$local_graph_template_graph_id = db_fetch_cell_prepared('SELECT local_graph_template_graph_id
1426			FROM graph_templates_graph
1427			WHERE local_graph_id = ?',
1428			array(get_request_var('id')));
1429
1430		$auto_unlock = read_config_option('graphs_auto_unlock');
1431
1432		if (get_request_var('id') != $_SESSION['sess_graph_lock_id'] && !empty($local_graph_template_graph_id)) {
1433			if ($auto_unlock == 'on') {
1434				$locked = false;
1435			} else {
1436				$locked = true;
1437			}
1438			$_SESSION['sess_graph_locked'] = $locked;
1439		} elseif (empty($local_graph_template_graph_id)) {
1440			$locked = false;
1441			$_SESSION['sess_graph_locked'] = $locked;
1442		} elseif (isset($_SESSION['sess_graph_locked'])) {
1443			$locked = $_SESSION['sess_graph_locked'];
1444		} else {
1445			if ($auto_unlock == 'on') {
1446				$locked = false;
1447			} else {
1448				$locked = true;
1449			}
1450			$_SESSION['sess_graph_locked'] = $locked;
1451		}
1452
1453		$graph = db_fetch_row_prepared('SELECT *
1454			FROM graph_templates_graph
1455			WHERE local_graph_id = ?',
1456			array(get_request_var('id')));
1457
1458		$graph_template = db_fetch_row_prepared('SELECT *
1459			FROM graph_templates_graph
1460			WHERE id = ?',
1461			array($local_graph_template_graph_id));
1462
1463		$host_id = db_fetch_cell_prepared('SELECT host_id
1464			FROM graph_local
1465			WHERE id = ?',
1466			array(get_request_var('id')));
1467
1468		/* case of a deleted graph */
1469		if (!cacti_sizeof($graph)) {
1470			raise_message(31);
1471			header('Location: graphs.php');
1472			exit;
1473		}
1474
1475		$header_label = __esc('Graph [edit: %s]', get_graph_title(get_request_var('id')));
1476
1477		if ($graph['graph_template_id'] == '0') {
1478			$use_graph_template = 'false';
1479		}
1480	} else {
1481		$header_label = __('Graph [new]');
1482		$use_graph_template = false;
1483
1484		if (isset_request_var('host_id') && get_filter_request_var('host_id') > 0) {
1485			$host_id = get_request_var('host_id');
1486		} else {
1487			$host_id = 0;
1488		}
1489
1490		if (isempty_request_var('graph_template_id')) {
1491			$locked = false;
1492		}
1493	}
1494
1495	/* handle debug mode */
1496	if (isset_request_var('debug')) {
1497		if (get_nfilter_request_var('debug') == '0') {
1498			kill_session_var('graph_debug_mode');
1499		} elseif (get_nfilter_request_var('debug') == '1') {
1500			$_SESSION['graph_debug_mode'] = true;
1501		}
1502	}
1503
1504	if (!isempty_request_var('id')) {
1505		if (isset($_SESSION['graph_debug_mode'])) {
1506			$message = __('Turn Off Graph Debug Mode.');
1507		} else {
1508			$message = __('Turn On Graph Debug Mode.');
1509		}
1510
1511		$data_sources = db_fetch_assoc_prepared('SELECT DISTINCT local_data_id
1512			FROM graph_templates_item AS gti
1513			INNER JOIN data_template_rrd AS dtr
1514			ON dtr.id = gti.task_item_id
1515			WHERE local_graph_id = ?',
1516			array(get_request_var('id')));
1517
1518		?>
1519		<table style='width:100%;'>
1520			<tr>
1521				<td class='textInfo left' style='vertical-align:top'>
1522					<?php print html_escape(get_graph_title(get_request_var('id')));?>
1523				</td>
1524				<td class='textInfo right' style='vertical-align:top;'>
1525					<span class='linkMarker'>*</span><a class='hyperLink' href='<?php print html_escape('graphs.php?action=graph_edit&id=' . (isset_request_var('id') ? get_request_var('id') : '0') . '&debug=' . (isset($_SESSION['graph_debug_mode']) ? '0' : '1'));?>'><?php print $message;?></a><br>
1526					<?php
1527						if (!empty($graph['graph_template_id'])) {
1528							?><span class='linkMarker'>*</span><a class='hyperLink' href='<?php print html_escape('graph_templates.php?action=template_edit&id=' . (isset($graph['graph_template_id']) ? $graph['graph_template_id'] : '0'));?>'><?php print __('Edit Graph Template.');?></a><br><?php
1529						}
1530						if (cacti_sizeof($data_sources)) {
1531							foreach($data_sources as $ds) {
1532								$name = db_fetch_cell_prepared('SELECT name_cache
1533									FROM data_template_data
1534									WHERE local_data_id = ?',
1535									array($ds['local_data_id']));
1536
1537							?><span class='linkMarker'>*</span><a class='hyperLink' href='<?php print html_escape('data_sources.php?action=ds_edit&id=' . $ds['local_data_id']);?>'><?php print __('Edit Data Source: \'%s\'.', $name);?></a><br><?php
1538							}
1539						}
1540						if (!isempty_request_var('host_id') || !empty($host_id)) {
1541							?><span class='linkMarker'>*</span><a class='hyperLink' href='<?php print html_escape('host.php?action=edit&id=' . ($host_id > 0 ? $host_id : get_request_var('host_id')));?>'><?php print __('Edit Device.');?></a><br><?php
1542						}
1543						if ($locked) {
1544							?><span class='linkMarker'>*</span><a href='#' class='hyperLink' id='unlockid'><?php print __('Unlock Graph.');?></a><?php
1545						} else {
1546							?><span class='linkMarker'>*</span><a href='#' class='hyperLink' id='lockid'><?php print __('Lock Graph.');?></a><?php
1547						}
1548					?>
1549				</td>
1550			</tr>
1551		</table>
1552		<?php
1553	}
1554
1555	form_start('graphs.php');
1556
1557	html_start_box($header_label, '100%', true, '3', 'center', '');
1558
1559	if (!empty($graph['local_graph_id'])) {
1560		$graph_template_id = get_current_graph_template($graph['local_graph_id']);
1561
1562		$gtsql = get_common_graph_templates($graph);
1563	} else {
1564		$graph_template_id = 0;
1565
1566		$gtsql = 'SELECT gt.id, gt.name
1567			FROM graph_templates AS gt
1568			WHERE id NOT IN (SELECT graph_template_id FROM snmp_query_graph)
1569			ORDER BY name';
1570	}
1571
1572	$form_array = array(
1573		'graph_template_id' => array(
1574			'method' => 'drop_sql',
1575			'friendly_name' => __('Selected Graph Template'),
1576			'description' => __('Choose a Graph Template to apply to this Graph. Please note that you may only change Graph Templates to a 100%% compatible Graph Template, which means that it includes identical Data Sources.'),
1577			'value' => $graph_template_id,
1578			'none_value' => (!isset($graph['graph_template_id']) || $graph['graph_template_id'] == 0 ? __('None'):''),
1579			'sql' => $gtsql
1580  			),
1581		'host_id' => array(
1582			'method' => 'drop_callback',
1583			'friendly_name' => __('Device'),
1584			'description' => __('Choose the Device that this Graph belongs to.'),
1585			'sql' => 'SELECT id, description as name FROM host ORDER BY name',
1586			'action' => 'ajax_hosts_noany',
1587			'none_value' => __('None'),
1588			'id' => $host_id,
1589			'value' => db_fetch_cell_prepared('SELECT description FROM host WHERE id = ?', array($host_id)),
1590			),
1591		'graph_template_graph_id' => array(
1592			'method' => 'hidden',
1593			'value' => (isset($graph['id']) ? $graph['id'] : '0')
1594			),
1595		'local_graph_id' => array(
1596			'method' => 'hidden',
1597			'value' => (isset($graph['local_graph_id']) ? $graph['local_graph_id'] : '0')
1598			),
1599		'local_graph_template_graph_id' => array(
1600			'method' => 'hidden',
1601			'value' => (isset($graph['local_graph_template_graph_id']) ? $graph['local_graph_template_graph_id'] : '0')
1602			),
1603		'graph_template_id_prev' => array(
1604			'method' => 'hidden',
1605			'value' => $graph_template_id
1606			),
1607		'host_id_prev' => array(
1608			'method' => 'hidden',
1609			'value' => (isset($host_id) ? $host_id : '0')
1610			)
1611		);
1612
1613	if (cacti_sizeof($graph)) {
1614		if ($graph['graph_template_id'] == 0) {
1615			$form_array['graph_template_id']['method'] = 'hidden';
1616			$form_array['graph_template_id']['value']  = '0';
1617		}
1618
1619		if ($graph['graph_template_id'] > 0 && $host_id > 0) {
1620			$form_array['graph_template_id']['method'] = 'hidden';
1621			$form_array['host_id']['method'] = 'hidden';
1622		}
1623
1624		if (is_multi_device_graph($graph['local_graph_id'])) {
1625			$form_array['host_id']['method'] = 'hidden';
1626		}
1627	}
1628
1629	draw_edit_form(
1630		array(
1631			'config' => array('no_form_tag' => true),
1632			'fields' => $form_array
1633		)
1634	);
1635
1636	html_end_box(true, true);
1637
1638	/* only display the "inputs" area if we are using a graph template for this graph */
1639	if (!empty($graph['graph_template_id'])) {
1640		html_start_box(__('Supplemental Graph Template Data'), '100%', true, '3', 'center', '');
1641
1642		draw_nontemplated_fields_graph($graph['graph_template_id'], $graph, '|field|', __('Graph Fields'), true, true, 0);
1643		draw_nontemplated_fields_graph_item($graph['graph_template_id'], get_request_var('id'), '|field|_|id|', __('Graph Item Fields'), true, $locked);
1644
1645		html_end_box(true, true);
1646	}
1647
1648	/* graph item list goes here */
1649	if ((!isempty_request_var('id')) && (empty($graph['graph_template_id']))) {
1650		item();
1651	}
1652
1653	$graph_start = -86400;
1654	$graph_end   = '-' . read_config_option('poller_interval');
1655
1656	$graph['src'] = html_escape($config['url_path'] . 'graph_json.php?local_graph_id=' . get_request_var('id') . '&rra_id=0&graph_start=' . $graph_start . '&graph_end=' . $graph_end . '&v=' . mt_rand());
1657
1658	if (!isempty_request_var('id')) {
1659		?>
1660		<div class='cactiTable'>
1661			<div id='graphLocation' class='center'></div>
1662		<?php
1663		if ((isset($_SESSION['graph_debug_mode'])) && (isset_request_var('id'))) {
1664			$graph_data_array['output_flag'] = RRDTOOL_OUTPUT_STDERR;
1665			$graph_data_array['print_source'] = 1;
1666			$graph_data_array['graph_end']    = $graph_end;
1667			$graph_data_array['graph_start']  = $graph_start;
1668
1669			$null_param = array();
1670		?>
1671		</div>
1672		<div class='cactiTable'>
1673			<div style='float:left'>
1674				<span class='textInfo'><?php print __('RRDtool Command:');?></span><br>
1675				<pre><?php print @rrdtool_function_graph(get_request_var('id'), 1, $graph_data_array, '', $null_param, $_SESSION['sess_user_id']);?></pre>
1676				<span class='textInfo'><?php print __('RRDtool Says:');?></span><br>
1677				<?php unset($graph_data_array['print_source']);?>
1678				<pre><?php print ($config['poller_id'] == 1 ? @rrdtool_function_graph(get_request_var('id'), 1, $graph_data_array, '', $null_param, $_SESSION['sess_user_id']):__esc('Not Checked'));?></pre>
1679			</div>
1680		<?php
1681		}
1682		?>
1683		</div>
1684		<br>
1685		<?php
1686	}
1687
1688	if (((isset_request_var('id')) || (isset_request_var('new'))) && (empty($graph['graph_template_id']))) {
1689		html_start_box(__('Graph Configuration'), '100%', true, '3', 'center', '');
1690
1691		$form_array = array();
1692
1693		foreach ($struct_graph as $field_name => $field_array) {
1694			$form_array += array($field_name => $struct_graph[$field_name]);
1695
1696			if (($field_array['method'] != 'header') && ($field_array['method'] != 'spacer' )){
1697				$form_array[$field_name]['value'] = (isset($graph[$field_name]) ? $graph[$field_name] : '');
1698				$form_array[$field_name]['form_id'] = (isset($graph[$field_name]) ? $graph['id'] : '0');
1699
1700				if ($use_graph_template == true && isset($graph_template['t_' . $field_name]) && ($graph_template['t_' . $field_name] == 'on')) {
1701					$form_array[$field_name]['method'] = 'template_' . $form_array[$field_name]['method'];
1702					$form_array[$field_name]['description'] = '';
1703				}
1704			}
1705		}
1706
1707		draw_edit_form(
1708			array(
1709				'config' => array('no_form_tag' => true),
1710				'fields' => $form_array
1711			)
1712		);
1713
1714		html_end_box(true, true);
1715	}
1716
1717	if ((isset_request_var('id')) || (isset_request_var('new'))) {
1718		form_hidden_box('save_component_graph','1','');
1719		form_hidden_box('save_component_input','1','');
1720	} else {
1721		form_hidden_box('save_component_graph_new','1','');
1722	}
1723
1724	form_hidden_box('rrdtool_version', get_rrdtool_version(), '');
1725
1726	form_save_button('graphs.php', 'return');
1727
1728	//Now we need some javascript to make it dynamic
1729	?>
1730	<script type='text/javascript'>
1731
1732	var locked         = <?php print ($locked ? 'true':'false');?>;
1733	var imageSource    = '<?php print $graph['src'];?>';
1734	var originalWidth  = null;
1735	var originalHeight = null;
1736
1737	function dynamic() {
1738		if ($('#scale_log_units').is(':checked')) {
1739			$('#scale_log_units').prop('disabled', true);
1740			if ($('#auto_scale_log').is(':checked')) {
1741				$('#scale_log_units').prop('disabled', false);
1742			}
1743		}
1744	}
1745
1746	function changeScaleLog() {
1747		if ($('#scale_log_units').is(':checked')) {
1748			$('#scale_log_units').prop('disabled', true);
1749			if ($('#auto_scale_log').is(':checked')) {
1750				$('#scale_log_units').prop('disabled', false);
1751			}
1752		}
1753	}
1754
1755	$(function() {
1756		dynamic();
1757
1758		$('#unlockid').click(function(event) {
1759			event.preventDefault;
1760
1761			$('body').append("<div id='modal' class='ui-widget-overlay ui-front' style='z-index: 100;'><i style='position:absolute;top:50%;left:50%;' class='fa fa-spin fa-circle-notch'/></div>");
1762
1763			$.get('graphs.php?action=unlock&header=false&id='+$('#local_graph_id').val())
1764				.done(function(data) {
1765					$('#modal').remove();
1766					$('#main').html(data);
1767					applySkin();
1768				})
1769				.fail(function(data) {
1770					getPresentHTTPError(data);
1771				});
1772		});
1773
1774		$.getJSON(imageSource)
1775			.done(function(data) {
1776				$('#graphLocation').html("<img class='cactiGraphImage' src='data:image/"+data.type+";base64,"+data.image+"' graph_start='"+data.graph_start+"' graph_end='"+data.graph_end+"' graph_left='"+data.graph_left+"' graph_top='"+data.graph_top+"' graph_width='"+data.graph_width+"' graph_height='"+data.graph_height+"' width='"+data.image_width+"' height='"+data.image_height+"' image_width='"+data.image_width+"' image_height='"+data.image_height+"' value_min='"+data.value_min+"' value_max='"+data.value_max+"'>");
1777				$(window).trigger('resize');
1778			})
1779			.fail(function(data) {
1780				getPresentHTTPError(data);
1781			});
1782
1783
1784		$('#lockid').click(function(event) {
1785			event.preventDefault;
1786
1787			loadPageNoHeader('graphs.php?action=lock&header=false&id='+$('#local_graph_id').val());
1788		});
1789
1790		$(window).resize(function() {
1791			imageWidth    = $('.cactiGraphImage').width();
1792			imageHeight   = $('.cactiGraphImage').height();
1793			aspectRatio   = imageWidth/imageHeight;
1794
1795			if (imageWidth > 0 && originalWidth == null) {
1796				originalWidth = imageWidth;
1797				originalHeight = imageHeight;
1798			}
1799
1800			$('.cactiGraphImage').hide();
1801
1802			mainSize      = $('#main').width();
1803
1804			if (imageWidth > mainSize || mainSize < originalWidth) {
1805				newWidth    = mainSize - 40;
1806				aspectRatio = imageWidth / imageHeight;
1807				imageWidth  = newWidth;
1808				imageHeight = newWidth / aspectRatio;
1809				$('.cactiGraphImage').css({ width: imageWidth, height: imageHeight });
1810			} else if (mainSize > originalWidth) {
1811				$('.cactiGraphImage').css({ width: originalWidth, height: originalHeight });
1812			}
1813
1814			$('.cactiGraphImage').show();
1815		}).trigger('resize');
1816
1817		$('.ui-selectmenu-button').css('width', '360px');
1818		$('.ui-autocomplete-input').css('width', '340px');
1819	});
1820
1821	if (locked) {
1822		$('input, select').not('input[value="<?php print __('Cancel');?>"]').prop('disabled', true);
1823		$('.moveArrow, .deleteMarker, .linkOverDark, .linkEditMain').attr('href', '#').removeClass('moveArrow').removeClass('deleteMarker');
1824		if ($('#submit').button('instance')) {
1825			$('#submit').button('disable');
1826		} else {
1827			$('#submit').prop('disabled', true);
1828		}
1829		$('#host_id_wrap').addClass('ui-selectmenu-disabled ui-state-disabled');
1830		$('#host_id_input').addClass('ui-state-disabled');
1831	}
1832	</script>
1833	<?php
1834	if (isset_request_var('id')) {
1835		api_plugin_hook_function('graph_edit_after', get_request_var('id'));
1836	} else {
1837		api_plugin_hook_function('graph_edit_after');
1838	}
1839}
1840
1841function validate_graph_request_vars() {
1842	/* ================= input validation and session storage ================= */
1843	$filters = array(
1844		'rows' => array(
1845			'filter' => FILTER_VALIDATE_INT,
1846			'pageset' => true,
1847			'default' => '-1'
1848			),
1849		'page' => array(
1850			'filter' => FILTER_VALIDATE_INT,
1851			'default' => '1'
1852			),
1853		'rfilter' => array(
1854			'filter' => FILTER_VALIDATE_IS_REGEX,
1855			'pageset' => true,
1856			'default' => '',
1857			),
1858		'orphans' => array(
1859			'filter' => FILTER_CALLBACK,
1860			'default' => '',
1861			'options' => array('options' => 'sanitize_search_string')
1862			),
1863		'sort_column' => array(
1864			'filter' => FILTER_CALLBACK,
1865			'default' => 'title_cache',
1866			'options' => array('options' => 'sanitize_search_string')
1867			),
1868		'sort_direction' => array(
1869			'filter' => FILTER_CALLBACK,
1870			'default' => 'ASC',
1871			'options' => array('options' => 'sanitize_search_string')
1872			),
1873		'host_id' => array(
1874			'filter' => FILTER_VALIDATE_INT,
1875			'pageset' => true,
1876			'default' => '-1'
1877			),
1878		'site_id' => array(
1879			'filter' => FILTER_VALIDATE_INT,
1880			'pageset' => true,
1881			'default' => '-1'
1882			),
1883		'template_id' => array(
1884			'filter' => FILTER_VALIDATE_REGEXP,
1885			'options' => array('options' => array('regexp' => '(cg_[0-9]|dq_[0-9]|[\-0-9])')),
1886			'pageset' => true,
1887			'default' => '-1'
1888			),
1889		'custom' => array(
1890			'filter' => FILTER_VALIDATE_REGEXP,
1891			'options' => array('options' => array('regexp' => '(true|false)')),
1892			'pageset' => true,
1893			'default' => ''
1894			),
1895		'local_graph_ids' => array(
1896			'filter' => FILTER_VALIDATE_IS_NUMERIC_LIST,
1897			'pageset' => true,
1898			'default' => ''
1899			)
1900	);
1901
1902	validate_store_request_vars($filters, 'sess_graph');
1903	/* ================= input validation ================= */
1904}
1905
1906function graph_management() {
1907	global $graph_actions, $graph_sources, $item_rows, $config;
1908
1909	if (get_request_var('rows') == -1) {
1910		$rows = read_config_option('num_rows_table');
1911	} else {
1912		$rows = get_request_var('rows');
1913	}
1914
1915	?>
1916	<script type='text/javascript'>
1917
1918	function applyFilter() {
1919		strURL  = 'graphs.php' +
1920			'?host_id=' + $('#host_id').val() +
1921			'&site_id=' + $('#site_id').val() +
1922			'&rows=' + $('#rows').val() +
1923			'&orphans=' + $('#orphans').is(':checked') +
1924			'&rfilter=' + base64_encode($('#rfilter').val()) +
1925			'&template_id=' + $('#template_id').val() +
1926			'&header=false';
1927		loadPageNoHeader(strURL);
1928	}
1929
1930	function clearFilter() {
1931		strURL = 'graphs.php?clear=1&header=false';
1932		loadPageNoHeader(strURL);
1933	}
1934
1935	$(function() {
1936		$('#clear').unbind().on('click', function() {
1937			clearFilter();
1938		});
1939
1940		$('#filter').unbind().on('change', function() {
1941			applyFilter();
1942		});
1943
1944		$('#form_graphs').unbind().on('submit', function(event) {
1945			event.preventDefault();
1946			applyFilter();
1947		});
1948	});
1949
1950	</script>
1951	<?php
1952
1953	if (read_config_option('grds_creation_method') == 1) {
1954		$add_url = html_escape('graphs.php?action=graph_edit&host_id=' . get_request_var('host_id'));
1955	} else {
1956		$add_url = '';
1957	}
1958
1959	if (get_request_var('local_graph_ids') != '') {
1960		$header = __('Graph Management [ Custom Graphs List Applied - Clear to Reset ]');
1961	} elseif (get_request_var('host_id') == -1) {
1962		$header = __('Graph Management [ All Devices ]');
1963	} elseif (get_request_var('host_id') == 0) {
1964		$header = __('Graph Management [ Non Device Based ]');
1965	} else {
1966		$description = db_fetch_cell_prepared('SELECT description FROM host WHERE id = ?', array(get_request_var('host_id')));
1967		$header = __esc('Graph Management [ %s ]', $description);
1968	}
1969
1970	html_start_box($header, '100%', '', '3', 'center', $add_url);
1971
1972	if (get_request_var('site_id') > 0) {
1973		$host_where = 'site_id = ' . get_request_var('site_id');
1974	} else {
1975		$host_where = '';
1976	}
1977
1978	?>
1979	<tr class='even noprint'>
1980		<td>
1981			<form id='form_graphs' action='graphs.php'>
1982			<table class='filterTable'>
1983				<tr>
1984					<?php print html_site_filter(get_request_var('site_id'));?>
1985					<?php print html_host_filter(get_request_var('host_id'), 'applyFilter', $host_where);?>
1986					<td>
1987						<?php print __('Template');?>
1988					</td>
1989					<td>
1990						<select id='template_id' onChange='applyFilter()'>
1991							<option value='-1'<?php if (get_request_var('template_id') == '-1') {?> selected<?php }?>><?php print __('Any');?></option>
1992							<option value='0'<?php if (get_request_var('template_id') == '0') {?> selected<?php }?>><?php print __('None');?></option>
1993							<?php
1994
1995							// suppress total rows retrieval
1996							$total_rows = -1;
1997
1998							if (get_request_var('host_id') == 0) {
1999								$templates = get_allowed_graph_templates_normalized('gl.host_id=0', 'name', '', $total_rows);
2000							} elseif (get_request_var('host_id') > 0) {
2001								$templates = get_allowed_graph_templates_normalized('gl.host_id=' . get_filter_request_var('host_id'), 'name', '', $total_rows);
2002							} else {
2003								$templates = get_allowed_graph_templates_normalized('', 'name', '', $total_rows);
2004							}
2005
2006							if (cacti_sizeof($templates)) {
2007								foreach ($templates as $template) {
2008									print "<option value='" . $template['id'] . "'"; if (get_request_var('template_id') == $template['id']) { print ' selected'; } print '>' . html_escape($template['name']) . "</option>\n";
2009								}
2010							}
2011							?>
2012						</select>
2013					</td>
2014					<td>
2015						<span>
2016							<input type='checkbox' id='orphans' onChange='applyFilter()' <?php print (get_request_var('orphans') == 'true' || get_request_var('orphans') == 'on' ? 'checked':'');?>>
2017   	                    	<label for='orphans' title='<?php print __esc('Note that this query may take some time to run.');?>'><?php print __('Orphaned');?></label>
2018						</span>
2019					</td>
2020					<td>
2021						<span>
2022							<input type='submit' class='ui-button ui-corner-all ui-widget' id='refresh' value='<?php print __('Go');?>' title='<?php print __esc('Set/Refresh Filters');?>'>
2023							<input type='button' class='ui-button ui-corner-all ui-widget' id='clear' value='<?php print __('Clear');?>' title='<?php print __esc('Clear Filters');?>'>
2024						</span>
2025					</td>
2026				</tr>
2027			</table>
2028			<table class='filterTable'>
2029				<tr>
2030					<td>
2031						<?php print __('Search');?>
2032					</td>
2033					<td>
2034						<input type='text' class='ui-state-default ui-corner-all' id='rfilter' size='30' value='<?php print html_escape_request_var('rfilter');?>'>
2035					</td>
2036					<td>
2037						<?php print __('Graphs');?>
2038					</td>
2039					<td>
2040						<select id='rows' onChange='applyFilter()'>
2041							<option value='-1'<?php print (get_request_var('rows') == '-1' ? ' selected>':'>') . __('Default');?></option>
2042							<?php
2043							if (cacti_sizeof($item_rows)) {
2044								foreach ($item_rows as $key => $value) {
2045									print "<option value='" . $key . "'"; if (get_request_var('rows') == $key) { print ' selected'; } print '>' . html_escape($value) . "</option>\n";
2046								}
2047							}
2048							?>
2049						</select>
2050					</td>
2051				</tr>
2052			</table>
2053			</form>
2054		</td>
2055	</tr>
2056	<?php
2057
2058	html_end_box();
2059
2060	/* form the 'where' clause for our main sql query */
2061	$sql_where  = '';
2062	$sql_where2 = '';
2063	if (get_request_var('rfilter') != '') {
2064		$sql_where = " WHERE (gtg.title_cache RLIKE '" . get_request_var('rfilter') . "'" .
2065			" OR gt.name RLIKE '" . get_request_var('rfilter') . "'" .
2066			" OR gl.id = '" . get_request_var('rfilter') . "')";
2067
2068		$sql_where2 = " AND (gl.id = '" . get_request_var('rfilter') . "')";
2069	}
2070
2071	if (get_request_var('host_id') == '-1') {
2072		/* Show all items */
2073	} elseif (isempty_request_var('host_id')) {
2074		$sql_where2 .= ($sql_where != '' ? ' AND ':'WHERE ') . ' gl.host_id=0';
2075		$sql_where2 .= ' AND gl.host_id=0';
2076	} elseif (!isempty_request_var('host_id')) {
2077		$sql_where  .= ($sql_where != '' ? ' AND ':'WHERE ') . ' gl.host_id=' . get_request_var('host_id');
2078		$sql_where2 .= ' AND gl.host_id=' . get_request_var('host_id');
2079	}
2080
2081	if (get_request_var('site_id') == '-1') {
2082		/* Show all items */
2083	} elseif (isempty_request_var('site_id')) {
2084		$sql_where  .= ($sql_where != '' ? ' AND ':'WHERE ') . ' h.site_id=0';
2085		$sql_where2 .= ' AND h.site_id=0';
2086	} elseif (!isempty_request_var('site_id')) {
2087		$sql_where  .= ($sql_where != '' ? ' AND ':'WHERE ') . ' h.site_id=' . get_request_var('site_id');
2088		$sql_where2 .= ' AND h.site_id=' . get_request_var('site_id');
2089	}
2090
2091	if (get_request_var('template_id') == '-1') {
2092		/* Show all items */
2093	} elseif (get_request_var('template_id') == '0') {
2094		$sql_where  .= ($sql_where != '' ? ' AND ':'WHERE ') . ' gtg.graph_template_id = 0';
2095		$sql_where2 .= ' AND gtg.graph_template_id = 0';
2096	} elseif (!isempty_request_var('template_id')) {
2097		$parts = explode('_', get_request_var('template_id'));
2098		if ($parts[0] == 'cg') {
2099			input_validate_input_number($parts[1]);
2100			$sql_where  .= ($sql_where != '' ? ' AND ':'WHERE ') . ' gl.graph_template_id = ' . $parts[1];
2101			$sql_where2 .= ' AND gl.graph_template_id = ' . $parts[1];
2102		} else {
2103			input_validate_input_number($parts[1]);
2104			$sql_where  .= ($sql_where != '' ? ' AND ':'WHERE ') . ' gl.snmp_query_graph_id = ' . $parts[1];
2105			$sql_where2 .= ' AND gl.snmp_query_graph_id = ' . $parts[1];
2106		}
2107	}
2108
2109	if (get_request_var('local_graph_ids') != '') {
2110		$sql_where  .= ($sql_where != '' ? ' AND ':'WHERE ') . ' gl.id IN(' . get_request_var('local_graph_ids') . ')';
2111		$sql_where2 .= ' AND gl.id IN(' . get_request_var('local_graph_ids') . ')';
2112	}
2113
2114	if (get_request_var('orphans') == 'true') {
2115		$orphan_join = "INNER JOIN (
2116			SELECT DISTINCT gti.local_graph_id, dtr.local_data_id
2117			FROM graph_templates_item AS gti
2118			INNER JOIN graph_local AS gl
2119			ON gl.id = gti.local_graph_id
2120			LEFT JOIN data_template_rrd AS dtr
2121			ON dtr.id = gti.task_item_id
2122			LEFT JOIN host AS h
2123			ON h.id = gl.host_id
2124			WHERE graph_type_id IN (4,5,6,7,8,20)
2125			AND cdef_id NOT IN (
2126				SELECT c.id
2127				FROM cdef AS c
2128				INNER JOIN cdef_items AS ci
2129				ON c.id = ci.cdef_id
2130				WHERE (ci.type = 4 OR (ci.type = 6 AND value LIKE '%DATA_SOURCE%'))
2131			)
2132			AND (dtr.id IS NULL OR (gl.snmp_query_id > 0 AND gl.snmp_index = ''))
2133			$sql_where2
2134		) AS dtr
2135		ON gl.id = dtr.local_graph_id";
2136	} else {
2137		$orphan_join = '';
2138	}
2139
2140	/* don't allow aggregates to be view here */
2141	$sql_where .= ($sql_where != '' ? ' AND ':'WHERE ') . ' ag.local_graph_id IS NULL';
2142
2143	/* allow plugins to modify sql_where */
2144	$sql_where = api_plugin_hook_function('graphs_sql_where', $sql_where);
2145
2146	$total_rows = db_fetch_cell("SELECT
2147		COUNT(gtg.id)
2148		FROM graph_local AS gl
2149		INNER JOIN graph_templates_graph AS gtg
2150		ON gl.id=gtg.local_graph_id
2151		LEFT JOIN graph_templates AS gt
2152		ON gl.graph_template_id=gt.id
2153		LEFT JOIN aggregate_graphs AS ag
2154		ON ag.local_graph_id=gl.id
2155		LEFT JOIN host AS h
2156		ON h.id=gl.host_id
2157		LEFT JOIN sites AS s
2158		ON h.site_id=s.id
2159		$orphan_join
2160		$sql_where");
2161
2162	$sql_order = get_order_string();
2163	$sql_limit = ' LIMIT ' . ($rows*(get_request_var('page')-1)) . ',' . $rows;
2164
2165	$graph_list = db_fetch_assoc("SELECT gtg.id, gl.id AS local_graph_id,
2166		gtg.height, gtg.width, gtg.title_cache, gt.name, gl.host_id,
2167		IF(gl.graph_template_id=0, 0, IF(gl.snmp_query_id=0, 2, 1)) AS graph_source
2168		FROM graph_local AS gl
2169		INNER JOIN graph_templates_graph AS gtg
2170		ON gl.id=gtg.local_graph_id
2171		LEFT JOIN graph_templates AS gt
2172		ON gl.graph_template_id=gt.id
2173		LEFT JOIN aggregate_graphs AS ag
2174		ON ag.local_graph_id=gl.id
2175		LEFT JOIN host AS h
2176		ON h.id=gl.host_id
2177		LEFT JOIN sites AS s
2178		ON h.site_id=s.id
2179		$orphan_join
2180		$sql_where
2181		$sql_order
2182		$sql_limit");
2183
2184	$nav = html_nav_bar('graphs.php', MAX_DISPLAY_PAGES, get_request_var('page'), $rows, $total_rows, 5, __('Graphs'), 'page', 'main');
2185
2186	form_start('graphs.php', 'chk');
2187
2188	print $nav;
2189
2190	html_start_box('', '100%', '', '3', 'center', '');
2191
2192	$display_text = array(
2193		'title_cache' => array(
2194			'display' => __('Graph Name'),
2195			'align'   => 'left',
2196			'sort'    => 'ASC',
2197			'tip'     => __('The Title of this Graph.  Generally programatically generated from the Graph Template definition or Suggested Naming rules.  The max length of the Title is controlled under Settings->Visual.')
2198		),
2199		'local_graph_id' => array(
2200			'display' => __('ID'),
2201			'align'   => 'right',
2202			'sort'    => 'ASC',
2203			'tip'     => __('The internal database ID for this Graph.  Useful when performing automation or debugging.')
2204		),
2205		'nosort_source' => array(
2206			'display' => __('Source Type'),
2207			'align'   => 'center',
2208			'sort'    => 'ASC',
2209			'tip'     => __('The underlying source that this Graph was based upon.')
2210		),
2211		'nosort_name' => array(
2212			'display' => __('Source Name'),
2213			'align'   => 'left',
2214			'sort'    => 'ASC',
2215			'tip'     => __('The Graph Template or Data Query that this Graph was based upon.')
2216		),
2217		'height' => array(
2218			'display' => __('Size'),
2219			'align'   => 'right',
2220			'sort'    => 'ASC',
2221			'tip'     => __('The size of this Graph when not in Preview mode.')
2222		)
2223	);
2224
2225	html_header_sort_checkbox($display_text, get_request_var('sort_column'), get_request_var('sort_direction'), false);
2226
2227	$i = 0;
2228	if (cacti_sizeof($graph_list)) {
2229		foreach ($graph_list as $graph) {
2230			/* we're escaping strings here, so no need to escape them on form_selectable_cell */
2231			$template_details = get_graph_template_details($graph['local_graph_id']);
2232
2233			if($graph['graph_source'] == '0') { //Not Templated, customize graph source and template details.
2234				$template_details = api_plugin_hook_function('customize_template_details', $template_details);
2235				$graph = api_plugin_hook_function('customize_graph', $graph);
2236			}
2237
2238			if (isset($template_details['graph_name'])) {
2239				$graph['name'] = $template_details['graph_name'];
2240			}
2241
2242			if (isset($template_details['graph_description'])) {
2243				$graph['description'] = $template_details['graph_description'];
2244			}
2245
2246			if (empty($graph['title_cache'])) {
2247				$graph['title_cache'] = __('Empty Graph');
2248			}
2249
2250			form_alternate_row('line' . $graph['local_graph_id'], true);
2251			form_selectable_cell(filter_value(title_trim($graph['title_cache'], read_config_option('max_title_length')), get_request_var('rfilter'), 'graphs.php?action=graph_edit&id=' . $graph['local_graph_id']), $graph['local_graph_id']);
2252			form_selectable_cell($graph['local_graph_id'], $graph['local_graph_id'], '', 'right');
2253			form_selectable_cell(filter_value($graph_sources[$graph['graph_source']], get_request_var('rfilter')), $graph['local_graph_id'], '', 'center');
2254			form_selectable_cell(filter_value($template_details['name'], get_request_var('rfilter'), $template_details['url']), $graph['local_graph_id'], '', 'left');
2255			form_selectable_ecell($graph['height'] . 'x' . $graph['width'], $graph['local_graph_id'], '', 'right');
2256			form_checkbox_cell($graph['title_cache'], $graph['local_graph_id']);
2257			form_end_row();
2258		}
2259	} else {
2260		print "<tr class='tableRow'><td colspan='" . (cacti_sizeof($display_text)+1) . "'><em>" . __('No Graphs Found') . "</em></td></tr>";
2261	}
2262
2263	html_end_box(false);
2264
2265	if (cacti_sizeof($graph_list)) {
2266		print $nav;
2267	}
2268
2269	/* add a list of tree names to the actions dropdown */
2270	add_tree_names_to_actions_array();
2271
2272	/* draw the dropdown containing a list of available actions for this form */
2273	draw_actions_dropdown($graph_actions);
2274
2275	form_end();
2276}
2277