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/administration.users.edit.js.php');
23
24if ($this->data['is_profile']) {
25	$userWidget = ($this->data['name'] !== '' || $this->data['surname'] !== '')
26		? (new CWidget())->setTitle(_('User profile').NAME_DELIMITER.$this->data['name'].' '.$this->data['surname'])
27		: (new CWidget())->setTitle(_('User profile').NAME_DELIMITER.$this->data['alias']);
28}
29else {
30	$userWidget = (new CWidget())->setTitle(_('Users'));
31}
32
33// create form
34$userForm = (new CForm())
35	->setName('userForm')
36	->addVar('form', $this->data['form']);
37
38if ($data['userid'] != 0) {
39	$userForm->addVar('userid', $data['userid']);
40}
41
42/*
43 * User tab
44 */
45$userFormList = new CFormList('userFormList');
46
47if (!$data['is_profile']) {
48	$userFormList->addRow(_('Alias'), (new CTextBox('alias', $this->data['alias']))
49		->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
50		->setAttribute('autofocus', 'autofocus')
51	);
52	$userFormList->addRow(_x('Name', 'user first name'),
53		(new CTextBox('name', $this->data['name']))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
54	);
55	$userFormList->addRow(_('Surname'),
56		(new CTextBox('surname', $this->data['surname']))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
57	);
58}
59
60// append user groups to form list
61if (!$this->data['is_profile']) {
62	$user_groups = [];
63
64	foreach ($this->data['groups'] as $group) {
65		$user_groups[] = CArrayHelper::renameKeys($group, ['usrgrpid' => 'id']);
66	}
67
68	$userFormList->addRow(
69		_('Groups'),
70		(new CMultiSelect([
71			'name' => 'user_groups[]',
72			'objectName' => 'usersGroups',
73			'data' => $user_groups,
74			'popup' => [
75				'parameters' => 'srctbl=usrgrp&dstfrm='.$userForm->getName().'&dstfld1=user_groups_&srcfld1=usrgrpid'.
76					'&multiselect=1'
77			]
78		]))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
79	);
80}
81
82// append password to form list
83if ($data['auth_type'] == ZBX_AUTH_INTERNAL) {
84	if ($data['userid'] == 0 || isset($this->data['change_password'])) {
85		$userFormList->addRow(
86			_('Password'),
87			(new CPassBox('password1', $this->data['password1']))->setWidth(ZBX_TEXTAREA_SMALL_WIDTH)
88		);
89		$userFormList->addRow(
90			_('Password (once again)'),
91			(new CPassBox('password2', $this->data['password2']))->setWidth(ZBX_TEXTAREA_SMALL_WIDTH)
92		);
93
94		if (isset($this->data['change_password'])) {
95			$userForm->addVar('change_password', $this->data['change_password']);
96		}
97	}
98	else {
99		$passwdButton = (new CSimpleButton(_('Change password')))
100			->onClick('javascript: submitFormWithParam("'.$userForm->getName().'", "change_password", "1");')
101			->addClass(ZBX_STYLE_BTN_GREY);
102		if ($this->data['alias'] == ZBX_GUEST_USER) {
103			$passwdButton->setAttribute('disabled', 'disabled');
104		}
105
106		$userFormList->addRow(_('Password'), $passwdButton);
107	}
108}
109else {
110	$userFormList->addRow(_('Password'),
111		new CSpan(_s('Unavailable for users with %1$s.', authentication2str($data['auth_type'])))
112	);
113}
114
115// append languages to form list
116$languageComboBox = new CComboBox('lang', $this->data['lang']);
117
118$allLocalesAvailable = true;
119foreach (getLocales() as $localeId => $locale) {
120	if ($locale['display']) {
121		// checking if this locale exists in the system. The only way of doing it is to try and set one
122		// trying to set only the LC_MONETARY locale to avoid changing LC_NUMERIC
123		$localeExists = ($localeId === 'en_GB' || setlocale(LC_MONETARY , zbx_locale_variants($localeId)));
124
125		$languageComboBox->addItem(
126			$localeId,
127			$locale['name'],
128			($localeId == $this->data['lang']) ? true : null,
129			$localeExists
130		);
131
132		$allLocalesAvailable &= $localeExists;
133	}
134}
135
136// restoring original locale
137setlocale(LC_MONETARY, zbx_locale_variants(CWebUser::$data['lang']));
138
139$languageError = '';
140if (!function_exists('bindtextdomain')) {
141	$languageError = 'Translations are unavailable because the PHP gettext module is missing.';
142	$languageComboBox->setAttribute('disabled', 'disabled');
143}
144elseif (!$allLocalesAvailable) {
145	$languageError = _('You are not able to choose some of the languages, because locales for them are not installed on the web server.');
146}
147
148$userFormList->addRow(
149	_('Language'),
150	$languageError
151		? [$languageComboBox, SPACE, (new CSpan($languageError))->addClass('red')->addClass('wrap')]
152		: $languageComboBox
153);
154
155// append themes to form list
156$themes = array_merge([THEME_DEFAULT => _('System default')], Z::getThemes());
157$userFormList->addRow(_('Theme'), new CComboBox('theme', $this->data['theme'], null, $themes));
158
159// append auto-login & auto-logout to form list
160$autologoutCheckBox = (new CCheckBox('autologout_visible'))->setChecked(isset($this->data['autologout']));
161if (isset($this->data['autologout'])) {
162	$autologoutTextBox = (new CNumericBox('autologout', $this->data['autologout'], 4))
163		->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH);
164}
165else {
166	$autologoutTextBox = (new CNumericBox('autologout', 900, 4))
167		->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH)
168		->setAttribute('disabled', 'disabled');
169}
170
171if ($this->data['alias'] != ZBX_GUEST_USER) {
172	$userFormList->addRow(_('Auto-login'), (new CCheckBox('autologin'))->setChecked($this->data['autologin']));
173	$userFormList->addRow(_('Auto-logout (min 90 seconds)'), [
174		$autologoutCheckBox,
175		(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
176		$autologoutTextBox
177	]);
178}
179
180$userFormList
181	->addRow(_('Refresh (in seconds)'),
182		(new CNumericBox('refresh', $this->data['refresh'], 4))->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH)
183	)
184	->addRow(_('Rows per page'),
185		(new CNumericBox('rows_per_page', $this->data['rows_per_page'], 6))
186			->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH)
187	)
188	->addRow(_('URL (after login)'),
189		(new CTextBox('url', $this->data['url']))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
190	);
191
192/*
193 * Media tab
194 */
195if (uint_in_array(CWebUser::$data['type'], [USER_TYPE_ZABBIX_ADMIN, USER_TYPE_SUPER_ADMIN])) {
196	$userMediaFormList = new CFormList('userMediaFormList');
197	$userForm->addVar('user_medias', $this->data['user_medias']);
198
199	$mediaTableInfo = (new CTable())
200		->setAttribute('style', 'width: 100%;')
201		->setHeader([_('Type'), _('Send to'), _('When active'), _('Use if severity'), ('Status'), _('Action')]);
202
203	foreach ($this->data['user_medias'] as $id => $media) {
204		if (!isset($media['active']) || !$media['active']) {
205			$status = (new CLink(_('Enabled'), '#'))
206				->addClass(ZBX_STYLE_LINK_ACTION)
207				->addClass(ZBX_STYLE_GREEN)
208				->onClick('return create_var("'.$userForm->getName().'","disable_media",'.$id.', true);');
209		}
210		else {
211			$status = (new CLink(_('Disabled'), '#'))
212				->addClass(ZBX_STYLE_LINK_ACTION)
213				->addClass(ZBX_STYLE_RED)
214				->onClick('return create_var("'.$userForm->getName().'","enable_media",'.$id.', true);');
215		}
216
217		$mediaUrl = 'popup_media.php'.
218			'?dstfrm='.$userForm->getName().
219			'&media='.$id.
220			'&mediatypeid='.$media['mediatypeid'].
221			'&sendto='.urlencode($media['sendto']).
222			'&period='.$media['period'].
223			'&severity='.$media['severity'].
224			'&active='.$media['active'];
225
226		$mediaSeverity = [];
227
228		for ($severity = TRIGGER_SEVERITY_NOT_CLASSIFIED; $severity < TRIGGER_SEVERITY_COUNT; $severity++) {
229			$severityName = getSeverityName($severity, $this->data['config']);
230
231			$mediaActive = ($media['severity'] & (1 << $severity));
232
233			$mediaSeverity[$severity] = (new CSpan(mb_substr($severityName, 0, 1)))
234				->setHint($severityName.' ('.($mediaActive ? _('on') : _('off')).')', '', false)
235				->addClass($mediaActive ? ZBX_STYLE_GREEN : ZBX_STYLE_GREY);
236		}
237
238		$mediaTableInfo->addRow(
239			(new CRow([
240				$media['description'],
241				$media['sendto'],
242				$media['period'],
243				$mediaSeverity,
244				$status,
245				(new CCol(
246					new CHorList([
247						(new CButton(null, _('Edit')))
248							->addClass(ZBX_STYLE_BTN_LINK)
249							->onClick('return PopUp("'.$mediaUrl.'");'),
250						(new CButton(null, _('Remove')))
251							->addClass(ZBX_STYLE_BTN_LINK)
252							->onClick('javascript: removeMedia('.$id.');')
253					])
254				))->addClass(ZBX_STYLE_NOWRAP)
255			]))->setId('user_medias_'.$id)
256		);
257	}
258
259	$userMediaFormList->addRow(_('Media'),
260		(new CDiv([
261			$mediaTableInfo,
262			(new CButton(null, _('Add')))
263				->onClick('return PopUp("popup_media.php?dstfrm='.$userForm->getName().'");')
264				->addClass(ZBX_STYLE_BTN_LINK),
265		]))
266			->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
267			->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
268	);
269}
270
271/*
272 * Profile fields
273 */
274if ($this->data['is_profile']) {
275	$zbxSounds = getSounds();
276
277	$userMessagingFormList = new CFormList();
278	$userMessagingFormList->addRow(_('Frontend messaging'),
279		(new CCheckBox('messages[enabled]'))->setChecked($this->data['messages']['enabled'] == 1)
280	);
281	$userMessagingFormList->addRow(_('Message timeout (seconds)'),
282		(new CNumericBox('messages[timeout]', $this->data['messages']['timeout'], 5))
283			->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH),
284		'timeout_row'
285	);
286
287	$repeatSound = new CComboBox('messages[sounds.repeat]', $this->data['messages']['sounds.repeat'],
288		'if (IE) { submit() }',
289		[
290			1 => _('Once'),
291			10 => '10 '._('Seconds'),
292			-1 => _('Message timeout')
293		]
294	);
295	$userMessagingFormList->addRow(_('Play sound'), $repeatSound, 'repeat_row');
296
297	$soundList = new CComboBox('messages[sounds.recovery]', $this->data['messages']['sounds.recovery']);
298	foreach ($zbxSounds as $filename => $file) {
299		$soundList->addItem($file, $filename);
300	}
301
302	$triggersTable = (new CTable())
303		->addRow([
304			new CLabel([
305				(new CCheckBox('messages[triggers.recovery]'))
306					->setChecked($this->data['messages']['triggers.recovery'] == 1),
307				_('Recovery')], 'messages[triggers.recovery]'
308			),
309			[
310				$soundList,
311				(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
312				(new CButton('start', _('Play')))
313					->addClass(ZBX_STYLE_BTN_GREY)
314					->onClick("javascript: testUserSound('messages_sounds.recovery');"),
315				(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
316				(new CButton('stop', _('Stop')))
317					->addClass(ZBX_STYLE_BTN_GREY)
318					->onClick('javascript: AudioControl.stop();')
319			]
320		]);
321
322	$msgVisibility = ['1' => [
323		'messages[timeout]',
324		'messages[sounds.repeat]',
325		'messages[sounds.recovery]',
326		'messages[triggers.recovery]',
327		'timeout_row',
328		'repeat_row',
329		'triggers_row'
330	]];
331
332	// trigger sounds
333	for ($severity = TRIGGER_SEVERITY_NOT_CLASSIFIED; $severity < TRIGGER_SEVERITY_COUNT; $severity++) {
334		$soundList = new CComboBox('messages[sounds.'.$severity.']', $this->data['messages']['sounds.'.$severity]);
335		foreach ($zbxSounds as $filename => $file) {
336			$soundList->addItem($file, $filename);
337		}
338
339		$triggersTable->addRow([
340			new CLabel([
341				(new CCheckBox('messages[triggers.severities]['.$severity.']'))
342					->setChecked(isset($this->data['messages']['triggers.severities'][$severity])),
343				getSeverityName($severity, $this->data['config'])], 'messages[triggers.severities]['.$severity.']'
344			),
345			[
346				$soundList,
347				(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
348				(new CButton('start', _('Play')))
349					->addClass(ZBX_STYLE_BTN_GREY)
350					->onClick( "javascript: testUserSound('messages_sounds.".$severity."');"),
351				(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
352				(new CButton('stop', _('Stop')))
353					->addClass(ZBX_STYLE_BTN_GREY)
354					->onClick('javascript: AudioControl.stop();')
355			]
356		]);
357
358		zbx_subarray_push($msgVisibility, 1, 'messages[triggers.severities]['.$severity.']');
359		zbx_subarray_push($msgVisibility, 1, 'messages[sounds.'.$severity.']');
360	}
361
362	$userMessagingFormList->addRow(_('Trigger severity'), $triggersTable, 'triggers_row');
363}
364
365// append form lists to tab
366$userTab = new CTabView();
367if (!$this->data['form_refresh']) {
368	$userTab->setSelected(0);
369}
370$userTab->addTab('userTab', _('User'), $userFormList);
371if (isset($userMediaFormList)) {
372	$userTab->addTab('mediaTab', _('Media'), $userMediaFormList);
373}
374
375if (!$this->data['is_profile']) {
376	/*
377	 * Permissions tab
378	 */
379	$permissionsFormList = new CFormList('permissionsFormList');
380
381	$userTypeComboBox = new CComboBox('user_type', $this->data['user_type'], 'submit();', [
382		USER_TYPE_ZABBIX_USER => user_type2str(USER_TYPE_ZABBIX_USER),
383		USER_TYPE_ZABBIX_ADMIN => user_type2str(USER_TYPE_ZABBIX_ADMIN),
384		USER_TYPE_SUPER_ADMIN => user_type2str(USER_TYPE_SUPER_ADMIN)
385	]);
386
387	if ($data['userid'] != 0 && bccomp(CWebUser::$data['userid'], $data['userid']) == 0) {
388		$userTypeComboBox->setEnabled(false);
389		$permissionsFormList->addRow(_('User type'), [$userTypeComboBox, SPACE, new CSpan(_('User can\'t change type for himself'))]);
390		$userForm->addVar('user_type', $this->data['user_type']);
391	}
392	else {
393		$permissionsFormList->addRow(_('User type'), $userTypeComboBox);
394	}
395
396	$permissionsFormList = getPermissionsFormList($this->data['user_rights'], $this->data['user_type'], $permissionsFormList);
397	$permissionsFormList->addInfo(_('Permissions can be assigned for user groups only.'));
398
399	$userTab->addTab('permissionsTab', _('Permissions'), $permissionsFormList);
400}
401if (isset($userMessagingFormList)) {
402	$userTab->addTab('messagingTab', _('Messaging'), $userMessagingFormList);
403}
404
405// append buttons to form
406if ($data['userid'] != 0) {
407	$buttons = [
408		new CButtonCancel()
409	];
410
411	if (!$this->data['is_profile']) {
412		$deleteButton = new CButtonDelete(_('Delete selected user?'), url_param('form').url_param('userid'));
413		if (bccomp(CWebUser::$data['userid'], $data['userid']) == 0) {
414			$deleteButton->setAttribute('disabled', 'disabled');
415		}
416
417		array_unshift($buttons, $deleteButton);
418	}
419
420	$userTab->setFooter(makeFormFooter(new CSubmit('update', _('Update')), $buttons));
421}
422else {
423	$userTab->setFooter(makeFormFooter(
424		new CSubmit('add', _('Add')),
425		[new CButtonCancel()]
426	));
427}
428
429// append tab to form
430$userForm->addItem($userTab);
431
432// append form to widget
433$userWidget->addItem($userForm);
434
435return $userWidget;
436