1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (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** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22/**
23 * @var CView $this
24 */
25
26$widget = new CWidget();
27
28if ($data['parent_discoveryid'] === null) {
29	$widget
30		->setTitle(_('Graphs'))
31		->addItem(get_header_host_table('graphs', $data['hostid']));
32}
33else {
34	$widget
35		->setTitle(_('Graph prototypes'))
36		->addItem(get_header_host_table('graphs', $data['hostid'], $data['parent_discoveryid']));
37}
38
39// Create form.
40$graphForm = (new CForm())
41	->setName('graphForm')
42	->setAttribute('aria-labeledby', ZBX_STYLE_PAGE_TITLE)
43	->addVar('form', $this->data['form'])
44	->addVar('hostid', $this->data['hostid'])
45	->addVar('ymin_itemid', $this->data['ymin_itemid'])
46	->addVar('ymax_itemid', $this->data['ymax_itemid']);
47
48if ($data['parent_discoveryid'] !== null) {
49	$graphForm->addItem((new CVar('parent_discoveryid', $data['parent_discoveryid']))->removeId());
50}
51
52if ($data['graphid'] != 0) {
53	$graphForm->addVar('graphid', $data['graphid']);
54}
55
56// Create form list.
57$graphFormList = new CFormList('graphFormList');
58
59$is_templated = (bool) $this->data['templates'];
60if ($is_templated) {
61	$graphFormList->addRow(_('Parent graphs'), $data['templates']);
62}
63
64$discovered_graph = false;
65if (array_key_exists('flags', $data) && $data['flags'] == ZBX_FLAG_DISCOVERY_CREATED) {
66	$discovered_graph = true;
67}
68
69$readonly = false;
70if ($is_templated || $discovered_graph) {
71	$readonly = true;
72}
73
74if ($discovered_graph) {
75	$graphFormList->addRow(_('Discovered by'), new CLink($data['discoveryRule']['name'],
76		(new CUrl('graphs.php'))
77			->setArgument('form', 'update')
78			->setArgument('parent_discoveryid', $data['discoveryRule']['itemid'])
79			->setArgument('graphid', $data['graphDiscovery']['parent_graphid'])
80	));
81}
82
83$graphFormList
84	->addRow(
85		(new CLabel(_('Name'), 'name'))->setAsteriskMark(),
86		(new CTextBox('name', $this->data['name'], $readonly))
87			->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
88			->setAriaRequired()
89			->setAttribute('autofocus', 'autofocus')
90	)
91	->addRow((new CLabel(_('Width'), 'width'))->setAsteriskMark(),
92		(new CNumericBox('width', $this->data['width'], 5, $readonly))
93			->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH)
94			->setAriaRequired()
95	)
96	->addRow((new CLabel(_('Height'), 'height'))->setAsteriskMark(),
97		(new CNumericBox('height', $this->data['height'], 5, $readonly))
98			->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH)
99			->setAriaRequired()
100	)
101	->addRow((new CLabel(_('Graph type'), 'label-graphtype')),
102		(new CSelect('graphtype'))
103			->setId('graphtype')
104			->setFocusableElementId('label-graphtype')
105			->setValue($this->data['graphtype'])
106			->addOptions(CSelect::createOptionsFromArray(graphType()))
107			->setDisabled($readonly)
108	)
109	->addRow(_('Show legend'),
110		(new CCheckBox('show_legend'))
111			->setChecked($this->data['show_legend'] == 1)
112			->setEnabled(!$readonly)
113	);
114
115// Append graph types to form list.
116if ($this->data['graphtype'] == GRAPH_TYPE_NORMAL || $this->data['graphtype'] == GRAPH_TYPE_STACKED) {
117	$graphFormList->addRow(_('Show working time'),
118		(new CCheckBox('show_work_period'))
119			->setChecked($this->data['show_work_period'] == 1)
120			->setEnabled(!$readonly)
121	);
122	$graphFormList->addRow(_('Show triggers'),
123		(new CCheckbox('show_triggers'))
124			->setchecked($this->data['show_triggers'] == 1)
125			->setEnabled(!$readonly)
126	);
127
128	if ($this->data['graphtype'] == GRAPH_TYPE_NORMAL) {
129		// Percent left.
130		$percentLeftTextBox = (new CTextBox('percent_left', $this->data['percent_left'], $readonly, 7))
131			->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
132		$percentLeftCheckbox = (new CCheckBox('visible[percent_left]'))
133			->setChecked(true)
134			->onClick('javascript: showHideVisible("percent_left");')
135			->setEnabled(!$readonly);
136
137		if(isset($this->data['visible']) && isset($this->data['visible']['percent_left'])) {
138			$percentLeftCheckbox->setChecked(true);
139		}
140		elseif ($this->data['percent_left'] == 0) {
141			$percentLeftTextBox->addStyle('visibility: hidden;');
142			$percentLeftCheckbox->setChecked(false);
143		}
144
145		$graphFormList->addRow(_('Percentile line (left)'), [$percentLeftCheckbox, SPACE, $percentLeftTextBox]);
146
147		// Percent right.
148		$percentRightTextBox = (new CTextBox('percent_right', $this->data['percent_right'], $readonly, 7))
149			->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
150		$percentRightCheckbox = (new CCheckBox('visible[percent_right]'))
151			->setChecked(true)
152			->onClick('javascript: showHideVisible("percent_right");')
153			->setEnabled(!$readonly);
154
155		if(isset($this->data['visible']) && isset($this->data['visible']['percent_right'])) {
156			$percentRightCheckbox->setChecked(true);
157		}
158		elseif ($this->data['percent_right'] == 0) {
159			$percentRightTextBox->addStyle('visibility: hidden;');
160			$percentRightCheckbox->setChecked(false);
161		}
162
163		$graphFormList->addRow(_('Percentile line (right)'), [$percentRightCheckbox, SPACE, $percentRightTextBox]);
164	}
165
166	$yaxisMinData = [];
167	$yaxisMinData[] = (new CSelect('ymin_type'))
168		->setId('ymin_type')
169		->setValue($this->data['ymin_type'])
170		->addOptions(CSelect::createOptionsFromArray([
171			GRAPH_YAXIS_TYPE_CALCULATED => _('Calculated'),
172			GRAPH_YAXIS_TYPE_FIXED => _('Fixed'),
173			GRAPH_YAXIS_TYPE_ITEM_VALUE => _('Item')
174		]))
175		->setDisabled($readonly);
176
177	if ($this->data['ymin_type'] == GRAPH_YAXIS_TYPE_FIXED) {
178		$yaxisMinData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
179		$yaxisMinData[] = (new CTextBox('yaxismin', $this->data['yaxismin'], $readonly))
180			->setWidth(ZBX_TEXTAREA_SMALL_WIDTH);
181	}
182	elseif ($this->data['ymin_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) {
183		$graphForm->addVar('yaxismin', $this->data['yaxismin']);
184
185		$ymin_name = '';
186		if (!empty($this->data['ymin_itemid'])) {
187			$min_host = get_host_by_itemid($this->data['ymin_itemid']);
188
189			$minItems = CMacrosResolverHelper::resolveItemNames([get_item_by_itemid($this->data['ymin_itemid'])]);
190			$minItem = reset($minItems);
191
192			$ymin_name = $min_host['name'].NAME_DELIMITER.$minItem['name_expanded'];
193		}
194
195		$yaxisMinData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
196		$yaxisMinData[] = (new CTextBox('ymin_name', $ymin_name, true))
197			->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
198			->setAriaRequired();
199		$yaxisMinData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
200
201		// Select item button.
202		$yaxisMinData[] = (new CButton('yaxis_min', _('Select')))
203			->addClass(ZBX_STYLE_BTN_GREY)
204			->onClick('return PopUp("popup.generic",jQuery.extend('.
205				json_encode([
206					'srctbl' => 'items',
207					'srcfld1' => 'itemid',
208					'srcfld2' => 'name',
209					'dstfrm' => $graphForm->getName(),
210					'dstfld1' => 'ymin_itemid',
211					'dstfld2' => 'ymin_name',
212					'with_webitems' => '1',
213					'numeric' => '1',
214					'writeonly' => '1'
215				]).
216					',getOnlyHostParam()), null, this);'
217			)
218			->setEnabled(!$readonly);
219
220		// Select item prototype button.
221		if ($data['parent_discoveryid'] !== null) {
222			$yaxisMinData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
223			$yaxisMinData[] = (new CButton('yaxis_min_prototype', _('Select prototype')))
224				->addClass(ZBX_STYLE_BTN_GREY)
225				->onClick('return PopUp("popup.generic",'.
226					json_encode([
227						'srctbl' => 'item_prototypes',
228						'srcfld1' => 'itemid',
229						'srcfld2' => 'name',
230						'dstfrm' => $graphForm->getName(),
231						'dstfld1' => 'ymin_itemid',
232						'dstfld2' => 'ymin_name',
233						'parent_discoveryid' => $data['parent_discoveryid'],
234						'numeric' => '1'
235					]).', null, this);'
236				)
237				->setEnabled(!$readonly);
238		}
239	}
240	else {
241		$graphForm->addVar('yaxismin', $this->data['yaxismin']);
242	}
243
244	$yaxismin_label = new CLabel(_('Y axis MIN value'));
245	if ($this->data['ymin_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) {
246		$yaxismin_label
247			->setAsteriskMark()
248			->setAttribute('for', 'ymin_name');
249	}
250
251	$graphFormList->addRow($yaxismin_label, $yaxisMinData);
252
253	$yaxisMaxData = [];
254	$yaxisMaxData[] = (new CSelect('ymax_type'))
255		->setId('ymax_type')
256		->setValue($this->data['ymax_type'])
257		->addOptions(CSelect::createOptionsFromArray([
258			GRAPH_YAXIS_TYPE_CALCULATED => _('Calculated'),
259			GRAPH_YAXIS_TYPE_FIXED => _('Fixed'),
260			GRAPH_YAXIS_TYPE_ITEM_VALUE => _('Item')
261		]))
262		->setDisabled($readonly);
263
264	if ($this->data['ymax_type'] == GRAPH_YAXIS_TYPE_FIXED) {
265		$yaxisMaxData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
266		$yaxisMaxData[] = (new CTextBox('yaxismax', $this->data['yaxismax'], $readonly))
267			->setWidth(ZBX_TEXTAREA_SMALL_WIDTH);
268	}
269	elseif ($this->data['ymax_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) {
270		$graphForm->addVar('yaxismax', $this->data['yaxismax']);
271
272		$ymax_name = '';
273		if (!empty($this->data['ymax_itemid'])) {
274			$max_host = get_host_by_itemid($this->data['ymax_itemid']);
275
276			$maxItems = CMacrosResolverHelper::resolveItemNames([get_item_by_itemid($this->data['ymax_itemid'])]);
277			$maxItem = reset($maxItems);
278
279			$ymax_name = $max_host['name'].NAME_DELIMITER.$maxItem['name_expanded'];
280		}
281
282		$yaxisMaxData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
283		$yaxisMaxData[] = (new CTextBox('ymax_name', $ymax_name, true))
284			->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
285			->setAriaRequired();
286		$yaxisMaxData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
287
288		// Select item button.
289		$yaxisMaxData[] = (new CButton('yaxis_max', _('Select')))
290			->addClass(ZBX_STYLE_BTN_GREY)
291			->onClick('return PopUp("popup.generic",jQuery.extend('.
292				json_encode([
293					'srctbl' => 'items',
294					'srcfld1' => 'itemid',
295					'srcfld2' => 'name',
296					'dstfrm' => $graphForm->getName(),
297					'dstfld1' => 'ymax_itemid',
298					'dstfld2' => 'ymax_name',
299					'with_webitems' => '1',
300					'numeric' => '1',
301					'writeonly' => '1'
302				]).
303					',getOnlyHostParam()), null, this);'
304			)
305			->setEnabled(!$readonly);
306
307		// Select item prototype button.
308		if ($data['parent_discoveryid'] !== null) {
309			$yaxisMaxData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
310			$yaxisMaxData[] = (new CButton('yaxis_max_prototype', _('Select prototype')))
311				->addClass(ZBX_STYLE_BTN_GREY)
312				->onClick('return PopUp("popup.generic",'.
313					json_encode([
314						'srctbl' => 'item_prototypes',
315						'srcfld1' => 'itemid',
316						'srcfld2' => 'name',
317						'dstfrm' => $graphForm->getName(),
318						'dstfld1' => 'ymax_itemid',
319						'dstfld2' => 'ymax_name',
320						'parent_discoveryid' => $data['parent_discoveryid'],
321						'numeric' => '1'
322					]).', null, this);'
323				)
324				->setEnabled(!$readonly);
325		}
326	}
327	else {
328		$graphForm->addVar('yaxismax', $this->data['yaxismax']);
329	}
330
331	$yaxismax_label = new CLabel(_('Y axis MAX value'));
332	if ($this->data['ymax_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) {
333		$yaxismax_label
334			->setAsteriskMark()
335			->setAttribute('for', 'ymax_name');
336	}
337
338	$graphFormList->addRow($yaxismax_label, $yaxisMaxData);
339}
340else {
341	$graphFormList->addRow(_('3D view'),
342		(new CCheckBox('show_3d'))
343			->setChecked($this->data['show_3d'] == 1)
344			->setEnabled(!$readonly)
345	);
346}
347
348// Append items to form list.
349$items_table = (new CTable())
350	->setId('itemsTable')
351	->setColumns([
352		(new CTableColumn())->addClass('table-col-handle'),
353		(new CTableColumn())->addClass('table-col-no'),
354		(new CTableColumn(_('Name')))->addClass(($this->data['graphtype'] == GRAPH_TYPE_NORMAL)
355			? 'table-col-name-normal'
356			: 'table-col-name'
357		),
358		in_array($this->data['graphtype'], [GRAPH_TYPE_PIE, GRAPH_TYPE_EXPLODED])
359			? (new CTableColumn(_('Type')))->addClass('table-col-type')
360			: null,
361		(new CTableColumn(_('Function')))->addClass('table-col-function'),
362		($this->data['graphtype'] == GRAPH_TYPE_NORMAL)
363			? (new CTableColumn(
364				(new CColHeader(_('Draw style')))->addClass(ZBX_STYLE_NOWRAP)
365			))
366				->addClass('table-col-draw-style')
367			: null,
368		in_array($this->data['graphtype'], [GRAPH_TYPE_NORMAL, GRAPH_TYPE_STACKED])
369			? (new CTableColumn(
370				(new CColHeader(_('Y axis side')))->addClass(ZBX_STYLE_NOWRAP)
371			))
372				->addClass('table-col-y-axis-side')
373			: null,
374		(new CTableColumn(_('Colour')))->addClass('table-col-colour'),
375		$readonly ? null : (new CTableColumn(_('Action')))->addClass('table-col-action')
376	]);
377
378$popup_options_add = [
379	'srctbl' => 'items',
380	'srcfld1' => 'itemid',
381	'srcfld2' => 'name',
382	'dstfrm' => $graphForm->getName(),
383	'numeric' => '1',
384	'writeonly' => '1',
385	'multiselect' => '1',
386	'with_webitems' => '1'
387];
388if ($data['normal_only']) {
389	$popup_options_add['normal_only'] = '1';
390}
391if ($data['hostid']) {
392	$popup_options_add['hostid'] = $data['hostid'];
393}
394
395$popup_options_add_prototype = [
396	'srctbl' => 'item_prototypes',
397	'srcfld1' => 'itemid',
398	'srcfld2' => 'name',
399	'dstfrm' => $graphForm->getName(),
400	'numeric' => '1',
401	'writeonly' => '1',
402	'multiselect' => '1',
403	'graphtype' => $data['graphtype']
404];
405if ($data['normal_only']) {
406	$popup_options_add_prototype['normal_only'] = '1';
407}
408if ($data['parent_discoveryid']) {
409	$popup_options_add_prototype['parent_discoveryid'] = $data['parent_discoveryid'];
410}
411
412$items_table->addRow(
413	(new CRow(
414		$readonly
415			? null
416			: (new CCol(
417				new CHorList([
418					(new CButton('add_item', _('Add')))
419						->onClick('return PopUp("popup.generic",jQuery.extend('.
420							json_encode($popup_options_add).',getOnlyHostParam()), null, this);'
421						)
422						->addClass(ZBX_STYLE_BTN_LINK),
423					$data['parent_discoveryid']
424						? (new CButton('add_protoitem', _('Add prototype')))
425							->onClick('return PopUp("popup.generic",'.
426								json_encode($popup_options_add_prototype).', null, this);'
427							)
428							->addClass(ZBX_STYLE_BTN_LINK)
429						: null
430				])
431			))->setColSpan(8)
432	))->setId('itemButtonsRow')
433);
434
435foreach ($this->data['items'] as $n => $item) {
436	$name = $item['host'].NAME_DELIMITER.$item['name_expanded'];
437
438	if (zbx_empty($item['drawtype'])) {
439		$item['drawtype'] = 0;
440	}
441
442	if (zbx_empty($item['yaxisside'])) {
443		$item['yaxisside'] = 0;
444	}
445
446	if (!array_key_exists('gitemid', $item)) {
447		$item['gitemid'] = '';
448	}
449
450	insert_js('loadItem('.$n.', '.json_encode($item['gitemid']).', '.$item['itemid'].', '.
451		json_encode($name).', '.$item['type'].', '.$item['calc_fnc'].', '.$item['drawtype'].', '.
452		$item['yaxisside'].', \''.$item['color'].'\', '.$item['flags'].');',
453		true
454	);
455}
456
457$graphFormList->addRow(
458	(new CLabel(_('Items'), $items_table->getId()))->setAsteriskMark(),
459	(new CDiv($items_table))->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
460);
461
462if ($data['parent_discoveryid']) {
463	$graphFormList->addRow(_('Discover'),
464		(new CCheckBox('discover', ZBX_PROTOTYPE_DISCOVER))
465			->setChecked($data['discover'] == ZBX_PROTOTYPE_DISCOVER)
466			->setUncheckedValue(ZBX_PROTOTYPE_NO_DISCOVER)
467	);
468}
469
470// Append tabs to form.
471$graphTab = (new CTabView())
472	->setSelected(0)
473	->addTab('graphTab', ($data['parent_discoveryid'] === null) ? _('Graph') : _('Graph prototype'), $graphFormList);
474
475/*
476 * Preview tab
477 */
478$graphPreviewTable = (new CTable())
479	->addStyle('width: 100%;')
480	->addRow(
481		(new CRow(
482			(new CDiv())->setId('previewChart')
483		))->addClass(ZBX_STYLE_CENTER)
484	);
485$graphTab->addTab('previewTab', _('Preview'), $graphPreviewTable);
486
487// Append buttons to form.
488if ($data['graphid'] != 0) {
489	$updateButton = new CSubmit('update', _('Update'));
490	$deleteButton = new CButtonDelete(
491		($data['parent_discoveryid'] === null) ? _('Delete graph?') : _('Delete graph prototype?'),
492		url_params(['graphid', 'parent_discoveryid', 'hostid'])
493	);
494
495	if ($readonly) {
496		$updateButton->setEnabled(false);
497	}
498
499	if ($is_templated) {
500		$deleteButton->setEnabled(false);
501	}
502
503	$graphTab->setFooter(makeFormFooter(
504		$updateButton, [
505			new CSubmit('clone', _('Clone')),
506			$deleteButton,
507			new CButtonCancel(url_param('parent_discoveryid').url_param('hostid', $this->data['hostid']))
508		]
509	));
510}
511else {
512	$graphTab->setFooter(makeFormFooter(
513		new CSubmit('add', _('Add')),
514		[new CButtonCancel(url_param('parent_discoveryid').url_param('hostid', $this->data['hostid']))]
515	));
516}
517
518$graph_item_drawtypes = [];
519foreach (graph_item_drawtypes() as $drawtype) {
520	$graph_item_drawtypes[$drawtype] = graph_item_drawtype2str($drawtype);
521}
522
523// Insert js (depended from some variables inside the file).
524require_once dirname(__FILE__).'/js/configuration.graph.edit.js.php';
525
526$graphForm->addItem($graphTab);
527
528// Append form to widget.
529$widget->addItem($graphForm);
530
531$widget->show();
532