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
26require_once dirname(__FILE__).'/js/configuration.triggers.edit.js.php';
27
28$widget = (new CWidget())->setTitle(_('Triggers'));
29
30// Append host summary to widget header.
31if ($data['hostid'] != 0) {
32	$widget->addItem(get_header_host_table('triggers', $data['hostid']));
33}
34
35// Create form.
36$triggersForm = (new CForm())
37	->setName('triggersForm')
38	->setAttribute('aria-labeledby', ZBX_STYLE_PAGE_TITLE)
39	->addVar('form', $data['form'])
40	->addVar('hostid', $data['hostid'])
41	->addVar('expression_constructor', $data['expression_constructor'])
42	->addVar('recovery_expression_constructor', $data['recovery_expression_constructor'])
43	->addVar('toggle_expression_constructor', '')
44	->addVar('toggle_recovery_expression_constructor', '')
45	->addVar('remove_expression', '')
46	->addVar('remove_recovery_expression', '');
47
48$discovered_trigger = false;
49
50if ($data['triggerid'] !== null) {
51	$triggersForm->addVar('triggerid', $data['triggerid']);
52
53	if ($data['flags'] == ZBX_FLAG_DISCOVERY_CREATED) {
54		$discovered_trigger = true;
55	}
56}
57
58$readonly = ($data['limited'] || $discovered_trigger);
59
60if ($readonly) {
61	$triggersForm
62		->addItem((new CVar('opdata', $data['opdata']))->removeId())
63		->addItem((new CVar('recovery_mode', $data['recovery_mode']))->removeId())
64		->addItem((new CVar('type', $data['type']))->removeId())
65		->addItem((new CVar('correlation_mode', $data['correlation_mode']))->removeId())
66		->addItem((new CVar('manual_close', $data['manual_close']))->removeId());
67}
68
69// Create form list.
70$triggersFormList = new CFormList('triggersFormList');
71if (!empty($data['templates'])) {
72	$triggersFormList->addRow(_('Parent triggers'), $data['templates']);
73}
74
75if ($discovered_trigger) {
76	$triggersFormList->addRow(_('Discovered by'), new CLink($data['discoveryRule']['name'],
77		(new CUrl('trigger_prototypes.php'))
78			->setArgument('form', 'update')
79			->setArgument('parent_discoveryid', $data['discoveryRule']['itemid'])
80			->setArgument('triggerid', $data['triggerDiscovery']['parent_triggerid'])
81	));
82}
83
84$triggersFormList
85	->addRow(
86		(new CLabel(_('Name'), 'description'))->setAsteriskMark(),
87		(new CTextBox('description', $data['description'], $readonly))
88			->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
89			->setAriaRequired()
90			->setAttribute('autofocus', 'autofocus')
91	)
92	->addRow(
93		new CLabel(_('Operational data'), 'opdata'),
94		(new CTextBox('opdata', $data['opdata'], $readonly))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
95	);
96
97if ($discovered_trigger) {
98	$triggersFormList->addVar('priority', (int) $data['priority']);
99	$severity = new CSeverity(['name' => 'priority_names', 'value' => (int) $data['priority']], false);
100}
101else {
102	$severity = new CSeverity(['name' => 'priority', 'value' => (int) $data['priority']]);
103}
104
105$triggersFormList->addRow(_('Severity'), $severity);
106
107// Append expression to form list.
108if ($data['expression_field_readonly']) {
109	$triggersForm->addItem((new CVar('expression', $data['expression']))->removeId());
110}
111
112if ($data['recovery_expression_field_readonly']) {
113	$triggersForm->addItem((new CVar('recovery_expression', $data['recovery_expression']))->removeId());
114}
115
116$popup_options = [
117	'srctbl' => $data['expression_field_name'],
118	'srcfld1' => $data['expression_field_name'],
119	'dstfrm' => $triggersForm->getName(),
120	'dstfld1' => $data['expression_field_name']
121];
122
123if ($data['hostid']) {
124	$popup_options['hostid'] = $data['hostid'];
125}
126
127$expression_row = [
128	(new CTextArea(
129		$data['expression_field_name'],
130		$data['expression_field_value'],
131		['readonly' => $data['expression_field_readonly']]
132	))
133		->addClass(ZBX_STYLE_MONOSPACE_FONT)
134		->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
135		->setAriaRequired(),
136	(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
137	(new CButton('insert', ($data['expression_constructor'] == IM_TREE) ? _('Edit') : _('Add')))
138		->addClass(ZBX_STYLE_BTN_GREY)
139		->onClick('return PopUp("popup.triggerexpr",jQuery.extend('.json_encode($popup_options).
140			',{expression: jQuery(\'[name="'.$data['expression_field_name'].'"]\').val()}), null, this);'
141		)
142		->setEnabled(!$readonly)
143		->removeId()
144];
145
146if ($data['expression_constructor'] == IM_TREE) {
147	// Append "Insert expression" button.
148	$expression_row[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
149	$expression_row[] = (new CButton('insert_macro', _('Insert expression')))
150		->addClass(ZBX_STYLE_BTN_GREY)
151		->setMenuPopup(CMenuPopupHelper::getTriggerMacro())
152		->setEnabled(!$readonly);
153	$expression_row[] = BR();
154
155	if ($data['expression_formula'] === '') {
156		// Append "Add" button.
157		$expression_row[] = (new CSimpleButton(_('Add')))
158			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "add_expression", "1");')
159			->addClass(ZBX_STYLE_BTN_GREY)
160			->setEnabled(!$readonly);
161	}
162	else {
163		// Append "And" button.
164		$expression_row[] = (new CSimpleButton(_('And')))
165			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "and_expression", "1");')
166			->addClass(ZBX_STYLE_BTN_GREY)
167			->setEnabled(!$readonly);
168
169		// Append "Or" button.
170		$expression_row[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
171		$expression_row[] = (new CSimpleButton(_('Or')))
172			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "or_expression", "1");')
173			->addClass(ZBX_STYLE_BTN_GREY)
174			->setEnabled(!$readonly);
175
176		// Append "Replace" button.
177		$expression_row[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
178		$expression_row[] = (new CSimpleButton(_('Replace')))
179			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "replace_expression", "1");')
180			->addClass(ZBX_STYLE_BTN_GREY)
181			->setEnabled(!$readonly);
182	}
183}
184elseif ($data['expression_constructor'] != IM_FORCED) {
185	$input_method_toggle = (new CSimpleButton(_('Expression constructor')))
186		->addClass(ZBX_STYLE_BTN_LINK)
187		->onClick('javascript: '.
188			'document.getElementById("toggle_expression_constructor").value=1;'.
189			'document.getElementById("expression_constructor").value='.
190				(($data['expression_constructor'] == IM_TREE) ? IM_ESTABLISHED : IM_TREE).';'.
191			'document.forms["'.$triggersForm->getName().'"].submit();');
192	$expression_row[] = [BR(), $input_method_toggle];
193}
194
195$triggersFormList->addRow(
196	(new CLabel(_('Expression'), $data['expression_field_name']))->setAsteriskMark(),
197	$expression_row,
198	'expression_row'
199);
200
201// Append expression table to form list.
202if ($data['expression_constructor'] == IM_TREE) {
203	$expression_table = (new CTable())
204		->setAttribute('style', 'width: 100%;')
205		->setHeader([
206			$readonly ? null : _('Target'),
207			_('Expression'),
208			$readonly ? null : _('Action'),
209			_('Info')
210		]);
211
212	$allowed_testing = true;
213	if ($data['expression_tree']) {
214		foreach ($data['expression_tree'] as $i => $e) {
215			$info_icons = [];
216			if (isset($e['expression']['levelErrors'])) {
217				$allowed_testing = false;
218				$errors = [];
219
220				if (is_array($e['expression']['levelErrors'])) {
221					foreach ($e['expression']['levelErrors'] as $expVal => $errTxt) {
222						if ($errors) {
223							$errors[] = BR();
224						}
225						$errors[] = $expVal.':'.$errTxt;
226					}
227				}
228
229				$info_icons[] = makeErrorIcon($errors);
230			}
231
232			// Templated or discovered trigger.
233			if ($readonly) {
234				// Make all links inside inactive.
235				foreach ($e['list'] as &$obj) {
236					if ($obj instanceof CLinkAction && $obj->getAttribute('class') == ZBX_STYLE_LINK_ACTION) {
237						$obj = new CSpan($obj->items);
238					}
239				}
240				unset($obj);
241			}
242
243			$expression_table->addRow(
244				new CRow([
245					!$readonly
246						? (new CCheckBox('expr_target_single', $e['id']))
247							->setChecked($i == 0)
248							->onClick('check_target(this, '.TRIGGER_EXPRESSION.');')
249							->removeId()
250						: null,
251					(new CDiv($e['list']))->addClass(ZBX_STYLE_WORDWRAP),
252					!$readonly
253						? (new CCol(
254							(new CSimpleButton(_('Remove')))
255								->addClass(ZBX_STYLE_BTN_LINK)
256								->onClick('javascript:'.
257									' if (confirm('.json_encode(_('Delete expression?')).')) {'.
258										' delete_expression("'.$e['id'] .'", '.TRIGGER_EXPRESSION.');'.
259										' document.forms["'.$triggersForm->getName().'"].submit();'.
260									' }'
261								)
262						))->addClass(ZBX_STYLE_NOWRAP)
263						: null,
264					makeInformationList($info_icons)
265				])
266			);
267		}
268	}
269	else {
270		$allowed_testing = false;
271		$data['expression_formula'] = '';
272	}
273
274	$testButton = (new CButton('test_expression', _('Test')))
275		->onClick('return PopUp("popup.testtriggerexpr",{expression: this.form.elements["expression"].value}, null,'.
276					'this);')
277		->addClass(ZBX_STYLE_BTN_LINK)
278		->removeId();
279
280	if (!$allowed_testing) {
281		$testButton->setEnabled(false);
282	}
283
284	if ($data['expression_formula'] === '') {
285		$testButton->setEnabled(false);
286	}
287
288	$wrapOutline = new CSpan([$data['expression_formula']]);
289	$triggersFormList->addRow(null, [
290		$wrapOutline,
291		BR(),
292		BR(),
293		(new CDiv([$expression_table, $testButton]))
294			->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
295			->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
296	]);
297
298	$input_method_toggle = (new CSimpleButton(_('Close expression constructor')))
299		->addClass(ZBX_STYLE_BTN_LINK)
300		->onClick('javascript: '.
301			'document.getElementById("toggle_expression_constructor").value=1;'.
302			'document.getElementById("expression_constructor").value='.IM_ESTABLISHED.';'.
303			'document.forms["'.$triggersForm->getName().'"].submit();');
304	$triggersFormList->addRow(null, [$input_method_toggle, BR()]);
305}
306
307$triggersFormList->addRow(_('OK event generation'),
308	(new CRadioButtonList('recovery_mode', (int) $data['recovery_mode']))
309		->addValue(_('Expression'), ZBX_RECOVERY_MODE_EXPRESSION)
310		->addValue(_('Recovery expression'), ZBX_RECOVERY_MODE_RECOVERY_EXPRESSION)
311		->addValue(_('None'), ZBX_RECOVERY_MODE_NONE)
312		->setModern(true)
313		->setEnabled(!$readonly)
314);
315
316$popup_options = [
317	'srctbl' => $data['recovery_expression_field_name'],
318	'srcfld1' => $data['recovery_expression_field_name'],
319	'dstfrm' => $triggersForm->getName(),
320	'dstfld1' => $data['recovery_expression_field_name']
321];
322
323if ($data['hostid']) {
324	$popup_options['hostid'] = $data['hostid'];
325}
326
327$recovery_expression_row = [
328	(new CTextArea(
329		$data['recovery_expression_field_name'],
330		$data['recovery_expression_field_value'],
331		['readonly' => $data['recovery_expression_field_readonly']]
332	))
333		->addClass(ZBX_STYLE_MONOSPACE_FONT)
334		->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
335		->setAriaRequired(),
336	(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
337	(new CButton('insert', ($data['recovery_expression_constructor'] == IM_TREE) ? _('Edit') : _('Add')))
338		->addClass(ZBX_STYLE_BTN_GREY)
339		->onClick('return PopUp("popup.triggerexpr",jQuery.extend('.
340			json_encode($popup_options).
341				',{expression: jQuery(\'[name="'.$data['recovery_expression_field_name'].'"]\').val()}), null, this);'
342		)
343		->setEnabled(!$readonly)
344		->removeId()
345];
346
347if ($data['recovery_expression_constructor'] == IM_TREE) {
348	$recovery_expression_row[] = BR();
349
350	if ($data['recovery_expression_formula'] === '') {
351		// Append "Add" button.
352		$recovery_expression_row[] = (new CSimpleButton(_('Add')))
353			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "add_recovery_expression", "1");')
354			->addClass(ZBX_STYLE_BTN_GREY)
355			->setEnabled(!$readonly);
356	}
357	else {
358		// Append "And" button.
359		$recovery_expression_row[] = (new CSimpleButton(_('And')))
360			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "and_recovery_expression", "1");')
361			->addClass(ZBX_STYLE_BTN_GREY)
362			->setEnabled(!$readonly);
363
364		// Append "Or" button.
365		$recovery_expression_row[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
366		$recovery_expression_row[] = (new CSimpleButton(_('Or')))
367			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "or_recovery_expression", "1");')
368			->addClass(ZBX_STYLE_BTN_GREY)
369			->setEnabled(!$readonly);
370
371		// Append "Replace" button.
372		$recovery_expression_row[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
373		$recovery_expression_row[] = (new CSimpleButton(_('Replace')))
374			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "replace_recovery_expression", "1");')
375			->addClass(ZBX_STYLE_BTN_GREY)
376			->setEnabled(!$readonly);
377	}
378}
379elseif ($data['recovery_expression_constructor'] != IM_FORCED) {
380	$input_method_toggle = (new CSimpleButton(_('Expression constructor')))
381		->addClass(ZBX_STYLE_BTN_LINK)
382		->onClick('javascript: '.
383			'document.getElementById("toggle_recovery_expression_constructor").value=1;'.
384			'document.getElementById("recovery_expression_constructor").value='.
385				(($data['recovery_expression_constructor'] == IM_TREE) ? IM_ESTABLISHED : IM_TREE).';'.
386			'document.forms["'.$triggersForm->getName().'"].submit();'
387		);
388	$recovery_expression_row[] = [BR(), $input_method_toggle];
389}
390
391$triggersFormList->addRow(
392	(new CLabel(_('Recovery expression'), $data['recovery_expression_field_name']))->setAsteriskMark(),
393	$recovery_expression_row,
394	null,
395	'recovery_expression_constructor_row'
396);
397
398// Append expression table to form list.
399if ($data['recovery_expression_constructor'] == IM_TREE) {
400	$recovery_expression_table = (new CTable())
401		->setAttribute('style', 'width: 100%;')
402		->setHeader([
403			$readonly ? null : _('Target'),
404			_('Expression'),
405			$readonly ? null : _('Action'),
406			_('Info')
407		]);
408
409	$allowed_testing = true;
410
411	if ($data['recovery_expression_tree']) {
412		foreach ($data['recovery_expression_tree'] as $i => $e) {
413			$info_icons = [];
414			if (isset($e['expression']['levelErrors'])) {
415				$allowed_testing = false;
416				$errors = [];
417
418				if (is_array($e['expression']['levelErrors'])) {
419					foreach ($e['expression']['levelErrors'] as $expVal => $errTxt) {
420						if ($errors) {
421							$errors[] = BR();
422						}
423						$errors[] = $expVal.':'.$errTxt;
424					}
425				}
426
427				$info_icons[] = makeErrorIcon($errors);
428			}
429
430			// Templated or discovered trigger.
431			if ($readonly) {
432				// Make all links inside inactive.
433				foreach ($e['list'] as &$obj) {
434					if ($obj instanceof CLinkAction && $obj->getAttribute('class') == ZBX_STYLE_LINK_ACTION) {
435						$obj = new CSpan($obj->items);
436					}
437				}
438				unset($obj);
439			}
440
441			$recovery_expression_table->addRow(
442				new CRow([
443					!$readonly
444						? (new CCheckBox('recovery_expr_target_single', $e['id']))
445							->setChecked($i == 0)
446							->onClick('check_target(this, '.TRIGGER_RECOVERY_EXPRESSION.');')
447							->removeId()
448						: null,
449					(new CDiv($e['list']))->addClass(ZBX_STYLE_WORDWRAP),
450					!$readonly
451						? (new CCol(
452							(new CSimpleButton(_('Remove')))
453								->addClass(ZBX_STYLE_BTN_LINK)
454								->onClick('javascript:'.
455									' if (confirm('.json_encode(_('Delete expression?')).')) {'.
456										' delete_expression("'.$e['id'] .'", '.TRIGGER_RECOVERY_EXPRESSION.');'.
457										' document.forms["'.$triggersForm->getName().'"].submit();'.
458									' }'
459								)
460						))->addClass(ZBX_STYLE_NOWRAP)
461						: null,
462					makeInformationList($info_icons)
463				])
464			);
465		}
466	}
467	else {
468		$allowed_testing = false;
469		$data['recovery_expression_formula'] = '';
470	}
471
472	$testButton = (new CButton('test_expression', _('Test')))
473		->onClick('return PopUp("popup.testtriggerexpr",'.
474			'{expression: this.form.elements["recovery_expression"].value}, null, this);')
475		->addClass(ZBX_STYLE_BTN_LINK)
476		->removeId();
477
478	if (!$allowed_testing) {
479		$testButton->setAttribute('disabled', 'disabled');
480	}
481
482	if ($data['recovery_expression_formula'] === '') {
483		$testButton->setAttribute('disabled', 'disabled');
484	}
485
486	$wrapOutline = new CSpan([$data['recovery_expression_formula']]);
487	$triggersFormList->addRow(null, [
488		$wrapOutline,
489		BR(),
490		BR(),
491		(new CDiv([$recovery_expression_table, $testButton]))
492			->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
493			->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
494	], null, 'recovery_expression_constructor_row');
495
496	$input_method_toggle = (new CSimpleButton(_('Close expression constructor')))
497		->addClass(ZBX_STYLE_BTN_LINK)
498		->onClick('javascript: '.
499			'document.getElementById("toggle_recovery_expression_constructor").value=1;'.
500			'document.getElementById("recovery_expression_constructor").value='.IM_ESTABLISHED.';'.
501			'document.forms["'.$triggersForm->getName().'"].submit();'
502		);
503	$triggersFormList->addRow(null, [$input_method_toggle, BR()], null, 'recovery_expression_constructor_row');
504}
505
506$triggersFormList
507	->addRow(_('PROBLEM event generation mode'),
508		(new CRadioButtonList('type', (int) $data['type']))
509			->addValue(_('Single'), TRIGGER_MULT_EVENT_DISABLED)
510			->addValue(_('Multiple'), TRIGGER_MULT_EVENT_ENABLED)
511			->setModern(true)
512			->setEnabled(!$readonly)
513	)
514	->addRow(_('OK event closes'),
515		(new CRadioButtonList('correlation_mode', (int) $data['correlation_mode']))
516			->addValue(_('All problems'), ZBX_TRIGGER_CORRELATION_NONE)
517			->addValue(_('All problems if tag values match'), ZBX_TRIGGER_CORRELATION_TAG)
518			->setModern(true)
519			->setEnabled(!$readonly),
520		'correlation_mode_row'
521	)
522	->addRow(
523		(new CLabel(_('Tag for matching'), 'correlation_tag'))->setAsteriskMark(),
524		(new CTextBox('correlation_tag', $data['correlation_tag'], $readonly))
525			->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
526			->setAriaRequired(),
527		'correlation_tag_row'
528	)
529	->addRow(_('Allow manual close'),
530		(new CCheckBox('manual_close'))
531			->setChecked($data['manual_close'] == ZBX_TRIGGER_MANUAL_CLOSE_ALLOWED)
532			->setEnabled(!$readonly)
533	);
534
535// Append status to form list.
536if (empty($data['triggerid']) && empty($data['form_refresh'])) {
537	$status = true;
538}
539else {
540	$status = ($data['status'] == TRIGGER_STATUS_ENABLED);
541}
542
543$triggersFormList
544	->addRow(_('URL'), (new CTextBox('url', $data['url'], $discovered_trigger))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH))
545	->addRow(_('Description'),
546		(new CTextArea('comments', $data['comments']))
547			->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
548			->setMaxlength(DB::getFieldLength('triggers', 'comments'))
549			->setReadonly($discovered_trigger)
550	)
551	->addRow(_('Enabled'), (new CCheckBox('status'))->setChecked($status));
552
553// Append tabs to form.
554$triggersTab = new CTabView();
555if (!$data['form_refresh']) {
556	$triggersTab->setSelected(0);
557}
558$triggersTab->addTab('triggersTab', _('Trigger'), $triggersFormList);
559
560// tags
561$triggersTab->addTab('tags-tab', _('Tags'), new CPartial('configuration.tags.tab', [
562	'source' => 'trigger',
563	'tags' => $data['tags'],
564	'show_inherited_tags' => $data['show_inherited_tags'],
565	'readonly' => $discovered_trigger
566]));
567
568/*
569 * Dependencies tab
570 */
571$dependenciesFormList = new CFormList('dependenciesFormList');
572$dependenciesTable = (new CTable())
573	->setAttribute('style', 'width: 100%;')
574	->setHeader([_('Name'), $discovered_trigger ? null : _('Action')]);
575
576foreach ($data['db_dependencies'] as $dependency) {
577	$triggersForm->addVar('dependencies[]', $dependency['triggerid'], 'dependencies_'.$dependency['triggerid']);
578
579	$dep_trigger_description = CHtml::encode(
580		implode(', ', zbx_objectValues($dependency['hosts'], 'name')).NAME_DELIMITER.$dependency['description']
581	);
582
583	$dependenciesTable->addRow(
584		(new CRow([
585			(new CLink($dep_trigger_description, 'triggers.php?form=update&triggerid='.$dependency['triggerid']))
586				->setTarget('_blank'),
587			(new CCol(
588				$discovered_trigger
589					? null
590					: (new CButton('remove', _('Remove')))
591						->onClick('javascript: removeDependency("'.$dependency['triggerid'].'");')
592						->addClass(ZBX_STYLE_BTN_LINK)
593						->removeId()
594			))->addClass(ZBX_STYLE_NOWRAP)
595		]))->setId('dependency_'.$dependency['triggerid'])
596	);
597}
598
599$dependenciesFormList->addRow(_('Dependencies'),
600	(new CDiv([
601		$dependenciesTable,
602		$discovered_trigger
603			? null
604			: (new CButton('bnt1', _('Add')))
605				->onClick('return PopUp("popup.generic",'.
606					json_encode([
607						'srctbl' => 'triggers',
608						'srcfld1' => 'triggerid',
609						'reference' => 'deptrigger',
610						'hostid' => $data['hostid'],
611						'multiselect' => '1',
612						'with_triggers' => '1',
613						'noempty' => '1'
614					]).', null, this);'
615				)
616				->addClass(ZBX_STYLE_BTN_LINK)
617	]))
618		->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
619		->addStyle('min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
620);
621$triggersTab->addTab('dependenciesTab', _('Dependencies'), $dependenciesFormList);
622
623// Append buttons to form list.
624if (!empty($data['triggerid'])) {
625	$triggersTab->setFooter(makeFormFooter(
626		new CSubmit('update', _('Update')), [
627			new CSubmit('clone', _('Clone')),
628			(new CButtonDelete(_('Delete trigger?'), url_params(['form', 'hostid', 'triggerid'])))
629				->setEnabled(!$data['limited']),
630			new CButtonCancel()
631		]
632	));
633}
634else {
635	$triggersTab->setFooter(makeFormFooter(
636		new CSubmit('add', _('Add')),
637		[new CButtonCancel()]
638	));
639}
640
641// Append tabs to form.
642$triggersForm->addItem($triggersTab);
643
644$widget->addItem($triggersForm);
645
646$widget->show();
647