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$this->includeJsFile('configuration.services.edit.js.php');
27
28$service = $this->data['service'];
29
30$widget = (new CWidget())->setTitle(_('Services'));
31
32// create form
33$servicesForm = (new CForm())
34	->setId('services-form')
35	->setName('servicesForm')
36	->setAttribute('aria-labeledby', ZBX_STYLE_PAGE_TITLE)
37	->addVar('form', $this->data['form'])
38	->addVar('parentid', $this->data['parentid'])
39	->addVar('parentname', $this->data['parentname'])
40	->addVar('triggerid', $this->data['triggerid']);
41if (isset($this->data['service'])) {
42	$servicesForm->addVar('serviceid', $this->data['service']['serviceid']);
43}
44
45// create form list
46$servicesFormList = (new CFormList('servicesFormList'))
47	->addRow(
48		(new CLabel(_('Name'), 'name'))->setAsteriskMark(),
49		(new CTextBox('name', $this->data['name'], false, 128))
50			->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
51			->setAriaRequired()
52			->setAttribute('autofocus', 'autofocus')
53	);
54
55// append parent link to form list
56$parent_service_popup_options = [
57	'pservices' => '1'
58];
59if ($this->data['service'] && $this->data['service']['serviceid']) {
60	$parent_service_popup_options['serviceid'] = $this->data['service']['serviceid'];
61}
62$servicesFormList->addRow((new CLabel(_('Parent service'), 'parent_name'))->setAsteriskMark(), [
63	(new CTextBox('parent_name', $this->data['parentname'], true, 128))
64		->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
65		->setAriaRequired(),
66	(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
67	(new CButton('select_parent', _x('Change', 'verb')))
68		->addClass(ZBX_STYLE_BTN_GREY)
69		->onClick('return PopUp("popup.services",jQuery.extend('.
70			json_encode($parent_service_popup_options).
71				',{parentid: this.form.parentid.value}), null, this);'
72		)
73]);
74
75// append algorithm to form list
76$servicesFormList->addRow(
77	new CLabel(_('Status calculation algorithm'), 'label-algorithm'),
78	(new CSelect('algorithm'))
79		->setId('algorithm')
80		->setValue($data['algorithm'])
81		->addOptions(CSelect::createOptionsFromArray(serviceAlgorithm()))
82		->setFocusableElementId('label-algorithm')
83);
84
85// append SLA to form list
86$showslaCheckbox = (new CCheckBox('showsla'))->setChecked($this->data['showsla'] == SERVICE_SHOW_SLA_ON);
87$goodslaTextBox = (new CTextBox('goodsla', $this->data['goodsla'], false, 8))->setWidth(ZBX_TEXTAREA_TINY_WIDTH);
88if (!$this->data['showsla']) {
89	$goodslaTextBox->setAttribute('disabled', 'disabled');
90}
91$servicesFormList->addRow(_('Calculate SLA, acceptable SLA (in %)'), [
92	$showslaCheckbox, (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), $goodslaTextBox
93]);
94
95// append trigger to form list
96$servicesFormList->addRow(_('Trigger'), [
97	(new CTextBox('trigger', $this->data['trigger'], true))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH),
98	(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
99	(new CButton('btn1', _('Select')))
100		->addClass(ZBX_STYLE_BTN_GREY)
101		->onClick('return PopUp("popup.generic",'.
102			json_encode([
103				'srctbl' => 'triggers',
104				'srcfld1' => 'triggerid',
105				'srcfld2' => 'description',
106				'dstfrm' => $servicesForm->getName(),
107				'dstfld1' => 'triggerid',
108				'dstfld2' => 'trigger',
109				'real_hosts' => '1',
110				'with_triggers' => '1'
111			]).', null, this);'
112		)
113]);
114$servicesFormList->addRow((new CLabel(_('Sort order (0->999)'), 'sortorder'))->setAsteriskMark(),
115	(new CTextBox('sortorder', $this->data['sortorder'], false, 3))
116		->setWidth(ZBX_TEXTAREA_TINY_WIDTH)
117		->setAriaRequired()
118);
119
120/*
121 * Dependencies tab
122 */
123$servicesChildTable = (new CTable())
124	->setAttribute('style', 'width: 100%;')
125	->setId('service_children')
126	->setHeader([_('Services'), _('Soft'), _('Trigger'), _('Action')]);
127foreach ($this->data['children'] as $child) {
128	$childrenLink = (new CLink($child['name'], 'services.php?form=1&serviceid='.$child['serviceid']))
129		->setTarget('_blank');
130
131	$servicesChildTable->addRow(
132		(new CRow([
133			[
134				$childrenLink,
135				new CVar('children['.$child['serviceid'].'][name]', $child['name']),
136				new CVar('children['.$child['serviceid'].'][serviceid]', $child['serviceid']),
137				new CVar('children['.$child['serviceid'].'][trigger]', $child['trigger'])
138			],
139			(new CCheckBox('children['.$child['serviceid'].'][soft]'))
140				->setChecked(isset($child['soft']) && !empty($child['soft'])),
141			!empty($child['trigger']) ? $child['trigger'] : '',
142			(new CCol(
143				(new CButton('remove', _('Remove')))
144					->onClick('javascript: removeDependentChild(\''.$child['serviceid'].'\');')
145					->addClass(ZBX_STYLE_BTN_LINK)
146					->removeId()
147			))->addClass(ZBX_STYLE_NOWRAP)
148		]))->setId('children_'.$child['serviceid'])
149	);
150}
151$servicesDependenciesFormList = new CFormList('servicesDependensiesFormList');
152
153$dep_service_popup_options = [
154	'cservices' => '1'
155];
156if ($this->data['service'] && $this->data['service']['serviceid']) {
157	$dep_service_popup_options['serviceid'] = $this->data['service']['serviceid'];
158}
159
160$servicesDependenciesFormList->addRow(
161	_('Depends on'),
162	(new CDiv([
163		$servicesChildTable,
164		(new CButton('add_child_service', _('Add')))
165			->onClick('return PopUp("popup.services",jQuery.extend('.
166				json_encode($dep_service_popup_options).
167					',{parentid: this.form.parentid.value}), null, this);'
168			)
169			->addClass(ZBX_STYLE_BTN_LINK)
170	]))
171		->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
172		->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
173);
174
175// Service times tab.
176$servicesTimeFormList = new CFormList('servicesTimeFormList');
177$servicesTimeTable = (new CTable())
178	->setId('time-table')
179	->setAttribute('style', 'width: 100%;')
180	->setHeader([_('Type'), _('Interval'), _('Note'), _('Action')]);
181
182$i = 0;
183
184foreach ($data['times'] as $service_time) {
185	switch ($service_time['type']) {
186		case SERVICE_TIME_TYPE_UPTIME:
187			$type = (new CSpan(_('Uptime')))->addClass('enabled');
188			$from = dowHrMinToStr($service_time['ts_from']);
189			$till = dowHrMinToStr($service_time['ts_to'], true);
190			break;
191
192		case SERVICE_TIME_TYPE_DOWNTIME:
193			$type = (new CSpan(_('Downtime')))->addClass('disabled');
194			$from = dowHrMinToStr($service_time['ts_from']);
195			$till = dowHrMinToStr($service_time['ts_to'], true);
196			break;
197
198		case SERVICE_TIME_TYPE_ONETIME_DOWNTIME:
199			$type = (new CSpan(_('One-time downtime')))->addClass('disabled');
200			$from = zbx_date2str(DATE_TIME_FORMAT, $service_time['ts_from']);
201			$till = zbx_date2str(DATE_TIME_FORMAT, $service_time['ts_to']);
202			break;
203	}
204
205	$row = new CRow([
206		[
207			$type,
208			new CVar('times['.$i.'][type]', $service_time['type']),
209			new CVar('times['.$i.'][ts_from]', $service_time['ts_from']),
210			new CVar('times['.$i.'][ts_to]', $service_time['ts_to']),
211			new CVar('times['.$i.'][note]', $service_time['note'])
212		],
213		$from.' - '.$till,
214		(new CCol($service_time['note']))
215			->addClass(ZBX_STYLE_WORDWRAP)
216			->addStyle('max-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;'),
217		(new CCol(
218			(new CButton('remove', _('Remove')))
219				->onClick('javascript: removeTime(\''.$i.'\');')
220				->addClass(ZBX_STYLE_BTN_LINK)
221				->removeId()
222		))->addClass(ZBX_STYLE_NOWRAP)
223	]);
224	$row->setId('times_'.$i);
225	$servicesTimeTable->addRow($row);
226	$i++;
227}
228
229$servicesTimeFormList->addRow(_('Service times'),
230	(new CDiv($servicesTimeTable))
231		->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
232		->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
233);
234
235// create service time table
236$serviceTimeTable = (new CFormList())
237	->addRow(
238		(new CLabel(_('Period type'), 'label-period-type')),
239		(new CSelect('new_service_time[type]'))
240			->setId('period-type')
241			->setFocusableElementId('label-period-type')
242			->setValue($data['new_service_time']['type'])
243			->addOptions(CSelect::createOptionsFromArray([
244				SERVICE_TIME_TYPE_UPTIME => _('Uptime'),
245				SERVICE_TIME_TYPE_DOWNTIME => _('Downtime'),
246				SERVICE_TIME_TYPE_ONETIME_DOWNTIME => _('One-time downtime')
247			]))
248	);
249
250if ($data['new_service_time']['type'] == SERVICE_TIME_TYPE_ONETIME_DOWNTIME) {
251	$serviceTimeTable
252		->addRow(
253			_('Note'),
254			(new CTextBox('new_service_time[note]'))
255				->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
256				->setAttribute('placeholder', _('short description'))
257		)
258		->addRow(
259			(new CLabel(_('From'), 'new_service_time_from'))->setAsteriskMark(),
260			(new CDateSelector('new_service_time_from', $data['new_service_time_from']))
261				->setDateFormat(ZBX_DATE_TIME)
262				->setPlaceholder(_('YYYY-MM-DD hh:mm'))
263				->setAriaRequired()
264		)
265		->addRow(
266			(new CLabel(_('Till'), 'new_service_time_till'))->setAsteriskMark(),
267			(new CDateSelector('new_service_time_till', $data['new_service_time_till']))
268				->setDateFormat(ZBX_DATE_TIME)
269				->setPlaceholder(_('YYYY-MM-DD hh:mm'))
270				->setAriaRequired()
271		);
272}
273else {
274	$week_from_select = (new CSelect('new_service_time[from_week]'))
275		->setValue(isset($_REQUEST['new_service_time']['from_week']) ? $_REQUEST['new_service_time']['from_week'] : 0);
276
277	$week_to_select = (new CSelect('new_service_time[to_week]'))
278		->setValue(isset($_REQUEST['new_service_time']['from_week']) ? $_REQUEST['new_service_time']['to_week'] : 0);
279
280	for ($dow = 0; $dow < 7; $dow++) {
281		$week_from_select->addOption(new CSelectOption($dow, getDayOfWeekCaption($dow)));
282		$week_to_select->addOption(new CSelectOption($dow, getDayOfWeekCaption($dow)));
283	}
284	$timeFromHourTextBox = (new CTextBox('new_service_time[from_hour]', isset($_REQUEST['new_service_time']['from_hour'])
285			? $_REQUEST['new_service_time']['from_hour'] : '', false, 2))
286		->setWidth(ZBX_TEXTAREA_2DIGITS_WIDTH)
287		->setAriaRequired()
288		->setAttribute('placeholder', _('hh'));
289	$timeFromMinuteTextBox = (new CTextBox('new_service_time[from_minute]', isset($_REQUEST['new_service_time']['from_minute'])
290			? $_REQUEST['new_service_time']['from_minute'] : '', false, 2))
291		->setWidth(ZBX_TEXTAREA_2DIGITS_WIDTH)
292		->setAriaRequired()
293		->setAttribute('placeholder', _('mm'));
294	$timeToHourTextBox = (new CTextBox('new_service_time[to_hour]', isset($_REQUEST['new_service_time']['to_hour'])
295			? $_REQUEST['new_service_time']['to_hour'] : '', false, 2))
296		->setWidth(ZBX_TEXTAREA_2DIGITS_WIDTH)
297		->setAriaRequired()
298		->setAttribute('placeholder', _('hh'));
299	$timeToMinuteTextBox = (new CTextBox('new_service_time[to_minute]', isset($_REQUEST['new_service_time']['to_minute'])
300			? $_REQUEST['new_service_time']['to_minute'] : '', false, 2))
301		->setWidth(ZBX_TEXTAREA_2DIGITS_WIDTH)
302		->setAriaRequired()
303		->setAttribute('placeholder', _('mm'));
304
305	$serviceTimeTable
306		->addRow(
307			(new CLabel(_('From'), 'new_service_time_from'))->setAsteriskMark(),
308			(new CDiv([
309					$week_from_select,
310					(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
311					_('Time'),
312					(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
313					$timeFromHourTextBox,
314					(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
315					':',
316					(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
317					$timeFromMinuteTextBox
318			]))
319		)
320		->addRow(
321			(new CLabel(_('Till'), 'new_service_time_to'))->setAsteriskMark(),
322			(new CDiv([
323				$week_to_select,
324				(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
325				_('Time'),
326				(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
327				$timeToHourTextBox,
328				(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
329				':',
330				(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
331				$timeToMinuteTextBox
332			]))
333		);
334	$servicesForm->addVar('new_service_time[note]', '');
335}
336
337$servicesTimeFormList->addRow(_('New service time'),
338	(new CDiv([
339		$serviceTimeTable,
340		(new CSimpleButton(_('Add')))
341			->onClick('javascript: submitFormWithParam("'.$servicesForm->getName().'", "add_service_time", "1");')
342			->addClass(ZBX_STYLE_BTN_LINK)
343	]))
344		->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
345		->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
346);
347
348/*
349 * Append tabs to form
350 */
351$servicesTab = new CTabView();
352if (!$this->data['form_refresh']) {
353	$servicesTab->setSelected(0);
354}
355$servicesTab
356	->addTab('servicesTab', _('Service'), $servicesFormList)
357	->addTab('servicesDependenciesTab', _('Dependencies'), $servicesDependenciesFormList,
358		TAB_INDICATOR_SERVICE_DEPENDENCY
359	)
360	->addTab('servicesTimeTab', _('Time'), $servicesTimeFormList, TAB_INDICATOR_TIME);
361
362// append buttons to form
363if ($service && $service['serviceid']) {
364	$buttons = [new CButtonCancel()];
365	if (!$service['dependencies']) {
366		array_unshift($buttons, new CButtonDelete(
367			'Delete selected service?',
368			url_param('form').url_param('serviceid').'&saction=1'
369		));
370	}
371
372	$servicesTab->setFooter(makeFormFooter(
373		(new CSubmit('update', _('Update')))->onClick('javascript: document.forms[0].action += \'?saction=1\';'),
374		$buttons
375	));
376}
377else {
378	$servicesTab->setFooter(makeFormFooter(
379		(new CSubmit('add', _('Add')))->onClick('javascript: document.forms[0].action += \'?saction=1\';'),
380		[new CButtonCancel()]
381	));
382}
383
384$servicesForm->addItem($servicesTab);
385
386// append form to widget
387$widget->addItem($servicesForm);
388
389$widget->show();
390