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.item.list.js.php';
23
24$widget = (new CWidget())
25	->setTitle(_('Items'))
26	->setControls(
27		(new CTag('nav', true,
28			(new CList())->addItem(
29				($data['hostid'] != 0)
30					? new CRedirectButton(_('Create item'), (new CUrl('items.php'))
31						->setArgument('form', 'create')
32						->setArgument('hostid', $data['hostid'])
33						->getUrl()
34					)
35					: (new CButton('form', _('Create item (select host first)')))->setEnabled(false)
36			)
37		))->setAttribute('aria-label', _('Content controls'))
38	);
39
40if (!empty($this->data['hostid'])) {
41	$widget->addItem(get_header_host_table('items', $this->data['hostid']));
42}
43$widget->addItem($this->data['flicker']);
44
45// create form
46$itemForm = (new CForm())->setName('items');
47if (!empty($this->data['hostid'])) {
48	$itemForm->addVar('hostid', $this->data['hostid']);
49}
50
51$url = (new CUrl('items.php'))
52	->setArgument('hostid', $data['hostid'])
53	->getUrl();
54
55// create table
56$itemTable = (new CTableInfo())
57	->setHeader([
58		(new CColHeader(
59			(new CCheckBox('all_items'))->onClick("checkAll('".$itemForm->getName()."', 'all_items', 'group_itemid');")
60		))->addClass(ZBX_STYLE_CELL_WIDTH),
61		_('Wizard'),
62		empty($this->data['filter_hostid']) ? _('Host') : null,
63		make_sorting_header(_('Name'), 'name', $data['sort'], $data['sortorder'], $url),
64		_('Triggers'),
65		make_sorting_header(_('Key'), 'key_', $data['sort'], $data['sortorder'], $url),
66		make_sorting_header(_('Interval'), 'delay', $data['sort'], $data['sortorder'], $url),
67		make_sorting_header(_('History'), 'history', $data['sort'], $data['sortorder'], $url),
68		make_sorting_header(_('Trends'), 'trends', $data['sort'], $data['sortorder'], $url),
69		make_sorting_header(_('Type'), 'type', $data['sort'], $data['sortorder'], $url),
70		_('Applications'),
71		make_sorting_header(_('Status'), 'status', $data['sort'], $data['sortorder'], $url),
72		_('Info')
73	]);
74
75if (!$this->data['filterSet']) {
76	$itemTable->setNoDataMessage(_('Specify some filter condition to see the items.'));
77}
78
79$current_time = time();
80
81$this->data['itemTriggers'] = CMacrosResolverHelper::resolveTriggerExpressions($this->data['itemTriggers'], [
82	'html' => true,
83	'sources' => ['expression', 'recovery_expression']
84]);
85
86$update_interval_parser = new CUpdateIntervalParser(['usermacros' => true]);
87
88foreach ($data['items'] as $item) {
89	// description
90	$description = [];
91	$description[] = makeItemTemplatePrefix($item['itemid'], $data['parent_templates'], ZBX_FLAG_DISCOVERY_NORMAL);
92
93	if (!empty($item['discoveryRule'])) {
94		$description[] = (new CLink(CHtml::encode($item['discoveryRule']['name']),
95			'disc_prototypes.php?parent_discoveryid='.$item['discoveryRule']['itemid']
96		))
97			->addClass(ZBX_STYLE_LINK_ALT)
98			->addClass(ZBX_STYLE_ORANGE);
99		$description[] = NAME_DELIMITER;
100	}
101
102	if ($item['type'] == ITEM_TYPE_DEPENDENT) {
103		if ($item['master_item']['type'] == ITEM_TYPE_HTTPTEST) {
104			$description[] = CHtml::encode($item['master_item']['name_expanded']);
105		}
106		else {
107			$description[] = (new CLink(CHtml::encode($item['master_item']['name_expanded']),
108				'?form=update&hostid='.$item['hostid'].'&itemid='.$item['master_item']['itemid']
109			))
110				->addClass(ZBX_STYLE_LINK_ALT)
111				->addClass(ZBX_STYLE_TEAL);
112		}
113
114		$description[] = NAME_DELIMITER;
115	}
116
117	$description[] = new CLink(CHtml::encode($item['name_expanded']),
118		'?form=update&hostid='.$item['hostid'].'&itemid='.$item['itemid']
119	);
120
121	// status
122	$status = new CCol((new CLink(
123		itemIndicator($item['status'], $item['state']),
124		'?group_itemid[]='.$item['itemid'].
125			'&hostid='.$item['hostid'].
126			'&action='.($item['status'] == ITEM_STATUS_DISABLED ? 'item.massenable' : 'item.massdisable')))
127		->addClass(ZBX_STYLE_LINK_ACTION)
128		->addClass(itemIndicatorStyle($item['status'], $item['state']))
129		->addSID()
130	);
131
132	// info
133	$info_icons = [];
134
135	if ($item['status'] == ITEM_STATUS_ACTIVE && !zbx_empty($item['error'])) {
136		$info_icons[] = makeErrorIcon($item['error']);
137	}
138
139	// discovered item lifetime indicator
140	if ($item['flags'] == ZBX_FLAG_DISCOVERY_CREATED && $item['itemDiscovery']['ts_delete'] != 0) {
141		$info_icons[] = getItemLifetimeIndicator($current_time, $item['itemDiscovery']['ts_delete']);
142	}
143
144	// triggers info
145	$triggerHintTable = (new CTableInfo())->setHeader([_('Severity'), _('Name'), _('Expression'), _('Status')]);
146
147	foreach ($item['triggers'] as $num => &$trigger) {
148		$trigger = $this->data['itemTriggers'][$trigger['triggerid']];
149
150		$trigger_description = [];
151		$trigger_description[] = makeTriggerTemplatePrefix($trigger['triggerid'], $data['trigger_parent_templates'],
152			ZBX_FLAG_DISCOVERY_NORMAL
153		);
154
155		$trigger['hosts'] = zbx_toHash($trigger['hosts'], 'hostid');
156
157		if ($trigger['flags'] == ZBX_FLAG_DISCOVERY_CREATED) {
158			$trigger_description[] = new CSpan(CHtml::encode($trigger['description']));
159		}
160		else {
161			$trigger_description[] = new CLink(
162				CHtml::encode($trigger['description']),
163				'triggers.php?form=update&hostid='.key($trigger['hosts']).'&triggerid='.$trigger['triggerid']
164			);
165		}
166
167		if ($trigger['state'] == TRIGGER_STATE_UNKNOWN) {
168			$trigger['error'] = '';
169		}
170
171		if ($trigger['recovery_mode'] == ZBX_RECOVERY_MODE_RECOVERY_EXPRESSION) {
172			$expression = [
173				_('Problem'), ': ', $trigger['expression'], BR(),
174				_('Recovery'), ': ', $trigger['recovery_expression']
175			];
176		}
177		else {
178			$expression = $trigger['expression'];
179		}
180
181		$triggerHintTable->addRow([
182			getSeverityCell($trigger['priority'], $this->data['config']),
183			$trigger_description,
184			$expression,
185			(new CSpan(triggerIndicator($trigger['status'], $trigger['state'])))
186				->addClass(triggerIndicatorStyle($trigger['status'], $trigger['state']))
187		]);
188	}
189	unset($trigger);
190
191	if ($triggerHintTable->getNumRows()) {
192		$triggerInfo = (new CLinkAction(_('Triggers')))->setHint($triggerHintTable);
193		$triggerInfo = [$triggerInfo];
194		$triggerInfo[] = CViewHelper::showNum($triggerHintTable->getNumRows());
195
196		$triggerHintTable = [];
197	}
198	else {
199		$triggerInfo = '';
200	}
201
202	if (in_array($item['value_type'], [ITEM_VALUE_TYPE_STR, ITEM_VALUE_TYPE_LOG, ITEM_VALUE_TYPE_TEXT])) {
203		$item['trends'] = '';
204	}
205
206	// Hide zeros for trapper, SNMP trap and dependent items.
207	if ($item['type'] == ITEM_TYPE_TRAPPER || $item['type'] == ITEM_TYPE_SNMPTRAP
208			|| $item['type'] == ITEM_TYPE_DEPENDENT) {
209		$item['delay'] = '';
210	}
211	elseif ($update_interval_parser->parse($item['delay']) == CParser::PARSE_SUCCESS) {
212		$item['delay'] = $update_interval_parser->getDelay();
213	}
214
215	$wizard = (new CSpan(
216		(new CButton(null))
217			->addClass(ZBX_STYLE_ICON_WZRD_ACTION)
218			->setMenuPopup(CMenuPopupHelper::getItem($item['itemid']))
219	))->addClass(ZBX_STYLE_REL_CONTAINER);
220
221	$itemTable->addRow([
222		new CCheckBox('group_itemid['.$item['itemid'].']', $item['itemid']),
223		$wizard,
224		empty($this->data['filter_hostid']) ? $item['host'] : null,
225		$description,
226		$triggerInfo,
227		CHtml::encode($item['key_']),
228		$item['delay'],
229		$item['history'],
230		$item['trends'],
231		item_type2str($item['type']),
232		CHtml::encode($item['applications_list']),
233		$status,
234		makeInformationList($info_icons)
235	]);
236}
237
238$massclearhistory = [
239	'name' => _('Clear history'),
240	'confirm' => _('Delete history of selected items?'),
241	'disabled' => $data['is_template']
242];
243
244// append table to form
245$itemForm->addItem([
246	$itemTable,
247	$this->data['paging'],
248	new CActionButtonList('action', 'group_itemid',
249		[
250			'item.massenable' => ['name' => _('Enable'), 'confirm' => _('Enable selected items?')],
251			'item.massdisable' => ['name' => _('Disable'), 'confirm' => _('Disable selected items?')],
252			'item.masscheck_now' => ['name' => _('Check now'), 'disabled' => $data['is_template']],
253			'item.massclearhistory' => $massclearhistory,
254			'item.masscopyto' => ['name' => _('Copy')],
255			'item.massupdateform' => ['name' => _('Mass update')],
256			'item.massdelete' => ['name' => _('Delete'), 'confirm' => _('Delete selected items?')]
257		],
258		$this->data['hostid']
259	)
260]);
261
262// append form to widget
263$widget->addItem($itemForm);
264
265return $widget;
266