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