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__).'/include/config.inc.php';
23require_once dirname(__FILE__).'/include/actions.inc.php';
24require_once dirname(__FILE__).'/include/events.inc.php';
25require_once dirname(__FILE__).'/include/triggers.inc.php';
26require_once dirname(__FILE__).'/include/users.inc.php';
27require_once dirname(__FILE__).'/include/html.inc.php';
28
29$page['title'] = _('Event details');
30$page['file'] = 'tr_events.php';
31$page['type'] = detect_page_type();
32$page['scripts'] = ['layout.mode.js'];
33$page['web_layout_mode'] = CViewHelper::loadLayoutMode();
34
35require_once dirname(__FILE__).'/include/page_header.php';
36
37// VAR	TYPE	OPTIONAL	FLAGS	VALIDATION	EXCEPTION
38$fields = [
39	'triggerid' =>	[T_ZBX_INT, O_OPT, P_SYS,	DB_ID,		PAGE_TYPE_HTML.'=='.$page['type']],
40	'eventid' =>	[T_ZBX_INT, O_OPT, P_SYS,	DB_ID,		PAGE_TYPE_HTML.'=='.$page['type']],
41	// Ajax
42	'widget' =>		[T_ZBX_STR, O_OPT, P_ACT,	IN('"'.WIDGET_HAT_EVENTACTIONS.'","'.WIDGET_HAT_EVENTLIST.'"'), null],
43	'state' =>		[T_ZBX_INT, O_OPT, P_ACT,	IN('0,1'), null]
44];
45check_fields($fields);
46
47/*
48 * Ajax
49 */
50if (hasRequest('widget') && hasRequest('state')) {
51	CProfile::update('web.tr_events.hats.'.getRequest('widget').'.state', getRequest('state'), PROFILE_TYPE_INT);
52}
53
54if ($page['type'] == PAGE_TYPE_JS || $page['type'] == PAGE_TYPE_HTML_BLOCK) {
55	require_once dirname(__FILE__).'/include/page_footer.php';
56	exit;
57}
58
59// triggers
60$triggers = API::Trigger()->get([
61	'output' => API_OUTPUT_EXTEND,
62	'selectHosts' => API_OUTPUT_EXTEND,
63	'triggerids' => getRequest('triggerid')
64]);
65
66if (!$triggers) {
67	access_deny();
68}
69
70$trigger = reset($triggers);
71
72$events = API::Event()->get([
73	'output' => ['eventid', 'r_eventid', 'clock', 'ns', 'objectid', 'name', 'acknowledged', 'severity'],
74	'selectTags' => ['tag', 'value'],
75	'select_acknowledges' => ['clock', 'message', 'action', 'userid', 'old_severity', 'new_severity'],
76	'source' => EVENT_SOURCE_TRIGGERS,
77	'object' => EVENT_OBJECT_TRIGGER,
78	'eventids' => getRequest('eventid'),
79	'objectids' => getRequest('triggerid'),
80	'value' => TRIGGER_VALUE_TRUE
81]);
82
83if (!$events) {
84	access_deny();
85}
86$event = reset($events);
87
88$event['comments'] = ($trigger['comments'] !== '')
89	? CMacrosResolverHelper::resolveTriggerDescription(
90		[
91			'triggerid' => $trigger['triggerid'],
92			'expression' => $trigger['expression'],
93			'comments' => $trigger['comments'],
94			'clock' => $event['clock'],
95			'ns' => $event['ns']
96		],
97		['events' => true]
98	)
99	: '';
100
101if ($event['r_eventid'] != 0) {
102	$r_events = API::Event()->get([
103		'output' => ['correlationid', 'userid'],
104		'source' => EVENT_SOURCE_TRIGGERS,
105		'object' => EVENT_OBJECT_TRIGGER,
106		'eventids' => [$event['r_eventid']],
107		'objectids' => getRequest('triggerid')
108	]);
109
110	if ($r_events) {
111		$r_event = reset($r_events);
112
113		$event['correlationid'] = $r_event['correlationid'];
114		$event['userid'] = $r_event['userid'];
115	}
116}
117
118if ($trigger['opdata'] !== '') {
119	$event['opdata'] = (new CCol(CMacrosResolverHelper::resolveTriggerOpdata(
120		[
121			'triggerid' => $trigger['triggerid'],
122			'expression' => $trigger['expression'],
123			'opdata' => $trigger['opdata'],
124			'clock' => $event['clock'],
125			'ns' => $event['ns']
126		],
127		[
128			'events' => true,
129			'html' => true
130		]
131	)))
132		->addClass('opdata')
133		->addClass(ZBX_STYLE_WORDWRAP);
134}
135else {
136	$db_items = API::Item()->get([
137		'output' => ['itemid', 'hostid', 'name', 'key_', 'value_type', 'units', 'valuemapid'],
138		'triggerids' => $event['objectid']
139	]);
140	$db_items = CMacrosResolverHelper::resolveItemNames($db_items);
141	$event['opdata'] = (new CCol(CScreenProblem::getLatestValues($db_items)))->addClass('latest-values');
142}
143
144$config = select_config();
145$severity_config = [
146	'severity_name_0' => $config['severity_name_0'],
147	'severity_name_1' => $config['severity_name_1'],
148	'severity_name_2' => $config['severity_name_2'],
149	'severity_name_3' => $config['severity_name_3'],
150	'severity_name_4' => $config['severity_name_4'],
151	'severity_name_5' => $config['severity_name_5']
152];
153$actions = getEventDetailsActions($event);
154$users = API::User()->get([
155	'output' => ['alias', 'name', 'surname'],
156	'userids' => array_keys($actions['userids']),
157	'preservekeys' => true
158]);
159$mediatypes = API::Mediatype()->get([
160	'output' => ['maxattempts'],
161	'mediatypeids' => array_keys($actions['mediatypeids']),
162	'preservekeys' => true
163]);
164
165/*
166 * Display
167 */
168$event_tab = (new CDiv([
169	new CDiv([
170		(new CUiWidget(WIDGET_HAT_TRIGGERDETAILS, make_trigger_details($trigger, $event['eventid'])))
171			->setHeader(_('Trigger details')),
172		(new CUiWidget(WIDGET_HAT_EVENTDETAILS, make_event_details($event)))
173			->setHeader(_('Event details'))
174	]),
175	new CDiv([
176		(new CCollapsibleUiWidget(WIDGET_HAT_EVENTACTIONS,
177			makeEventDetailsActionsTable($actions, $users, $mediatypes, $severity_config)
178		))
179			->setExpanded((bool) CProfile::get('web.tr_events.hats.'.WIDGET_HAT_EVENTACTIONS.'.state', true))
180			->setHeader(_('Actions'), [], 'web.tr_events.hats.'.WIDGET_HAT_EVENTACTIONS.'.state')
181			->addClass(ZBX_STYLE_DASHBRD_WIDGET_FLUID),
182		(new CCollapsibleUiWidget(WIDGET_HAT_EVENTLIST, make_small_eventlist($event)))
183			->setExpanded((bool) CProfile::get('web.tr_events.hats.'.WIDGET_HAT_EVENTLIST.'.state', true))
184			->setHeader(_('Event list [previous 20]'), [], 'web.tr_events.hats.'.WIDGET_HAT_EVENTLIST.'.state')
185			->addClass(ZBX_STYLE_DASHBRD_WIDGET_FLUID)
186	])
187]))
188	->addClass(ZBX_STYLE_COLUMNS)
189	->addClass(ZBX_STYLE_COLUMNS_2);
190
191$script = (new CScriptTag(
192	'$.subscribe("acknowledge.create", function(event, response, overlay) {'.
193		'postMessageOk(response.message);'.
194		'location.href = location.href;'.
195	'});'
196))->setOnDocumentReady();
197
198(new CWidget())
199	->setTitle(_('Event details'))
200	->setWebLayoutMode($page['web_layout_mode'])
201	->setControls((new CTag('nav', true,
202		(new CList())
203			->addItem(get_icon('kioskmode', ['mode' => $page['web_layout_mode']]))
204		))
205		->setAttribute('aria-label', _('Content controls'))
206	)
207	->addItem($event_tab)
208	->addItem($script)
209	->show();
210
211require_once dirname(__FILE__).'/include/page_footer.php';
212