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/audit.inc.php';
24require_once dirname(__FILE__).'/include/actions.inc.php';
25require_once dirname(__FILE__).'/include/users.inc.php';
26
27$page['title'] = _('Action log');
28$page['file'] = 'auditacts.php';
29$page['scripts'] = ['class.calendar.js', 'gtlc.js'];
30$page['type'] = detect_page_type(PAGE_TYPE_HTML);
31
32require_once dirname(__FILE__).'/include/page_header.php';
33
34// VAR	TYPE	OPTIONAL	FLAGS	VALIDATION	EXCEPTION
35$fields = [
36	// filter
37	'filter_rst' =>	[T_ZBX_STR, O_OPT, P_SYS,	null,	null],
38	'filter_set' =>	[T_ZBX_STR, O_OPT, P_SYS,	null,	null],
39	'alias' =>		[T_ZBX_STR, O_OPT, P_SYS,	null,	null],
40	'period' =>		[T_ZBX_INT, O_OPT, null,	null,	null],
41	'stime' =>		[T_ZBX_STR, O_OPT, null,	null,	null],
42	// ajax
43	'favobj' =>		[T_ZBX_STR, O_OPT, P_ACT,	null,	null],
44	'favid' =>		[T_ZBX_INT, O_OPT, P_ACT,	null,	null]
45];
46check_fields($fields);
47
48/*
49 * Ajax
50 */
51if (isset($_REQUEST['favobj'])) {
52	// saving fixed/dynamic setting to profile
53	if ($_REQUEST['favobj'] == 'timelinefixedperiod') {
54		if (isset($_REQUEST['favid'])) {
55			CProfile::update('web.auditacts.timelinefixed', $_REQUEST['favid'], PROFILE_TYPE_INT);
56		}
57	}
58}
59
60if ($page['type'] == PAGE_TYPE_JS || $page['type'] == PAGE_TYPE_HTML_BLOCK) {
61	require_once dirname(__FILE__).'/include/page_footer.php';
62	exit;
63}
64
65/*
66 * Filter
67 */
68if (hasRequest('filter_set')) {
69	CProfile::update('web.auditacts.filter.alias', getRequest('alias', ''), PROFILE_TYPE_STR);
70}
71elseif (hasRequest('filter_rst')) {
72	DBStart();
73	CProfile::delete('web.auditacts.filter.alias');
74	DBend();
75}
76
77/*
78 * Display
79 */
80$effectivePeriod = navigation_bar_calc('web.auditacts.timeline', 0, true);
81
82$data = [
83	'stime' => getRequest('stime'),
84	'alias' => CProfile::get('web.auditacts.filter.alias', ''),
85	'users' => [],
86	'alerts' => [],
87	'paging' => null
88];
89
90$userId = null;
91
92if ($data['alias']) {
93	$data['users'] = API::User()->get([
94		'output' => ['userid', 'alias', 'name', 'surname'],
95		'filter' => ['alias' => $data['alias']],
96		'preservekeys' => true
97	]);
98
99	if ($data['users']) {
100		$user = reset($data['users']);
101
102		$userId = $user['userid'];
103	}
104}
105
106if (!$data['alias'] || $data['users']) {
107	$from = zbxDateToTime($data['stime']);
108	$till = $from + $effectivePeriod;
109
110	$config = select_config();
111
112	// fetch alerts for different objects and sources and combine them in a single stream
113	foreach (eventSourceObjects() as $eventSource) {
114		$data['alerts'] = array_merge($data['alerts'], API::Alert()->get([
115			'output' => ['alertid', 'actionid', 'userid', 'clock', 'sendto', 'subject', 'message', 'status',
116				'retries', 'error', 'alerttype'
117			],
118			'selectMediatypes' => ['mediatypeid', 'description'],
119			'userids' => $userId,
120			'time_from' => $from,
121			'time_till' => $till,
122			'eventsource' => $eventSource['source'],
123			'eventobject' => $eventSource['object'],
124			'sortfield' => 'alertid',
125			'sortorder' => ZBX_SORT_DOWN,
126			'limit' => $config['search_limit'] + 1
127		]));
128	}
129
130	CArrayHelper::sort($data['alerts'], [
131		['field' => 'alertid', 'order' => ZBX_SORT_DOWN]
132	]);
133
134	$data['alerts'] = array_slice($data['alerts'], 0, $config['search_limit'] + 1);
135
136	// paging
137	$data['paging'] = getPagingLine($data['alerts'], ZBX_SORT_DOWN, new CUrl('auditacts.php'));
138
139	// get users
140	if (!$data['alias']) {
141		$data['users'] = API::User()->get([
142			'output' => ['userid', 'alias', 'name', 'surname'],
143			'userids' => zbx_objectValues($data['alerts'], 'userid'),
144			'preservekeys' => true
145		]);
146	}
147}
148
149// get first alert clock
150$firstAlert = null;
151if ($userId) {
152	$firstAlert = DBfetch(DBselect(
153		'SELECT MIN(a.clock) AS clock'.
154		' FROM alerts a'.
155		' WHERE a.userid='.zbx_dbstr($userId)
156	));
157}
158elseif ($data['alias'] === '') {
159	$firstAlert = DBfetch(DBselect('SELECT MIN(a.clock) AS clock FROM alerts a'));
160}
161$minStartTime = ($firstAlert) ? $firstAlert['clock'] - 1 : null;
162
163// get actions names
164if ($data['alerts']) {
165	$data['actions'] = API::Action()->get([
166		'output' => ['actionid', 'name'],
167		'actionids' => array_unique(zbx_objectValues($data['alerts'], 'actionid')),
168		'preservekeys' => true
169	]);
170}
171
172// timeline
173$data['timeline'] = [
174	'period' => $effectivePeriod,
175	'starttime' => date(TIMESTAMP_FORMAT, $minStartTime),
176	'usertime' => $data['stime'] ? date(TIMESTAMP_FORMAT, zbxDateToTime($data['stime']) + $effectivePeriod) : null
177];
178
179// render view
180$auditView = new CView('administration.auditacts.list', $data);
181$auditView->render();
182$auditView->show();
183
184require_once dirname(__FILE__).'/include/page_footer.php';
185