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
21require_once dirname(__FILE__).'/js/configuration.item.list.js.php';
22
23if (empty($this->data['hostid'])) {
24	$create_button = (new CSubmit('form', _('Create item (select host first)')))->setEnabled(false);
25}
26else {
27	$create_button = new CSubmit('form', _('Create item'));
28}
29
30$widget = (new CWidget())
31	->setTitle(_('Items'))
32	->setControls((new CForm('get'))
33		->cleanItems()
34		->addVar('hostid', $this->data['hostid'])
35		->addItem((new CList())->addItem($create_button))
36	);
37
38if (!empty($this->data['hostid'])) {
39	$widget->addItem(get_header_host_table('items', $this->data['hostid']));
40}
41$widget->addItem($this->data['flicker']);
42
43// create form
44$itemForm = (new CForm())->setName('items');
45if (!empty($this->data['hostid'])) {
46	$itemForm->addVar('hostid', $this->data['hostid']);
47}
48
49$url = (new CUrl('items.php'))
50	->setArgument('hostid', $data['hostid'])
51	->getUrl();
52
53// create table
54$itemTable = (new CTableInfo())
55	->setHeader([
56		(new CColHeader(
57			(new CCheckBox('all_items'))->onClick("checkAll('".$itemForm->getName()."', 'all_items', 'group_itemid');")
58		))->addClass(ZBX_STYLE_CELL_WIDTH),
59		_('Wizard'),
60		empty($this->data['filter_hostid']) ? _('Host') : null,
61		make_sorting_header(_('Name'), 'name', $data['sort'], $data['sortorder'], $url),
62		_('Triggers'),
63		make_sorting_header(_('Key'), 'key_', $data['sort'], $data['sortorder'], $url),
64		make_sorting_header(_('Interval'), 'delay', $data['sort'], $data['sortorder'], $url),
65		make_sorting_header(_('History'), 'history', $data['sort'], $data['sortorder'], $url),
66		make_sorting_header(_('Trends'), 'trends', $data['sort'], $data['sortorder'], $url),
67		make_sorting_header(_('Type'), 'type', $data['sort'], $data['sortorder'], $url),
68		_('Applications'),
69		make_sorting_header(_('Status'), 'status', $data['sort'], $data['sortorder'], $url),
70		$data['showInfoColumn'] ? _('Info') : null
71	]);
72
73if (!$this->data['filterSet']) {
74	$itemTable->setNoDataMessage(_('Specify some filter condition to see the items.'));
75}
76
77$current_time = time();
78
79$this->data['itemTriggers'] =
80	CMacrosResolverHelper::resolveTriggerExpressions($this->data['itemTriggers'], ['html' => true]);
81
82foreach ($this->data['items'] as $item) {
83	// description
84	$description = [];
85	if (!empty($item['template_host'])) {
86		if (array_key_exists($item['template_host']['hostid'], $data['writable_templates'])) {
87			$description[] = (new CLink(CHtml::encode($item['template_host']['name']),
88				'?hostid='.$item['template_host']['hostid'].'&filter_set=1'
89			))
90				->addClass(ZBX_STYLE_LINK_ALT)
91				->addClass(ZBX_STYLE_GREY);
92		}
93		else {
94			$description[] = (new CSpan(CHtml::encode($item['template_host']['name'])))->addClass(ZBX_STYLE_GREY);
95		}
96
97		$description[] = NAME_DELIMITER;
98	}
99
100	if (!empty($item['discoveryRule'])) {
101		$description[] = (new CLink(
102			CHtml::encode($item['discoveryRule']['name']),
103			'disc_prototypes.php?parent_discoveryid='.$item['discoveryRule']['itemid']))
104			->addClass(ZBX_STYLE_LINK_ALT)
105			->addClass(ZBX_STYLE_ORANGE);
106		$description[] = NAME_DELIMITER.$item['name_expanded'];
107	}
108	else {
109		$description[] = new CLink(
110			CHtml::encode($item['name_expanded']),
111			'?form=update&hostid='.$item['hostid'].'&itemid='.$item['itemid']
112		);
113	}
114
115	// status
116	$status = new CCol((new CLink(
117		itemIndicator($item['status'], $item['state']),
118		'?group_itemid='.$item['itemid'].
119			'&hostid='.$item['hostid'].
120			'&action='.($item['status'] == ITEM_STATUS_DISABLED ? 'item.massenable' : 'item.massdisable')))
121		->addClass(ZBX_STYLE_LINK_ACTION)
122		->addClass(itemIndicatorStyle($item['status'], $item['state']))
123		->addSID()
124	);
125
126	// info
127	if ($data['showInfoColumn']) {
128		$infoIcons = [];
129
130		if ($item['status'] == ITEM_STATUS_ACTIVE && !zbx_empty($item['error'])) {
131			$infoIcons[] = makeErrorIcon($item['error']);
132		}
133
134		// discovered item lifetime indicator
135		if ($item['flags'] == ZBX_FLAG_DISCOVERY_CREATED && $item['itemDiscovery']['ts_delete'] != 0) {
136			if ($infoIcons) {
137				$infoIcons[] = SPACE;
138			}
139			$infoIcons[] = getItemLifetimeIndicator($current_time, $item['itemDiscovery']['ts_delete']);
140		}
141	}
142	else {
143		$infoIcons = null;
144	}
145
146	// triggers info
147	$triggerHintTable = (new CTableInfo())
148		->setHeader([
149			_('Severity'),
150			_('Name'),
151			_('Expression'),
152			_('Status')
153		]);
154
155	foreach ($item['triggers'] as $num => &$trigger) {
156		$trigger = $this->data['itemTriggers'][$trigger['triggerid']];
157		$trigger_description = [];
158
159		if ($trigger['templateid'] > 0) {
160			if (!isset($this->data['triggerRealHosts'][$trigger['triggerid']])) {
161				$trigger_description[] = (new CSpan('HOST'))->addClass(ZBX_STYLE_GREY);
162				$trigger_description[] = ':';
163			}
164			else {
165				$realHost = reset($this->data['triggerRealHosts'][$trigger['triggerid']]);
166
167				if (array_key_exists($realHost['hostid'], $data['writable_templates'])) {
168					$trigger_description[] = (new CLink(CHtml::encode($realHost['name']),
169						'triggers.php?hostid='.$realHost['hostid']
170					))->addClass(ZBX_STYLE_GREY);
171				}
172				else {
173					$trigger_description[] = (new CSpan(CHtml::encode($realHost['name'])))->addClass(ZBX_STYLE_GREY);
174				}
175
176				$trigger_description[] = ':';
177			}
178		}
179
180		$trigger['hosts'] = zbx_toHash($trigger['hosts'], 'hostid');
181
182		if ($trigger['flags'] == ZBX_FLAG_DISCOVERY_CREATED) {
183			$trigger_description[] = new CSpan(CHtml::encode($trigger['description']));
184		}
185		else {
186			$trigger_description[] = new CLink(
187				CHtml::encode($trigger['description']),
188				'triggers.php?form=update&hostid='.key($trigger['hosts']).'&triggerid='.$trigger['triggerid']
189			);
190		}
191
192		if ($trigger['state'] == TRIGGER_STATE_UNKNOWN) {
193			$trigger['error'] = '';
194		}
195
196		$trigger['functions'] = zbx_toHash($trigger['functions'], 'functionid');
197
198		$triggerHintTable->addRow([
199			getSeverityCell($trigger['priority'], $this->data['config']),
200			$trigger_description,
201			$trigger['expression'],
202			(new CSpan(triggerIndicator($trigger['status'], $trigger['state'])))
203				->addClass(triggerIndicatorStyle($trigger['status'], $trigger['state']))
204		]);
205
206		$item['triggers'][$num] = $trigger;
207	}
208	unset($trigger);
209
210	if (!empty($item['triggers'])) {
211		$triggerInfo = (new CSpan(_('Triggers')))
212			->addClass(ZBX_STYLE_LINK_ACTION)
213			->setHint($triggerHintTable);
214		$triggerInfo = [$triggerInfo];
215		$triggerInfo[] = CViewHelper::showNum(count($item['triggers']));
216
217		$triggerHintTable = [];
218	}
219	else {
220		$triggerInfo = SPACE;
221	}
222
223	// if item type is 'Log' we must show log menu
224	if (in_array($item['value_type'], [ITEM_VALUE_TYPE_LOG, ITEM_VALUE_TYPE_STR, ITEM_VALUE_TYPE_TEXT])) {
225		$triggers = [];
226
227		foreach ($item['triggers'] as $trigger) {
228			foreach ($trigger['functions'] as $function) {
229				if (!str_in_array($function['function'], ['regexp', 'iregexp'])) {
230					continue 2;
231				}
232			}
233
234			$triggers[] = [
235				'id' => $trigger['triggerid'],
236				'name' => $trigger['description']
237			];
238		}
239
240		$menuIcon = (new CSpan(
241			(new CButton(null))
242				->addClass(ZBX_STYLE_ICON_WZRD_ACTION)
243				->setMenuPopup(CMenuPopupHelper::getTriggerLog($item['itemid'], $item['name'], $triggers))
244		))->addClass(ZBX_STYLE_REL_CONTAINER);
245	}
246	else {
247		$menuIcon = '';
248	}
249
250	$checkBox = (new CCheckBox('group_itemid['.$item['itemid'].']', $item['itemid']))
251		->setEnabled(empty($item['discoveryRule']));
252
253	$itemTable->addRow([
254		$checkBox,
255		$menuIcon,
256		empty($this->data['filter_hostid']) ? $item['host'] : null,
257		$description,
258		$triggerInfo,
259		CHtml::encode($item['key_']),
260		($item['delay'] !== '') ? convertUnitsS($item['delay']) : '',
261		$item['history']._x('d', 'day short'),
262		($item['trends'] !== '') ? $item['trends']._x('d', 'day short') : '',
263		item_type2str($item['type']),
264		CHtml::encode($item['applications_list']),
265		$status,
266		$infoIcons
267	]);
268}
269
270zbx_add_post_js('cookie.prefix = "'.$this->data['hostid'].'";');
271
272// append table to form
273$itemForm->addItem([
274	$itemTable,
275	$this->data['paging'],
276	new CActionButtonList('action', 'group_itemid',
277		[
278			'item.massenable' => ['name' => _('Enable'), 'confirm' => _('Enable selected items?')],
279			'item.massdisable' => ['name' => _('Disable'), 'confirm' => _('Disable selected items?')],
280			'item.massclearhistory' => ['name' => _('Clear history'),
281				'confirm' => _('Delete history of selected items?')
282			],
283			'item.masscopyto' => ['name' => _('Copy')],
284			'item.massupdateform' => ['name' => _('Mass update')],
285			'item.massdelete' => ['name' => _('Delete'), 'confirm' => _('Delete selected items?')]
286		],
287		$this->data['hostid']
288	)
289]);
290
291// append form to widget
292$widget->addItem($itemForm);
293
294return $widget;
295