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
22require_once dirname(__FILE__).'/js/configuration.triggers.edit.js.php';
23
24$widget = (new CWidget())->setTitle(_('Triggers'));
25
26// append host summary to widget header
27if (!empty($this->data['hostid'])) {
28	$widget->addItem(get_header_host_table('triggers', $this->data['hostid']));
29}
30
31// create form
32$triggersForm = (new CForm())
33	->setName('triggersForm')
34	->addVar('form', $this->data['form'])
35	->addVar('hostid', $this->data['hostid'])
36	->addVar('input_method', $this->data['input_method'])
37	->addVar('toggle_input_method', '')
38	->addVar('remove_expression', '');
39
40if ($data['triggerid'] !== null) {
41	$triggersForm->addVar('triggerid', $this->data['triggerid']);
42}
43
44// create form list
45$triggersFormList = new CFormList('triggersFormList');
46if (!empty($this->data['templates'])) {
47	$triggersFormList->addRow(_('Parent triggers'), $this->data['templates']);
48}
49$triggersFormList->addRow(_('Name'),
50	(new CTextBox('description', $this->data['description'], $this->data['limited']))
51		->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
52		->setAttribute('autofocus', 'autofocus')
53);
54
55// append expression to form list
56if ($this->data['expression_field_readonly']) {
57	$triggersForm->addVar('expression', $this->data['expression']);
58}
59
60$addExpressionButton = (new CButton('insert', ($this->data['input_method'] == IM_TREE) ? _('Edit') : _('Add')))
61	->addClass(ZBX_STYLE_BTN_GREY)
62	->onClick(
63		'return PopUp("popup_trexpr.php?dstfrm='.$triggersForm->getName().
64			(($data['groupid'] && $data['hostid'])
65				? '&groupid='.$data['groupid'].'&hostid='.$data['hostid']
66				: ''
67			).
68			'&dstfld1='.$this->data['expression_field_name'].'&srctbl=expression&srcfld1=expression'.
69			'&expression=" + encodeURIComponent(jQuery(\'[name="'.$this->data['expression_field_name'].'"]\').val()));'
70	);
71if ($this->data['limited']) {
72	$addExpressionButton->setAttribute('disabled', 'disabled');
73}
74$expressionRow = [
75	(new CTextArea(
76		$this->data['expression_field_name'],
77		$this->data['expression_field_value'],
78		[
79			'readonly' => $this->data['expression_field_readonly']
80		]
81	))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH),
82	(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
83	$addExpressionButton
84];
85
86if ($this->data['input_method'] == IM_TREE) {
87	// insert macro button
88	$insertMacroButton = (new CButton('insert_macro', _('Insert expression')))
89		->addClass(ZBX_STYLE_BTN_GREY)
90		->setMenuPopup(CMenuPopupHelper::getTriggerMacro());
91	if ($this->data['limited']) {
92		$insertMacroButton->setAttribute('disabled', 'disabled');
93	}
94	$expressionRow[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
95	$expressionRow[] = $insertMacroButton;
96
97	array_push($expressionRow, BR());
98	if (empty($this->data['outline'])) {
99		// Append "Add" button.
100		$expressionRow[] = (new CSimpleButton(_('Add')))
101			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "add_expression", "1");')
102			->addClass(ZBX_STYLE_BTN_GREY)
103			->setEnabled(!$this->data['limited']);
104	}
105	else {
106		// Append "And" button.
107		$expressionRow[] = (new CSimpleButton(_('And')))
108			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "and_expression", "1");')
109			->addClass(ZBX_STYLE_BTN_GREY)
110			->setEnabled(!$this->data['limited']);
111
112		// Append "Or" button.
113		$expressionRow[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
114		$expressionRow[] = (new CSimpleButton(_('Or')))
115			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "or_expression", "1");')
116			->addClass(ZBX_STYLE_BTN_GREY)
117			->setEnabled(!$this->data['limited']);
118
119		// Append "Replace" button.
120		$expressionRow[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN);
121		$expressionRow[] = (new CSimpleButton(_('Replace')))
122			->onClick('javascript: submitFormWithParam("'.$triggersForm->getName().'", "replace_expression", "1");')
123			->addClass(ZBX_STYLE_BTN_GREY)
124			->setEnabled(!$this->data['limited']);
125	}
126}
127elseif ($this->data['input_method'] != IM_FORCED) {
128	$inputMethodToggle = (new CSimpleButton(_('Expression constructor')))
129		->addClass(ZBX_STYLE_BTN_LINK)
130		->onClick('javascript: '.
131			'document.getElementById("toggle_input_method").value=1;'.
132			'document.getElementById("input_method").value='.(($this->data['input_method'] == IM_TREE) ? IM_ESTABLISHED : IM_TREE).';'.
133			'document.forms["'.$triggersForm->getName().'"].submit();');
134	$expressionRow[] = [BR(), $inputMethodToggle];
135}
136$triggersFormList->addRow(_('Expression'), $expressionRow);
137
138// append expression table to form list
139if ($this->data['input_method'] == IM_TREE) {
140	$expressionTable = (new CTable())
141		->setAttribute('style', 'width: 100%;')
142		->setId('exp_list')
143		->setHeader([
144			$this->data['limited'] ? null : _('Target'),
145			_('Expression'),
146			$this->data['limited'] ? null : _('Action'),
147			_('Info')
148		]);
149
150	$allowedTesting = true;
151	if (!empty($this->data['eHTMLTree'])) {
152		foreach ($this->data['eHTMLTree'] as $i => $e) {
153			if (!isset($e['expression']['levelErrors'])) {
154				$errorImg = '';
155			}
156			else {
157				$allowedTesting = false;
158				$errors = [];
159
160				if (is_array($e['expression']['levelErrors'])) {
161					foreach ($e['expression']['levelErrors'] as $expVal => $errTxt) {
162						if ($errors) {
163							$errors[] = BR();
164						}
165						$errors[] = $expVal.':'.$errTxt;
166					}
167				}
168
169				$errorImg = makeErrorIcon($errors);
170			}
171
172			// templated trigger
173			if ($this->data['limited']) {
174				// make all links inside inactive
175				foreach ($e['list'] as &$obj) {
176					if (gettype($obj) == 'object' && get_class($obj) == 'CSpan'
177							&& $obj->getAttribute('class') == ZBX_STYLE_LINK_ACTION) {
178						$obj->removeAttribute('class');
179						$obj->onClick(null);
180					}
181				}
182				unset($obj);
183			}
184
185			$expressionTable->addRow(
186				new CRow([
187					!$this->data['limited']
188						? (new CCheckBox('expr_target_single', $e['id']))
189							->setChecked($i == 0)
190							->onClick('check_target(this);')
191						: null,
192					$e['list'],
193					!$this->data['limited']
194						? (new CCol(
195							(new CSimpleButton(_('Remove')))
196								->addClass(ZBX_STYLE_BTN_LINK)
197								->onClick('javascript:'.
198									' if (confirm('.CJs::encodeJson(_('Delete expression?')).')) {'.
199										' delete_expression("'.$e['id'] .'");'.
200										' document.forms["'.$triggersForm->getName().'"].submit();'.
201									' }'
202								)
203						))->addClass(ZBX_STYLE_NOWRAP)
204						: null,
205					$errorImg
206				])
207			);
208		}
209	}
210	else {
211		$allowedTesting = false;
212		$this->data['outline'] = '';
213	}
214
215	$testButton = (new CButton('test_expression', _('Test')))
216		->onClick('openWinCentered("tr_testexpr.php?expression=" + encodeURIComponent(this.form.elements["expression"].value),'.
217		'"ExpressionTest", 950, 650, "titlebar=no, resizable=yes, scrollbars=yes"); return false;')
218		->addClass(ZBX_STYLE_BTN_LINK);
219	if (!$allowedTesting) {
220		$testButton->setAttribute('disabled', 'disabled');
221	}
222	if (empty($this->data['outline'])) {
223		$testButton->setAttribute('disabled', 'disabled');
224	}
225
226	$wrapOutline = new CSpan([$this->data['outline']]);
227	$triggersFormList->addRow(null, [
228		$wrapOutline,
229		BR(),
230		BR(),
231		(new CDiv([$expressionTable, $testButton]))
232			->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
233			->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
234	]);
235
236	$inputMethodToggle = (new CSimpleButton(_('Close expression constructor')))
237		->addClass(ZBX_STYLE_BTN_LINK)
238		->onClick('javascript: '.
239			'document.getElementById("toggle_input_method").value=1;'.
240			'document.getElementById("input_method").value='.IM_ESTABLISHED.';'.
241			'document.forms["'.$triggersForm->getName().'"].submit();');
242	$triggersFormList->addRow(null, [$inputMethodToggle, BR()]);
243}
244
245$triggersFormList
246	->addRow(_('Multiple PROBLEM events generation'),
247		(new CCheckBox('type'))->setChecked($this->data['type'] == TRIGGER_MULT_EVENT_ENABLED)
248	)
249	->addRow(_('Description'),
250		(new CTextArea('comments', $this->data['comments']))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
251	)
252	->addRow(_('URL'), (new CTextBox('url', $this->data['url']))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH))
253	->addRow(_('Severity'), new CSeverity(['name' => 'priority', 'value' => (int) $this->data['priority']]));
254
255// append status to form list
256if (empty($this->data['triggerid']) && empty($this->data['form_refresh'])) {
257	$status = true;
258}
259else {
260	$status = ($this->data['status'] == 0);
261}
262$triggersFormList->addRow(_('Enabled'), (new CCheckBox('status'))->setChecked($status));
263
264// append tabs to form
265$triggersTab = new CTabView();
266if (!$this->data['form_refresh']) {
267	$triggersTab->setSelected(0);
268}
269$triggersTab->addTab('triggersTab', _('Trigger'), $triggersFormList);
270
271/*
272 * Dependencies tab
273 */
274$dependenciesFormList = new CFormList('dependenciesFormList');
275$dependenciesTable = (new CTable())
276	->setAttribute('style', 'width: 100%;')
277	->setHeader([_('Name'), _('Action')]);
278
279foreach ($this->data['db_dependencies'] as $dependency) {
280	$triggersForm->addVar('dependencies[]', $dependency['triggerid'], 'dependencies_'.$dependency['triggerid']);
281
282	$depTriggerDescription = CHtml::encode(
283		implode(', ', zbx_objectValues($dependency['hosts'], 'name')).NAME_DELIMITER.$dependency['description']
284	);
285
286	if ($dependency['flags'] == ZBX_FLAG_DISCOVERY_NORMAL) {
287		$description = (new CLink($depTriggerDescription, 'triggers.php?form=update&triggerid='.$dependency['triggerid']))
288			->setAttribute('target', '_blank');
289	}
290	else {
291		$description = $depTriggerDescription;
292	}
293
294	$dependenciesTable->addRow(
295		(new CRow([
296			$description,
297			(new CCol(
298				(new CButton('remove', _('Remove')))
299					->onClick('javascript: removeDependency("'.$dependency['triggerid'].'");')
300					->addClass(ZBX_STYLE_BTN_LINK)
301			))->addClass(ZBX_STYLE_NOWRAP)
302		]))->setId('dependency_'.$dependency['triggerid'])
303	);
304}
305
306$dependenciesFormList->addRow(_('Dependencies'),
307	(new CDiv([
308		$dependenciesTable,
309		(new CButton('bnt1', _('Add')))
310			->onClick('return PopUp("popup.php?srctbl=triggers&srcfld1=triggerid&reference=deptrigger&multiselect=1'.
311				'&hostid='.$data['hostid'].'&groupid='.$data['groupid'].'&with_triggers=1&noempty=1");'
312			)
313			->addClass(ZBX_STYLE_BTN_LINK)
314	]))
315		->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
316		->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
317);
318$triggersTab->addTab('dependenciesTab', _('Dependencies'), $dependenciesFormList);
319
320// append buttons to form
321if (!empty($this->data['triggerid'])) {
322	$deleteButton = new CButtonDelete(_('Delete trigger?'), url_params(['form', 'hostid', 'triggerid']));
323	if ($this->data['limited']) {
324		$deleteButton->setAttribute('disabled', 'disabled');
325	}
326
327	$triggersTab->setFooter(makeFormFooter(
328		new CSubmit('update', _('Update')), [
329			new CSubmit('clone', _('Clone')),
330			$deleteButton,
331			new CButtonCancel(url_param('hostid'))
332		]
333	));
334}
335else {
336	$triggersTab->setFooter(makeFormFooter(
337		new CSubmit('add', _('Add')),
338		[new CButtonCancel(url_param('hostid'))]
339	));
340}
341
342// append tabs to form
343$triggersForm->addItem($triggersTab);
344
345$widget->addItem($triggersForm);
346
347return $widget;
348