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