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