1<?php
2
3// Pandora FMS - http://pandorafms.com
4// ==================================================
5// Copyright (c) 2005-2011 Artica Soluciones Tecnologicas
6// Please see http://pandorafms.org for full contribution list
7
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the  GNU Lesser General Public License
10// as published by the Free Software Foundation; version 2
11
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17include_once($config['homedir'] . "/include/functions_ui.php");
18include_once($config['homedir'] . "/include/functions_tags.php");
19enterprise_include_once ('meta/include/functions_events_meta.php');
20enterprise_include_once ('meta/include/functions_agents_meta.php');
21enterprise_include_once ('meta/include/functions_modules_meta.php');
22
23
24/**
25 * @package Include
26 * @subpackage Events
27 */
28
29function events_get_all_fields() {
30
31	$columns = array();
32
33	$columns['id_evento'] = __('Event id');
34	$columns['evento'] = __('Event name');
35	$columns['id_agente'] = __('Agent name');
36	$columns['id_usuario'] = __('User');
37	$columns['id_grupo'] = __('Group');
38	$columns['estado'] = __('Status');
39	$columns['timestamp'] = __('Timestamp');
40	$columns['event_type'] = __('Event type');
41	$columns['id_agentmodule'] = __('Agent module');
42	$columns['id_alert_am'] = __('Alert');
43	$columns['criticity'] = __('Severity');
44	$columns['user_comment'] = __('Comment');
45	$columns['tags'] = __('Tags');
46	$columns['source'] = __('Source');
47	$columns['id_extra'] = __('Extra id');
48	$columns['owner_user'] = __('Owner');
49	$columns['ack_utimestamp'] = __('ACK Timestamp');
50	$columns['instructions'] = __('Instructions');
51	$columns['server_name'] = __('Server name');
52
53	return $columns;
54}
55
56/**
57 * Get all rows of events from the database, that
58 * pass the filter, and can get only some fields.
59 *
60 * @param mixed Filters elements. It can be an indexed array
61 * (keys would be the field name and value the expected value, and would be
62 * joined with an AND operator) or a string, including any SQL clause (without
63 * the WHERE keyword). Example:
64 * <code>
65 * Both are similars:
66 * db_get_all_rows_filter ('table', array ('disabled', 0));
67 * db_get_all_rows_filter ('table', 'disabled = 0');
68 *
69 * Both are similars:
70 * db_get_all_rows_filter ('table', array ('disabled' => 0, 'history_data' => 0), 'name', 'OR');
71 * db_get_all_rows_filter ('table', 'disabled = 0 OR history_data = 0', 'name');
72 * </code>
73 * @param mixed Fields of the table to retrieve. Can be an array or a coma
74 * separated string. All fields are retrieved by default
75 *
76 *
77 * @return mixed False in case of error or invalid values passed. Affected rows otherwise
78 */
79function events_get_events ($filter = false, $fields = false) {
80	if ($filter['criticity'] == EVENT_CRIT_WARNING_OR_CRITICAL) {
81		$filter['criticity'] = array(EVENT_CRIT_WARNING, EVENT_CRIT_CRITICAL);
82	}
83
84	return db_get_all_rows_filter ('tevento', $filter, $fields);
85}
86
87/**
88 * Get the event with the id pass as parameter.
89 *
90 * @param int $id Event id
91 * @param mixed $fields The fields to show or by default all with false.
92 *
93 * @return mixed False in case of error or invalid values passed. Event row otherwise
94 */
95function events_get_event ($id, $fields = false) {
96	if (empty ($id))
97		return false;
98	global $config;
99
100	if (is_array ($fields)) {
101		if (! in_array ('id_grupo', $fields))
102			$fields[] = 'id_grupo';
103	}
104
105	$event = db_get_row ('tevento', 'id_evento', $id, $fields);
106	if (! check_acl ($config['id_user'], $event['id_grupo'], 'ER'))
107		return false;
108
109	return $event;
110}
111
112function events_get_events_grouped($sql_post, $offset = 0,
113	$pagination = 1, $meta = false, $history = false, $total = false) {
114
115	global $config;
116
117	$table = events_get_events_table($meta, $history);
118
119	if ($meta) {
120		$groupby_extra = ', server_id';
121	}
122	else {
123		$groupby_extra = '';
124	}
125
126	switch ($config["dbtype"]) {
127		case "mysql":
128			db_process_sql ('SET group_concat_max_len = 9999999');
129			if ($total) {
130				$sql = "SELECT COUNT(*) FROM (SELECT *
131					FROM $table te
132					WHERE 1=1 " . $sql_post . "
133					GROUP BY estado, evento, id_agentmodule" . $groupby_extra . ") AS t";
134			}
135			else {
136				$sql = "SELECT *, MAX(id_evento) AS id_evento,
137						GROUP_CONCAT(DISTINCT user_comment SEPARATOR '<br>') AS user_comment,
138						GROUP_CONCAT(DISTINCT id_evento SEPARATOR ',') AS similar_ids,
139						COUNT(*) AS event_rep, MAX(utimestamp) AS timestamp_rep,
140						MIN(utimestamp) AS timestamp_rep_min,
141						(SELECT owner_user FROM $table WHERE id_evento = MAX(te.id_evento)) owner_user,
142						(SELECT id_usuario FROM $table WHERE id_evento = MAX(te.id_evento)) id_usuario,
143						(SELECT id_agente FROM $table WHERE id_evento = MAX(te.id_evento)) id_agente,
144						(SELECT criticity FROM $table WHERE id_evento = MAX(te.id_evento)) AS criticity,
145						(SELECT ack_utimestamp FROM $table WHERE id_evento = MAX(te.id_evento)) AS ack_utimestamp
146					FROM $table te
147					WHERE 1=1 " . $sql_post . "
148					GROUP BY estado, evento, id_agentmodule" . $groupby_extra . "
149					ORDER BY timestamp_rep DESC LIMIT " . $offset . "," . $pagination;
150			}
151			break;
152		case "postgresql":
153			if ($total) {
154				$sql = "SELECT COUNT(*)
155					FROM $table te
156					WHERE 1=1 " . $sql_post . "
157					GROUP BY estado, evento, id_agentmodule, id_evento, id_agente, id_usuario, id_grupo, estado, timestamp, utimestamp, event_type, id_alert_am, criticity, user_comment, tags, source, id_extra" . $groupby_extra;
158			}
159			else {
160				$sql = "SELECT *, MAX(id_evento) AS id_evento, array_to_string(array_agg(DISTINCT user_comment), '<br>') AS user_comment,
161						array_to_string(array_agg(DISTINCT id_evento), ',') AS similar_ids,
162						COUNT(*) AS event_rep, MAX(utimestamp) AS timestamp_rep,
163						MIN(utimestamp) AS timestamp_rep_min,
164						(SELECT owner_user FROM $table WHERE id_evento = MAX(te.id_evento)) owner_user,
165						(SELECT id_usuario FROM $table WHERE id_evento = MAX(te.id_evento)) id_usuario,
166						(SELECT id_agente FROM $table WHERE id_evento = MAX(te.id_evento)) id_agente,
167						(SELECT criticity FROM $table WHERE id_evento = MAX(te.id_evento)) AS criticity,
168						(SELECT ack_utimestamp FROM $table WHERE id_evento = MAX(te.id_evento)) AS ack_utimestamp
169					FROM $table te
170					WHERE 1=1 " . $sql_post . "
171					GROUP BY estado, evento, id_agentmodule, id_evento,
172						id_agente, id_usuario, id_grupo, estado,
173						timestamp, utimestamp, event_type, id_alert_am,
174						criticity, user_comment, tags, source, id_extra,
175						te.critical_instructions,
176						te.warning_instructions,
177						te.unknown_instructions,
178						te.owner_user,
179						te.ack_utimestamp,
180						te.custom_data " . $groupby_extra . "
181					ORDER BY timestamp_rep DESC LIMIT " . $pagination . " OFFSET " . $offset;
182			}
183			break;
184		case "oracle":
185			if ($total) {
186				$sql = "SELECT COUNT(*)
187						FROM $table te
188						WHERE 1=1 $sql_post
189						GROUP BY estado, to_char(evento), id_agentmodule" . $groupby_extra . ") b ";
190			}
191			else {
192				$set = array();
193				$set['limit'] = $pagination;
194				$set['offset'] = $offset;
195
196				$sql = "SELECT ta.*, tb.event_rep, tb.timestamp_rep, tb.timestamp_rep_min, tb.user_comments, tb.similar_ids
197						FROM $table ta
198						INNER JOIN (SELECT MAX(id_evento) AS id_evento, COUNT(id_evento) AS event_rep,
199										MAX(utimestamp) AS timestamp_rep, MIN(utimestamp) AS timestamp_rep_min,
200										TAB_TO_STRING(CAST(COLLECT(TO_CHAR(user_comment) ORDER BY id_evento ASC) AS t_varchar2_tab), '<br>') AS user_comments,
201										TAB_TO_STRING(CAST(COLLECT(CAST(id_evento AS VARCHAR2(4000)) ORDER BY id_evento ASC) AS t_varchar2_tab)) AS similar_ids
202									FROM $table te
203									WHERE 1=1 $sql_post
204									GROUP BY estado, to_char(evento), id_agentmodule$groupby_extra) tb
205							ON ta.id_evento = tb.id_evento
206						ORDER BY tb.timestamp_rep DESC";
207				$sql = oracle_recode_query ($sql, $set);
208			}
209			break;
210	}
211
212	//Extract the events by filter (or not) from db
213	$events = db_get_all_rows_sql ($sql);
214
215	if ($total) {
216		return reset($events[0]);
217	}
218	else {
219		// Override the column 'user_comment' with the column 'user_comments' when oracle
220		if (!empty($events) && $config["dbtype"] == "oracle") {
221			array_walk($events, function(&$value, $key) {
222				set_if_defined($value['user_comments'], $value['user_comments']);
223			});
224		}
225
226		return $events;
227	}
228}
229
230function events_get_total_events_grouped($sql_post, $meta = false, $history = false) {
231	return events_get_events_grouped($sql_post, 0, 0, $meta, $history, true);
232}
233
234/**
235 * Get all the events ids similar to a given event id.
236 *
237 * An event is similar then the event text (evento) and the id_agentmodule are
238 * the same.
239 *
240 * @param int Event id to get similar events.
241 * @param bool Metaconsole mode flag
242 * @param bool History mode flag
243 *
244 * @return array A list of events ids.
245 */
246function events_get_similar_ids ($id, $meta = false, $history = false) {
247	$events_table = events_get_events_table($meta, $history);
248
249	$ids = array ();
250	if($meta) {
251		$event = events_meta_get_event($id, array ('evento', 'id_agentmodule'), $history);
252	}
253	else {
254		$event = events_get_event ($id, array ('evento', 'id_agentmodule'));
255	}
256	if ($event === false)
257		return $ids;
258
259	$events = db_get_all_rows_filter ($events_table,
260		array ('evento' => $event['evento'],
261			'id_agentmodule' => $event['id_agentmodule']),
262		array ('id_evento'));
263	if ($events === false)
264		return $ids;
265
266	foreach ($events as $event)
267		$ids[] = $event['id_evento'];
268
269	return $ids;
270}
271
272/**
273 * Delete events in a transresponse
274 *
275 * @param mixed Event ID or array of events
276 * @param bool Whether to delete similar events too.
277 * @param bool Metaconsole mode flag
278 * @param bool History mode flag
279 *
280 * @return bool Whether or not it was successful
281 */
282function events_delete_event ($id_event, $similar = true, $meta = false, $history = false) {
283	global $config;
284
285	$table_event = events_get_events_table($meta, $history);
286
287	//Cleans up the selection for all unwanted values also casts any single values as an array
288	$id_event = (array) safe_int ($id_event, 1);
289
290	/* We must delete all events like the selected */
291	if ($similar) {
292		foreach ($id_event as $id) {
293			$id_event = array_merge ($id_event, events_get_similar_ids ($id, $meta, $history));
294		}
295		$id_event = array_unique($id_event);
296	}
297
298	$errors = 0;
299
300	foreach ($id_event as $event) {
301		if ($meta) {
302			$event_group = events_meta_get_group ($event, $history);
303		}
304		else {
305			$event_group = events_get_group ($event);
306		}
307
308		if (check_acl ($config["id_user"], $event_group, "EM") == 0) {
309			//Check ACL
310			db_pandora_audit("ACL Violation", "Attempted deleting event #".$event);
311			$errors++;
312		}
313		else {
314			$ret = db_process_sql_delete($table_event, array('id_evento' => $event));
315
316			if(!$ret) {
317				$errors++;
318			}
319			else {
320				db_pandora_audit("Event deleted", "Deleted event #".$event);
321				//ACL didn't fail nor did return
322				continue;
323			}
324		}
325
326		break;
327	}
328
329	if ($errors > 0) {
330		return false;
331	}
332	else {
333		return true;
334	}
335}
336
337/**
338 * Change the status of one or various events
339 *
340 * @param mixed Event ID or array of events
341 * @param int new status of the event
342 * @param bool metaconsole mode flag
343 * @param bool history mode flag
344 *
345 * @return bool Whether or not it was successful
346 */
347function events_change_status ($id_event, $new_status, $meta = false, $history = false) {
348	global $config;
349
350	$event_table = events_get_events_table($meta, $history);
351
352	//Cleans up the selection for all unwanted values also casts any single values as an array
353	$id_event = (array) safe_int ($id_event, 1);
354
355	// Update ack info if the new status is validated
356	if ($new_status == EVENT_STATUS_VALIDATED) {
357		$ack_utimestamp = time();
358		$ack_user = $config['id_user'];
359	}
360	else {
361		$acl_utimestamp = 0;
362		$ack_user = '';
363	}
364
365	switch ($new_status) {
366		case EVENT_STATUS_NEW:
367			$status_string = 'New';
368			break;
369		case EVENT_STATUS_VALIDATED:
370			$status_string = 'Validated';
371			break;
372		case EVENT_STATUS_INPROCESS:
373			$status_string = 'In process';
374			break;
375		default:
376			$status_string = '';
377			break;
378	}
379
380	$alerts = array();
381
382	foreach ($id_event as $k => $id) {
383		if ($meta) {
384			$event_group = events_meta_get_group ($id, $history);
385			$event = events_meta_get_event ($id, false, $history);
386			$server_id = $event['server_id'];
387		}
388		else {
389			$event_group = events_get_group ($id);
390			$event = events_get_event ($id);
391		}
392
393		if ($event['id_alert_am'] > 0 && !in_array($event['id_alert_am'], $alerts)) {
394			$alerts[] = $event['id_alert_am'];
395		}
396
397		if (check_acl ($config["id_user"], $event_group, "EW") == 0) {
398			db_pandora_audit("ACL Violation", "Attempted updating event #".$id);
399
400			unset($id_event[$k]);
401		}
402	}
403
404	if (empty($id_event)) {
405		return false;
406	}
407
408	$values = array(
409		'estado' => $new_status,
410		'id_usuario' => $ack_user,
411		'ack_utimestamp' => $ack_utimestamp);
412
413	$ret = db_process_sql_update($event_table, $values,
414		array('id_evento' => $id_event));
415
416	if (($ret === false) || ($ret === 0)) {
417		return false;
418	}
419
420	events_comment($id_event, '', "Change status to $status_string", $meta, $history);
421
422	if ($meta && !empty($alerts)) {
423		$server = metaconsole_get_connection_by_id ($server_id);
424		metaconsole_connect($server);
425	}
426
427	// Put the alerts in standby or not depends the new status
428	foreach ($alerts as $alert) {
429		switch ($new_status) {
430			case EVENT_NEW:
431			case EVENT_VALIDATE:
432				alerts_agent_module_standby ($alert, 0);
433				break;
434			case EVENT_PROCESS:
435				alerts_agent_module_standby ($alert, 1);
436				break;
437		}
438	}
439
440	if ($meta && !empty($alerts)) {
441		metaconsole_restore_db();
442	}
443
444	return true;
445}
446
447/**
448 * Change the owner of an event if the event hasn't owner
449 *
450 * @param mixed Event ID or array of events
451 * @param string id_user of the new owner. If is false, the current owner will be setted
452 * @param bool flag to force the change or not (not force is change only when it hasn't owner)
453 * @param bool metaconsole mode flag
454 * @param bool history mode flag
455 *
456 * @return bool Whether or not it was successful
457 */
458function events_change_owner ($id_event, $new_owner = false, $force = false, $meta = false, $history = false) {
459	global $config;
460
461	$event_table = events_get_events_table($meta, $history);
462
463	//Cleans up the selection for all unwanted values also casts any single values as an array
464	$id_event = (array) safe_int ($id_event, 1);
465
466	foreach ($id_event as $k => $id) {
467		if ($meta) {
468			$event_group = events_meta_get_group ($id, $history);
469		}
470		else {
471			$event_group = events_get_group ($id);
472		}
473		if (check_acl ($config["id_user"], $event_group, "EW") == 0) {
474			db_pandora_audit("ACL Violation", "Attempted updating event #".$id);
475			unset($id_event[$k]);
476		}
477	}
478
479	if (empty($id_event)) {
480		return false;
481	}
482
483	// If no new_owner is provided, the current user will be the owner
484	// ** Comment this lines because if possible selected None owner in owner event. TIQUET: #2250***
485	//if (empty($new_owner)) {
486	//	$new_owner = $config['id_user'];
487	//}
488
489	// Only generate comment when is forced (sometimes is changed the owner when comment)
490	if ($force) {
491		events_comment($id_event, '', "Change owner to $new_owner", $meta, $history);
492	}
493
494	$values = array('owner_user' => $new_owner);
495
496	$where = array('id_evento' => $id_event);
497
498	// If not force, add to where if owner_user = ''
499	if (!$force) {
500		$where['owner_user'] = '';
501	}
502
503	$ret = db_process_sql_update($event_table, $values,
504		$where, 'AND', false);
505
506	if (($ret === false) || ($ret === 0)) {
507		return false;
508	}
509
510	return true;
511}
512
513function events_get_events_table($meta, $history) {
514	if ($meta) {
515		if ($history) {
516			$event_table = 'tmetaconsole_event_history';
517		}
518		else {
519			$event_table = 'tmetaconsole_event';
520		}
521	}
522	else {
523		$event_table = 'tevento';
524	}
525
526	return $event_table;
527}
528
529/**
530 * Comment events in a transresponse
531 *
532 * @param mixed Event ID or array of events
533 * @param string comment to be registered
534 * @param string action performed with the comment. Bu default just Added comment
535 * @param bool Flag of metaconsole mode
536 * @param bool Flag of history mode
537 *
538 * @return bool Whether or not it was successful
539 */
540function events_comment ($id_event, $comment = '', $action = 'Added comment', $meta = false, $history = false, $similars = true) {
541	global $config;
542
543	$event_table = events_get_events_table($meta, $history);
544
545	//Cleans up the selection for all unwanted values also casts any single values as an array
546	$id_event = (array) safe_int ($id_event, 1);
547
548	foreach ($id_event as $k => $id) {
549		if ($meta) {
550			$event_group = events_meta_get_group ($id, $history);
551		}
552		else {
553			$event_group = events_get_group ($id);
554		}
555		if (check_acl ($config["id_user"], $event_group, "EW") == 0) {
556			db_pandora_audit("ACL Violation", "Attempted updating event #".$id);
557
558			unset($id_event[$k]);
559		}
560	}
561
562	if (empty($id_event)) {
563		return false;
564	}
565
566	// If the event hasn't owner, assign the user as owner
567	events_change_owner ($id_event);
568
569	// Get the current event comments
570	$first_event = $id_event;
571	if (is_array($id_event)) {
572		$first_event = reset($id_event);
573	}
574	$event_comments = db_get_value('user_comment', $event_table, 'id_evento', $first_event);
575	$event_comments_array = array();
576
577	if ($event_comments == '') {
578		$comments_format = 'new';
579	}
580	else {
581		// If comments are not stored in json, the format is old
582		$event_comments_array = json_decode($event_comments);
583
584		if (is_null($event_comments_array)) {
585			$comments_format = 'old';
586		}
587		else {
588			$comments_format = 'new';
589		}
590	}
591
592	switch($comments_format) {
593		case 'new':
594			$comment_for_json['comment'] = $comment;
595			$comment_for_json['action'] = $action;
596			$comment_for_json['id_user'] = $config['id_user'];
597			$comment_for_json['utimestamp'] = time();
598
599			$event_comments_array[] = $comment_for_json;
600
601			$event_comments = io_json_mb_encode($event_comments_array);
602
603			// Update comment
604			$ret = db_process_sql_update($event_table,  array('user_comment' => $event_comments), array('id_evento' => implode(',', $id_event)));
605		break;
606		case 'old':
607			// Give old ugly format to comment. TODO: Change this method for aux table or json
608			$comment = str_replace(array("\r\n", "\r", "\n"), '<br>', $comment);
609
610			if ($comment != '') {
611				$commentbox = '<div style="border:1px dotted #CCC; min-height: 10px;">'.$comment.'</div>';
612			}
613			else {
614				$commentbox = '';
615			}
616
617			// Don't translate 'by' word because if various users with different languages
618			// make comments in the same console will be a mess
619			$comment = '<b>-- ' . $action . ' by '.$config['id_user'].' '.'['.date ($config["date_format"]).'] --</b><br>'.$commentbox.'<br>';
620
621			// Update comment
622			switch ($config['dbtype']) {
623				// Oldstyle SQL to avoid innecesary PHP foreach
624				case 'mysql':
625					$sql_validation = "UPDATE $event_table
626						SET user_comment = concat('" . $comment . "', user_comment)
627						WHERE id_evento in (" . implode(',', $id_event) . ")";
628
629					$ret = db_process_sql($sql_validation);
630					break;
631				case 'postgresql':
632				case 'oracle':
633					$sql_validation = "UPDATE $event_table
634						SET user_comment='" . $comment . "' || user_comment)
635						WHERE id_evento in (" . implode(',', $id_event) . ")";
636
637					$ret = db_process_sql($sql_validation);
638					break;
639			}
640		break;
641	}
642
643	if (($ret === false) || ($ret === 0)) {
644		return false;
645	}
646
647	return true;
648}
649
650/**
651 * Get group id of an event.
652 *
653 * @param int $id_event Event id
654 *
655 * @return int Group id of the given event.
656 */
657function events_get_group ($id_event) {
658	return (int) db_get_value ('id_grupo', 'tevento', 'id_evento', (int) $id_event);
659}
660
661/**
662 * Get description of an event.
663 *
664 * @param int $id_event Event id.
665 *
666 * @return string Description of the given event.
667 */
668function events_get_description ($id_event) {
669	return (string) db_get_value ('evento', 'tevento', 'id_evento', (int) $id_event);
670}
671
672/**
673 * Insert a event in the event log system.
674 *
675 * @param int $event
676 * @param int $id_group
677 * @param int $id_agent
678 * @param int $status
679 * @param string $id_user
680 * @param string $event_type
681 * @param int $priority
682 * @param int $id_agent_module
683 * @param int $id_aam
684 *
685 * @return int event id
686 */
687function events_create_event ($event, $id_group, $id_agent, $status = 0,
688	$id_user = "", $event_type = "unknown", $priority = 0,
689	$id_agent_module = 0, $id_aam = 0, $critical_instructions = '',
690	$warning_instructions = '', $unknown_instructions = '',
691	$source="Pandora", $tags="", $custom_data="", $server_id = 0) {
692
693	global $config;
694
695	$table_events = 'tevento';
696	if (defined ('METACONSOLE')) {
697		$table_events = 'tmetaconsole_event';
698
699		switch ($config["dbtype"]) {
700			case "mysql":
701				$sql = sprintf ('
702					INSERT INTO ' . $table_events . ' (id_agente, id_grupo, evento,
703						timestamp, estado, utimestamp, id_usuario,
704						event_type, criticity, id_agentmodule, id_alert_am,
705						critical_instructions, warning_instructions,
706						unknown_instructions, source, tags, custom_data,
707						server_id)
708					VALUES (%d, %d, "%s", NOW(), %d, UNIX_TIMESTAMP(NOW()),
709						"%s", "%s", %d, %d, %d, "%s", "%s", "%s", "%s",
710						"%s", "%s", %d)',
711					$id_agent, $id_group, $event, $status, $id_user,
712					$event_type, $priority, $id_agent_module, $id_aam,
713					$critical_instructions, $warning_instructions,
714					$unknown_instructions, $source, $tags, $custom_data,
715					$server_id);
716				break;
717			case "postgresql":
718				$sql = sprintf ('
719					INSERT INTO ' . $table_events . ' (id_agente, id_grupo, evento,
720						timestamp, estado, utimestamp, id_usuario,
721						event_type, criticity, id_agentmodule, id_alert_am,
722						critical_instructions, warning_instructions,
723						unknown_instructions, source, tags, custom_data,
724						server_id)
725					VALUES (%d, %d, "%s", NOW(), %d,
726						ceil(date_part(\'epoch\', CURRENT_TIMESTAMP)), "%s",
727						"%s", %d, %d, %d, "%s", "%s", "%s", "%s", "%s",
728						"%s", %d)',
729					$id_agent, $id_group, $event, $status, $id_user,
730					$event_type, $priority, $id_agent_module, $id_aam,
731					$critical_instructions, $warning_instructions,
732					$unknown_instructions, $source, $tags, $custom_data,
733					$server_id);
734				break;
735			case "oracle":
736				$sql = sprintf ('
737					INSERT INTO ' . $table_events . ' (id_agente, id_grupo, evento,
738						timestamp, estado, utimestamp, id_usuario,
739						event_type, criticity, id_agentmodule, id_alert_am,
740						critical_instructions, warning_instructions,
741						unknown_instructions, source, tags, custom_data,
742						server_id)
743					VALUES (%d, %d, "%s", CURRENT_TIMESTAMP, %d, UNIX_TIMESTAMP,
744						"%s", "%s", %d, %d, %d, "%s", "%s", "%s", "%s",
745						"%s", "%s", %d)',
746					$id_agent, $id_group, $event, $status, $id_user,
747					$event_type, $priority, $id_agent_module, $id_aam,
748					$critical_instructions, $warning_instructions,
749					$unknown_instructions, $source, $tags, $custom_data,
750					$server_id);
751				break;
752		}
753	}
754	else {
755		switch ($config["dbtype"]) {
756			case "mysql":
757				$sql = sprintf ('
758					INSERT INTO ' . $table_events . ' (id_agente, id_grupo, evento,
759						timestamp, estado, utimestamp, id_usuario,
760						event_type, criticity, id_agentmodule, id_alert_am,
761						critical_instructions, warning_instructions,
762						unknown_instructions, source, tags, custom_data)
763					VALUES (%d, %d, "%s", NOW(), %d, UNIX_TIMESTAMP(NOW()),
764						"%s", "%s", %d, %d, %d, "%s", "%s", "%s", "%s", "%s", "%s")',
765					$id_agent, $id_group, $event, $status, $id_user,
766					$event_type, $priority, $id_agent_module, $id_aam,
767					$critical_instructions, $warning_instructions,
768					$unknown_instructions, $source, $tags, $custom_data);
769				break;
770			case "postgresql":
771				$sql = sprintf ('
772					INSERT INTO ' . $table_events . ' (id_agente, id_grupo, evento,
773						timestamp, estado, utimestamp, id_usuario,
774						event_type, criticity, id_agentmodule, id_alert_am,
775						critical_instructions, warning_instructions,
776						unknown_instructions, source, tags, custom_data)
777					VALUES (%d, %d, "%s", NOW(), %d,
778						ceil(date_part(\'epoch\', CURRENT_TIMESTAMP)), "%s",
779						"%s", %d, %d, %d, "%s", "%s", "%s", "%s", "%s", "%s")',
780					$id_agent, $id_group, $event, $status, $id_user,
781					$event_type, $priority, $id_agent_module, $id_aam,
782					$critical_instructions, $warning_instructions,
783					$unknown_instructions, $source, $tags, $custom_data);
784				break;
785			case "oracle":
786				$sql = sprintf ("
787					INSERT INTO " . $table_events . " (id_agente, id_grupo, evento,
788						timestamp, estado, utimestamp, id_usuario,
789						event_type, criticity, id_agentmodule, id_alert_am,
790						critical_instructions, warning_instructions,
791						unknown_instructions, source, tags, custom_data)
792					VALUES (%d, %d, '%s', CURRENT_TIMESTAMP, %d, UNIX_TIMESTAMP,
793						'%s', '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s')",
794					$id_agent, $id_group, $event, $status, $id_user,
795					$event_type, $priority, $id_agent_module, $id_aam,
796					$critical_instructions, $warning_instructions,
797					$unknown_instructions, $source, $tags, $custom_data);
798				break;
799		}
800	}
801	return (int) db_process_sql ($sql, "insert_id");
802}
803
804
805/**
806 * Prints a small event table
807 *
808 * @param string $filter SQL WHERE clause
809 * @param int $limit How many events to show
810 * @param int $width How wide the table should be
811 * @param bool $return Prints out HTML if false
812 * @param int agent id if is the table of one agent. 0 otherwise
813 *
814 * @return string HTML with table element
815 */
816function events_print_event_table ($filter = "", $limit = 10, $width = 440, $return = false, $agent_id = 0, $tactical_view = false) {
817	global $config;
818
819	if ($agent_id == 0) {
820		$agent_condition = '';
821	}
822	else {
823		$agent_condition = " id_agente = $agent_id AND ";
824	}
825
826	if ($filter == '') {
827		$filter = '1 = 1';
828	}
829
830	switch ($config["dbtype"]) {
831		case "mysql":
832		case "postgresql":
833				$sql = sprintf ("SELECT *
834					FROM tevento
835					WHERE %s %s
836					ORDER BY utimestamp DESC LIMIT %d", $agent_condition, $filter, $limit);
837			break;
838		case "oracle":
839				$sql = sprintf ("SELECT *
840					FROM tevento
841					WHERE %s %s AND rownum <= %d
842					ORDER BY utimestamp DESC", $agent_condition, $filter, $limit);
843			break;
844	}
845
846	$result = db_get_all_rows_sql ($sql);
847
848	if ($result === false) {
849		if ($return) {
850			$returned = ui_print_info_message (__('No events'), '', true);
851			return $returned;
852		}
853		else {
854			echo ui_print_info_message (__('No events'));
855		}
856	}
857	else {
858		$table = new stdClass();
859		$table->id = 'latest_events_table';
860		$table->cellpadding = 0;
861		$table->cellspacing = 0;
862		$table->width = $width;
863		$table->class = "databox data";
864		if (!$tactical_view)
865			$table->title = __('Latest events');
866		$table->titleclass = 'tabletitle';
867		$table->titlestyle = 'text-transform:uppercase;';
868		$table->headclass = array ();
869		$table->head = array ();
870		$table->rowclass = array ();
871		$table->cellclass = array ();
872		$table->data = array ();
873		$table->align = array ();
874		$table->style[0] = $table->style[1] = $table->style[2] = 'width:25px;';
875		if ($agent_id == 0) {
876			$table->style[3] = 'word-break: break-all;';
877		}
878		$table->style[4] = 'width:120px; word-break: break-all;';
879
880		$table->head[0] = "<span title='" . __('Validated') . "'>" . __('V.') . "</span>";
881		$table->align[0] = 'center';
882
883		$table->head[1] = "<span title='" . __('Severity') . "'>" . __('S.') . "</span>";
884		$table->align[1] = 'center';
885
886		$table->head[2] = __('Type');
887		$table->headclass[2] = "datos3 f9";
888		$table->align[2] = "center";
889
890		$table->head[3] = __('Event name');
891
892		if ($agent_id == 0) {
893			$table->head[4] = __('Agent name');
894			$table->size[4] = "15%";
895		}
896
897		$table->head[5] = __('Timestamp');
898		$table->headclass[5] = "datos3 f9";
899		$table->align[5] = "left";
900		$table->size[5] = "15%";
901
902		foreach ($result as $event) {
903			if (! check_acl ($config["id_user"], $event["id_grupo"], "ER")) {
904				continue;
905			}
906
907			$data = array ();
908
909			// Colored box
910			switch($event["estado"]) {
911				case 0:
912					$img = "images/star.png";
913					$title = __('New event');
914					break;
915				case 1:
916					$img = "images/tick.png";
917					$title = __('Event validated');
918					break;
919				case 2:
920					$img = "images/hourglass.png";
921					$title = __('Event in process');
922					break;
923			}
924
925			$data[0] = html_print_image ($img, true,
926				array ("class" => "image_status",
927					"title" => $title));
928
929			switch ($event["criticity"]) {
930				default:
931				case EVENT_CRIT_MAINTENANCE:
932					$img = "images/status_sets/default/severity_maintenance.png";
933					break;
934				case EVENT_CRIT_INFORMATIONAL:
935					$img = "images/status_sets/default/severity_informational.png";
936					break;
937				case EVENT_CRIT_NORMAL:
938					$img = "images/status_sets/default/severity_normal.png";
939					break;
940				case EVENT_CRIT_WARNING:
941					$img = "images/status_sets/default/severity_warning.png";
942					break;
943				case EVENT_CRIT_CRITICAL:
944					$img = "images/status_sets/default/severity_critical.png";
945					break;
946			}
947
948			$data[1] = html_print_image ($img, true,
949				array ("class" => "image_status",
950					"width" => 12,
951					"height" => 12,
952					"title" => get_priority_name ($event["criticity"])));
953
954			/* Event type */
955			$data[2] = events_print_type_img ($event["event_type"], true);
956
957			/* Event text */
958			$data[3] = ui_print_string_substr (io_safe_output($event["evento"]), 75, true, '7.5');
959
960			if($agent_id == 0) {
961				if ($event["id_agente"] > 0) {
962					// Agent name
963					// Get class name, for the link color...
964					$myclass =  get_priority_class ($event["criticity"]);
965
966					$data[4] = "<a class='$myclass' href='index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente=".$event["id_agente"]."'>".
967								agents_get_name ($event["id_agente"]). "</A>";
968
969				// ui_print_agent_name ($event["id_agente"], true, 25, '', true);
970				// for System or SNMP generated alerts
971				}
972				elseif ($event["event_type"] == "system") {
973					$data[4] = __('System');
974				}
975				else {
976					$data[4] = __('Alert')."SNMP";
977				}
978			}
979
980			// Timestamp
981			$data[5] = ui_print_timestamp ($event["timestamp"], true, array('style' => 'font-size: 7.5pt; letter-spacing: 0.3pt;'));
982
983			$class = get_priority_class ($event["criticity"]);
984			$cell_classes[3] = $cell_classes[4] = $cell_classes[5] = $class;
985			array_push ($table->cellclass, $cell_classes);
986			//array_push ($table->rowclass, get_priority_class ($event["criticity"]));
987			array_push ($table->data, $data);
988		}
989
990		$events_table = html_print_table ($table, true);
991		$out = '<table width="100%"><tr><td style="width: 90%; vertical-align: top; padding-top: 0px;">';
992		$out .= $events_table;
993
994		if (!$tactical_view) {
995			if ($agent_id != 0) {
996				$out .= '</td><td style="width: 200px; vertical-align: top;">';
997				$out .= '<table cellpadding=0 cellspacing=0 class="databox"><tr><td>';
998				$out .= '<fieldset class="databox tactical_set">
999						<legend>' .
1000							__('Events -by module-') .
1001						'</legend>' .
1002						graph_event_module (180, 100, $event['id_agente']) . '</fieldset>';
1003				$out .= '</td></tr></table>';
1004			}
1005			else {
1006				$out .= '</td><td style="width: 200px; vertical-align: top;">';
1007				$out .= '<table cellpadding=0 cellspacing=0 class="databox"><tr><td>';
1008				$out .= '<fieldset class="databox tactical_set">
1009						<legend>' .
1010							__('Event graph') .
1011						'</legend>' .
1012						grafico_eventos_total("", 180, 60) . '</fieldset>';
1013				$out .= '<fieldset class="databox tactical_set">
1014						<legend>' .
1015							__('Event graph by agent') .
1016						'</legend>' .
1017						grafico_eventos_grupo(180, 60) . '</fieldset>';
1018				$out .= '</td></tr></table>';
1019			}
1020		}
1021		$out .= '</td></tr></table>';
1022
1023		unset ($table);
1024
1025		if ($return) {
1026			return $out;
1027		}
1028		else {
1029			echo $out;
1030		}
1031	}
1032}
1033
1034
1035/**
1036 * Prints the event type image
1037 *
1038 * @param string $type Event type from SQL
1039 * @param bool $return Whether to return or print
1040 * @param bool $only_url Flag to return only url of image, by default false.
1041 *
1042 * @return string HTML with img
1043 */
1044function events_print_type_img ($type, $return = false, $only_url = false) {
1045	global $config;
1046
1047	$output = '';
1048
1049	$urlImage = ui_get_full_url(false);
1050
1051	switch ($type) {
1052		case "alert_recovered":
1053			$icon = "bell.png";
1054			break;
1055		case "alert_manual_validation":
1056			$icon = "ok.png";
1057			break;
1058		case "going_down_critical":
1059		case "going_up_critical": //This is to be backwards compatible
1060			$icon = "module_critical.png";
1061			break;
1062		case "going_up_normal":
1063		case "going_down_normal": //This is to be backwards compatible
1064			$icon = "module_ok.png";
1065			break;
1066		case "going_up_warning":
1067		case "going_down_warning":
1068			$icon = "module_warning.png";
1069			break;
1070		case "going_unknown":
1071			$icon = "module_unknown.png";
1072			break;
1073		case "alert_fired":
1074			$icon = "bell_error.png";
1075			break;
1076		case "system":
1077			$icon = "cog.png";
1078			break;
1079		case "recon_host_detected":
1080			$icon = "recon.png";
1081			break;
1082		case "new_agent":
1083			$icon = "agent.png";
1084			break;
1085		case "configuration_change":
1086			$icon = "config.png";
1087			break;
1088		case "unknown":
1089		default:
1090			$icon = "lightning_go.png";
1091			break;
1092	}
1093
1094	if ($only_url) {
1095		$output = $urlImage . "/" . "images/" . $icon;
1096	}
1097	else {
1098		$output .= html_print_image ("images/" . $icon, true,
1099			array ("title" => events_print_type_description($type, true)));
1100	}
1101
1102	if ($return)
1103		return $output;
1104	echo $output;
1105}
1106
1107/**
1108 * Prints the event type description
1109 *
1110 * @param string $type Event type from SQL
1111 * @param bool $return Whether to return or print
1112 *
1113 * @return string HTML with img
1114 */
1115function events_print_type_description ($type, $return = false) {
1116	$output = '';
1117
1118	switch ($type) {
1119		case "going_unknown":
1120			$output .= __('Going to unknown');
1121			break;
1122		case "alert_recovered":
1123			$output .= __('Alert recovered');
1124			break;
1125		case "alert_manual_validation":
1126			$output .= __('Alert manually validated');
1127			break;
1128		case "going_up_warning":
1129			$output .= __('Going from critical to warning');
1130			break;
1131		case "going_down_critical":
1132		case "going_up_critical": //This is to be backwards compatible
1133			$output .= __('Going down to critical state');
1134			break;
1135		case "going_up_normal":
1136		case "going_down_normal": //This is to be backwards compatible
1137			$output .= __('Going up to normal state');
1138			break;
1139		case "going_down_warning":
1140			$output .= __('Going down from normal to warning');
1141			break;
1142		case "alert_fired":
1143			$output .= __('Alert fired');
1144			break;
1145		case "system";
1146			$output .= __('SYSTEM');
1147			break;
1148		case "recon_host_detected";
1149			$output .= __('Recon server detected a new host');
1150			break;
1151		case "new_agent";
1152			$output .= __('New agent created');
1153			break;
1154		case "configuration_change";
1155			$output .= __('Configuration change');
1156			break;
1157		case "alert_ceased";
1158			$output .= __('Alert ceased');
1159			break;
1160		case "error";
1161			$output .= __('Error');
1162			break;
1163		case "unknown":
1164		default:
1165			$output .= __('Unknown type:').': '.$type;
1166			break;
1167	}
1168
1169	if ($return)
1170		return $output;
1171	echo $output;
1172}
1173
1174/**
1175 * Get all the events happened in a group during a period of time.
1176 *
1177 * The returned events will be in the time interval ($date - $period, $date]
1178 *
1179 * @param mixed $id_group Group id to get events for.
1180 * @param int $period Period of time in seconds to get events.
1181 * @param int $date Beginning date to get events.
1182 *
1183 * @return array An array with all the events happened.
1184 */
1185function events_get_group_events ($id_group, $period, $date,
1186	$filter_event_validated = false, $filter_event_critical = false,
1187	$filter_event_warning = false, $filter_event_no_validated = false,
1188	$filter_event_search = false, $meta = false) {
1189
1190	global $config;
1191
1192	$id_group = groups_safe_acl ($config["id_user"], $id_group, "ER");
1193
1194	if (empty ($id_group)) {
1195		//An empty array means the user doesn't have access
1196		return false;
1197	}
1198
1199	$datelimit = $date - $period;
1200
1201	$sql_where = ' AND 1 = 1 ';
1202	$criticities = array();
1203	if ($filter_event_critical) {
1204		$criticities[] = 4;
1205	}
1206	if ($filter_event_warning) {
1207		$criticities[] = 3;
1208	}
1209	if (!empty($criticities)) {
1210		$sql_where .= ' AND criticity IN (' . implode(', ', $criticities) . ')';
1211	}
1212	if ($filter_event_validated) {
1213		$sql_where .= ' AND estado = 1 ';
1214	}
1215	if ($filter_event_no_validated) {
1216		$sql_where .= ' AND estado = 0 ';
1217	}
1218
1219	if (!empty($filter_event_search)) {
1220		$sql_where .= ' AND (evento LIKE "%'. io_safe_input($filter_event_search) . '%"'.
1221			' OR id_evento LIKE "%' . io_safe_input($filter_event_search) . '%")';
1222	}
1223
1224	$sql_where .= sprintf('
1225		AND id_grupo IN (%s)
1226		AND utimestamp > %d
1227		AND utimestamp <= %d ',
1228		implode (",", $id_group), $datelimit, $date);
1229
1230	return events_get_events_grouped($sql_where, 0, 1000, $meta);
1231}
1232
1233/**
1234 * Get all the events happened in a group during a period of time.
1235 *
1236 * The returned events will be in the time interval ($date - $period, $date]
1237 *
1238 * @param mixed $id_group Group id to get events for.
1239 * @param int $period Period of time in seconds to get events.
1240 * @param int $date Beginning date to get events.
1241 *
1242 * @return array An array with all the events happened.
1243 */
1244function events_get_group_events_steps ($begin, &$result, $id_group, $period, $date,
1245	$filter_event_validated = false, $filter_event_critical = false,
1246	$filter_event_warning = false, $filter_event_no_validated = false) {
1247
1248	global $config;
1249
1250	$id_group = groups_safe_acl ($config["id_user"], $id_group, "ER");
1251
1252	if (empty ($id_group)) {
1253		//An empty array means the user doesn't have access
1254		return false;
1255	}
1256
1257	$datelimit = $date - $period;
1258
1259	$sql_where = ' AND 1 = 1 ';
1260	$criticities = array();
1261	if ($filter_event_critical) {
1262		$criticities[] = 4;
1263	}
1264	if ($filter_event_warning) {
1265		$criticities[] = 3;
1266	}
1267	if (!empty($criticities)) {
1268		$sql_where .= ' AND criticity IN (' . implode(', ', $criticities) . ')';
1269	}
1270	if ($filter_event_validated) {
1271		$sql_where .= ' AND estado = 1 ';
1272	}
1273	if ($filter_event_no_validated) {
1274		$sql_where .= ' AND estado = 0 ';
1275	}
1276
1277
1278	$sql = sprintf ('SELECT *,
1279			(SELECT t2.nombre
1280				FROM tagente t2
1281				WHERE t2.id_agente = t3.id_agente) AS agent_name,
1282			(SELECT t2.fullname
1283				FROM tusuario t2
1284				WHERE t2.id_user = t3.id_usuario) AS user_name
1285		FROM tevento t3
1286		WHERE utimestamp > %d AND utimestamp <= %d
1287			AND id_grupo IN (%s) ' . $sql_where . '
1288		ORDER BY utimestamp ASC',
1289		$datelimit, $date, implode (",", $id_group));
1290
1291	return db_get_all_row_by_steps_sql($begin, $result, $sql);
1292}
1293
1294/**
1295 * Get all the events happened in an Agent during a period of time.
1296 *
1297 * The returned events will be in the time interval ($date - $period, $date]
1298 *
1299 * @param int $id_agent Agent id to get events.
1300 * @param int $period Period of time in seconds to get events.
1301 * @param int $date Beginning date to get events.
1302 *
1303 * @return array An array with all the events happened.
1304 */
1305function events_get_agent ($id_agent, $period, $date = 0,
1306	$filter_event_validated = false, $filter_event_critical = false,
1307	$filter_event_warning = false, $filter_event_no_validated = false) {
1308
1309	if (!is_numeric ($date)) {
1310		$date = strtotime ($date);
1311	}
1312	if (empty ($date)) {
1313		$date = get_system_time ();
1314	}
1315
1316	$datelimit = $date - $period;
1317
1318	$sql_where = '';
1319
1320	$criticities = array();
1321	if ($filter_event_critical) {
1322		$criticities[] = 4;
1323	}
1324	if ($filter_event_warning) {
1325		$criticities[] = 3;
1326	}
1327	if (!empty($criticities)) {
1328		$sql_where .= ' AND criticity IN (' . implode(', ', $criticities) . ')';
1329	}
1330
1331	if ( $filter_event_validated && $filter_event_no_validated ) {
1332		$sql_where .= " AND (estado = 1 OR estado = 0)";
1333	}
1334	else {
1335		if ($filter_event_validated) {
1336			$sql_where .= ' AND estado = 1 ';
1337		} else {
1338			if ($filter_event_no_validated) {
1339				$sql_where .= ' AND estado = 0 ';
1340			}
1341		}
1342	}
1343
1344	$sql_where .= sprintf(' AND id_agente = %d AND utimestamp > %d
1345			AND utimestamp <= %d ', $id_agent, $datelimit, $date);
1346
1347	return events_get_events_grouped($sql_where, 0, 1000, is_metaconsole());
1348}
1349
1350/**
1351 * Get all the events happened in an Agent during a period of time.
1352 *
1353 * The returned events will be in the time interval ($date - $period, $date]
1354 *
1355 * @param int $id_agent_module Module id to get events.
1356 * @param int $period Period of time in seconds to get events.
1357 * @param int $date Beginning date to get events.
1358 *
1359 * @return array An array with all the events happened.
1360 */
1361function events_get_module ($id_agent_module, $period, $date = 0) {
1362	if (!is_numeric ($date)) {
1363		$date = strtotime ($date);
1364	}
1365	if (empty ($date)) {
1366		$date = get_system_time ();
1367	}
1368
1369	$datelimit = $date - $period;
1370
1371	$sql_where = sprintf(' AND id_agentmodule = %d AND utimestamp > %d
1372			AND utimestamp <= %d ', $id_agent_module, $datelimit, $date);
1373
1374	return events_get_events_grouped($sql_where, 0, 1000);
1375
1376	$sql = sprintf ('SELECT evento, event_type, criticity, count(*) as count_rep, max(timestamp) AS time2
1377		FROM tevento
1378		WHERE id_agentmodule = %d AND utimestamp > %d AND utimestamp <= %d
1379		GROUP BY id_agentmodule, evento ORDER BY time2 DESC', $id_agent_module, $datelimit, $date);
1380
1381	return db_get_all_rows_sql ($sql);
1382}
1383
1384/**
1385 * Decode a numeric type into type description.
1386 *
1387 * @param int $type_id Numeric type.
1388 *
1389 * @return string Type description.
1390 */
1391function events_get_event_types ($type_id) {
1392
1393	$diferent_types = get_event_types ();
1394
1395	$type_desc = '';
1396	switch ($type_id) {
1397		case 'unknown':
1398			$type_desc = __('Unknown');
1399			break;
1400		case 'critical':
1401			$type_desc = __('Monitor Critical');
1402			break;
1403		case 'warning':
1404			$type_desc = __('Monitor Warning');
1405			break;
1406		case 'normal':
1407			$type_desc = __('Monitor Normal');
1408			break;
1409		case 'alert_fired':
1410			$type_desc = __('Alert fired');
1411			break;
1412		case 'alert_recovered':
1413			$type_desc = __('Alert recovered');
1414			break;
1415		case 'alert_ceased':
1416			$type_desc = __('Alert ceased');
1417			break;
1418		case 'alert_manual_validation':
1419			$type_desc = __('Alert manual validation');
1420			break;
1421		case 'recon_host_detected':
1422			$type_desc = __('Recon host detected');
1423			break;
1424		case 'system':
1425			$type_desc = __('System');
1426			break;
1427		case 'error':
1428			$type_desc = __('Error');
1429			break;
1430		case 'configuration_change':
1431			$type_desc = __('Configuration change');
1432			break;
1433		case 'not_normal':
1434			$type_desc = __('Not normal');
1435			break;
1436		default:
1437			if (isset($config['text_char_long'])) {
1438				foreach ($diferent_types as $key => $type) {
1439					if ($key == $type_id) {
1440						$type_desc = ui_print_truncate_text($type, $config['text_char_long'], false, true, false);
1441					}
1442				}
1443			}
1444			break;
1445	}
1446
1447	return $type_desc;
1448}
1449
1450
1451/**
1452 * Decode a numeric severity into severity description.
1453 *
1454 * @param int $severity_id Numeric severity.
1455 *
1456 * @return string Severity description.
1457 */
1458function events_get_severity_types ($severity_id) {
1459
1460	$diferent_types = get_priorities ();
1461
1462	$severity_desc = '';
1463	switch ($severity_id) {
1464		case EVENT_CRIT_MAINTENANCE:
1465			$severity_desc = __('Maintenance');
1466			break;
1467		case EVENT_CRIT_INFORMATIONAL:
1468			$severity_desc = __('Informational');
1469			break;
1470		case EVENT_CRIT_NORMAL:
1471			$severity_desc = __('Normal');
1472			break;
1473		case EVENT_CRIT_WARNING:
1474			$severity_desc = __('Warning');
1475			break;
1476		case EVENT_CRIT_CRITICAL:
1477			$severity_desc = __('Critical');
1478			break;
1479		default:
1480			if (isset($config['text_char_long'])) {
1481				foreach ($diferent_types as $key => $type) {
1482					if ($key == $severity_id) {
1483						$severity_desc = ui_print_truncate_text($type,
1484							$config['text_char_long'], false, true, false);
1485					}
1486				}
1487			}
1488			break;
1489	}
1490
1491	return $severity_desc;
1492}
1493
1494/**
1495 * Return all descriptions of event status.
1496 *
1497 * @return array Status description array.
1498 */
1499function events_get_all_status () {
1500	$fields = array ();
1501	$fields[-1] = __('All event');
1502	$fields[0] = __('Only new');
1503	$fields[1] = __('Only validated');
1504	$fields[2] = __('Only in process');
1505	$fields[3] = __('Only not validated');
1506
1507	return $fields;
1508}
1509
1510/**
1511 * Decode a numeric status into status description.
1512 *
1513 * @param int $status_id Numeric status.
1514 *
1515 * @return string Status description.
1516 */
1517function events_get_status ($status_id) {
1518	switch ($status_id) {
1519		case -1:
1520			$status_desc = __('All event');
1521			break;
1522		case 0:
1523			$status_desc = __('Only new');
1524			break;
1525		case 1:
1526			$status_desc = __('Only validated');
1527			break;
1528		case 2:
1529			$status_desc = __('Only in process');
1530			break;
1531		case 3:
1532			$status_desc = __('Only not validated');
1533			break;
1534	}
1535
1536	return $status_desc;
1537}
1538
1539/**
1540 * Checks if a user has permissions to see an event filter.
1541 *
1542 * @param int $id_filter Id of the event filter.
1543 *
1544 * @return bool True if the user has permissions or false otherwise.
1545 */
1546function events_check_event_filter_group ($id_filter) {
1547	global $config;
1548
1549	$id_group = db_get_value('id_group_filter', 'tevent_filter', 'id_filter', $id_filter);
1550	$own_info = get_user_info ($config['id_user']);
1551	// Get group list that user has access
1552	$groups_user = users_get_groups ($config['id_user'], "EW", $own_info['is_admin'], true);
1553
1554	// Permissions in any group allow to edit "All group" filters
1555	if($id_group == 0 && !empty($groups_user)) {
1556		return true;
1557	}
1558
1559	$groups_id = array();
1560	$has_permission = false;
1561
1562	foreach ($groups_user as $key => $groups) {
1563		if ($groups['id_grupo'] == $id_group)
1564			return true;
1565	}
1566
1567	return false;
1568}
1569
1570/**
1571 * Return an array with all the possible macros in event responses
1572 *
1573 * @return array
1574 */
1575function events_get_macros() {
1576	return array('_agent_address_' => __('Agent address'),
1577		'_agent_id_' => __('Agent id'),
1578		'_event_id_' => __('Event id'),
1579		'_module_address_' => __('Module Agent address'),);
1580}
1581
1582/**
1583 *  Get a event filter.
1584 *
1585 * @param int Filter id to be fetched.
1586 * @param array Extra filter.
1587 * @param array Fields to be fetched.
1588 *
1589 * @return array A event filter matching id and filter or false.
1590 */
1591function events_get_event_filter ($id_filter, $filter = false, $fields = false) {
1592
1593	if (empty($id_filter)) {
1594		return false;
1595	}
1596
1597	if (! is_array ($filter)) {
1598		$filter = array ();
1599		$filter['id_filter'] = (int) $id_filter;
1600	}
1601
1602	return db_get_row_filter ('tevent_filter', $filter, $fields);
1603}
1604
1605/**
1606 *  Get a event filters in select format.
1607 *
1608 * @param boolean If event filters are used for manage/view operations (non admin users can see group ALL for manage) # Fix
1609 * @return array A event filter matching id and filter or false.
1610 */
1611function events_get_event_filter_select($manage = true) {
1612	global $config;
1613
1614	$strict_acl = db_get_value('strict_acl', 'tusuario', 'id_user', $config['id_user']);
1615
1616	if ($strict_acl) {
1617		$user_groups = users_get_strict_mode_groups($config['id_user'],
1618			users_can_manage_group_all());
1619	}
1620	else {
1621		$user_groups = users_get_groups ($config['id_user'], "EW",
1622			users_can_manage_group_all(), true);
1623	}
1624
1625	if(empty($user_groups)) {
1626		return array();
1627	}
1628	$sql = "
1629		SELECT id_filter, id_name
1630		FROM tevent_filter
1631		WHERE id_group_filter IN (" . implode(',', array_keys ($user_groups)) . ")";
1632
1633	$event_filters = db_get_all_rows_sql($sql);
1634
1635	if ($event_filters === false) {
1636		return array();
1637	}
1638	else {
1639		$result = array();
1640		foreach ($event_filters as $event_filter) {
1641			$result[$event_filter['id_filter']] = $event_filter['id_name'];
1642		}
1643	}
1644
1645	return $result;
1646}
1647
1648
1649// Events pages functions to load modal window with advanced view of an event.
1650// Called from include/ajax/events.php
1651
1652function events_page_responses ($event, $childrens_ids = array()) {
1653	global $config;
1654	/////////
1655	// Responses
1656	/////////
1657
1658	$table_responses->cellspacing = 2;
1659	$table_responses->cellpadding = 2;
1660	$table_responses->id = 'responses_table';
1661	$table_responses->width = '100%';
1662	$table_responses->data = array ();
1663	$table_responses->head = array ();
1664	$table_responses->style[0] = 'width:35%; font-weight: bold; text-align: left; height: 23px;';
1665	$table_responses->style[1] = 'text-align: left; height: 23px; text-align: right;';
1666	$table_responses->class = "alternate rounded_cells";
1667
1668	if (tags_checks_event_acl ($config["id_user"], $event["id_grupo"], "EM", $event['clean_tags'], $childrens_ids)) {
1669		// Owner
1670		$data = array();
1671		$data[0] = __('Change owner');
1672		// Owner change can be done to users that belong to the event group with ER permission
1673		$profiles_view_events = db_get_all_rows_filter('tperfil', array('event_view' => '1'), 'id_perfil');
1674		foreach($profiles_view_events as $k => $v) {
1675			$profiles_view_events[$k] = reset($v);
1676		}
1677		// Juanma (05/05/2014) Fix : Propagate ACL hell!
1678		$_user_groups = array_keys(users_get_groups($config['id_user'], 'ER', users_can_manage_group_all()));
1679		$strict_user = db_get_value('strict_acl', 'tusuario', 'id_user', $config['id_user']);
1680		if ($strict_user) {
1681			$user_name = db_get_value('fullname', 'tusuario', 'id_user', $config['id_user']);
1682
1683			$users = array();
1684			$users[0]['id_user'] = $config['id_user'];
1685			$users[0]['fullname'] = $user_name;
1686		} else {
1687			$users = groups_get_users($_user_groups, array('id_perfil' => $profiles_view_events), true, true);
1688		}
1689
1690		foreach($users as $u) {
1691			$owners[$u['id_user']] = $u['fullname'];
1692		}
1693
1694		if($event['owner_user'] == '') {
1695			$owner_name = __('None');
1696		}
1697		else {
1698			$owner_name = db_get_value('fullname', 'tusuario', 'id_user', $event['owner_user']);
1699			$owners[$event['owner_user']] = $owner_name;
1700		}
1701
1702		$data[1] = html_print_select($owners, 'id_owner', $event['owner_user'], '', __('None'), -1, true);
1703		$data[1] .= html_print_button(__('Update'),'owner_button',false,'event_change_owner();','class="sub next"',true);
1704
1705		$table_responses->data[] = $data;
1706	}
1707
1708	// Status
1709	$data = array();
1710	$data[0] = __('Change status');
1711
1712	$status_blocked = false;
1713
1714	if (tags_checks_event_acl ($config["id_user"], $event["id_grupo"], "EM", $event['clean_tags'], $childrens_ids)) {
1715		// If the user has manager acls, the status can be changed to all possibilities always
1716		$status = array(0 => __('New'), 2 => __('In process'), 1 => __('Validated'));
1717	}
1718	else {
1719		switch($event['estado']) {
1720			case 0:
1721				// If the user hasnt manager acls and the event is new. The status can be changed
1722				$status = array(2 => __('In process'), 1 => __('Validated'));
1723				break;
1724			case 1:
1725				// If the user hasnt manager acls and the event is validated. The status cannot be changed
1726				$status = array(1 => __('Validated'));
1727				$status_blocked = true;
1728				break;
1729			case 2:
1730				// If the user hasnt manager acls and the event is in process. The status only can be changed to validated
1731				$status = array(1 => __('Validated'));
1732				break;
1733		}
1734
1735	}
1736
1737	// The change status option will be enabled only when is possible change the status
1738	$data[1] = html_print_select($status, 'estado', $event['estado'], '', '', 0, true, false, false, '', $status_blocked);
1739
1740	if(!$status_blocked) {
1741		$data[1] .= html_print_button(__('Update'),'status_button',false,'event_change_status(\''.$event['similar_ids'] .'\');','class="sub next"',true);
1742	}
1743
1744	$table_responses->data[] = $data;
1745
1746	// Comments
1747	$data = array();
1748	$data[0] = __('Comment');
1749	$data[1] = html_print_button(__('Add comment'),'comment_button',false,'$(\'#link_comments\').trigger(\'click\');','class="sub next"',true);
1750
1751	$table_responses->data[] = $data;
1752
1753	if (tags_checks_event_acl($config["id_user"], $event["id_grupo"], "EM", $event['clean_tags'], $childrens_ids)) {
1754		// Delete
1755		$data = array();
1756		$data[0] = __('Delete event');
1757		$data[1] = '<form method="post">';
1758		$data[1] .= html_print_button(__('Delete event'),'delete_button',false,'if(!confirm(\''.__('Are you sure?').'\')) { return false; } this.form.submit();','class="sub cancel"',true);
1759		$data[1] .= html_print_input_hidden('delete', 1, true);
1760		$data[1] .= html_print_input_hidden('validate_ids', $event['id_evento'], true);
1761		$data[1] .= '</form>';
1762
1763		$table_responses->data[] = $data;
1764	}
1765
1766	// Custom responses
1767	$data = array();
1768	$data[0] = __('Custom responses');
1769
1770	$id_groups = array_keys(users_get_groups(false, "EW"));
1771	$event_responses = db_get_all_rows_filter('tevent_response',
1772		array('id_group' => $id_groups));
1773
1774	if (empty($event_responses)) {
1775		$data[1] = '<i>'.__('N/A').'</i>';
1776	}
1777	else {
1778		$responses = array();
1779		foreach ($event_responses as $v) {
1780			$responses[$v['id']] = $v['name'];
1781		}
1782		$data[1] = html_print_select(
1783			$responses,
1784			'select_custom_response','','','','',true, false, false);
1785
1786		if (isset($event['server_id'])) {
1787			$server_id = $event['server_id'];
1788		}
1789		else {
1790			$server_id = 0;
1791		}
1792
1793		$data[1] .= html_print_button(__('Execute'),'custom_response_button',false,'execute_response('.$event['id_evento'].','.$server_id.')',"class='sub next'",true);
1794	}
1795
1796	$table_responses->data[] = $data;
1797
1798
1799	$responses_js = "<script>
1800			$('#select_custom_response').change(function() {
1801				var id_response = $('#select_custom_response').val();
1802				var params = get_response_params(id_response);
1803				var description = get_response_description(id_response);
1804				$('.params_rows').remove();
1805
1806				$('#responses_table')
1807					.append('<tr class=\"params_rows\"><td style=\"text-align:left; font-weight: bolder;\">".__('Description')."</td><td style=\"text-align:left;\">'+description+'</td></tr>');
1808
1809				if (params.length == 1 && params[0] == '') {
1810					return;
1811				}
1812
1813				$('#responses_table')
1814					.append('<tr class=\"params_rows\"><td style=\"text-align:left; padding-left:20px;\" colspan=\"2\">".__('Parameters')."</td></tr>');
1815
1816				for (i = 0; i < params.length; i++) {
1817					add_row_param('responses_table',params[i]);
1818				}
1819			});
1820			$('#select_custom_response').trigger('change');
1821			</script>";
1822
1823	$responses = '<div id="extended_event_responses_page" class="extended_event_pages">' .
1824		html_print_table($table_responses, true) .
1825		$responses_js .
1826		'</div>';
1827
1828	return $responses;
1829}
1830
1831// Replace macros in the target of a response and return it
1832// If server_id > 0, is a metaconsole query
1833function events_get_response_target($event_id, $response_id, $server_id, $history = false) {
1834	global $config;
1835
1836	$event_response = db_get_row('tevent_response','id',$response_id);
1837
1838	if ($server_id > 0) {
1839		$meta = true;
1840	}
1841	else {
1842		$meta = false;
1843	}
1844
1845	$event_table = events_get_events_table($meta, $history);
1846
1847	$event = db_get_row($event_table,'id_evento', $event_id);
1848
1849	$macros = array_keys(events_get_macros());
1850
1851	$target = io_safe_output($event_response['target']);
1852
1853	foreach($macros as $macro) {
1854		$subst = '';
1855		switch($macro) {
1856			case '_agent_address_':
1857				if ($meta) {
1858					$server = metaconsole_get_connection_by_id ($server_id);
1859					metaconsole_connect($server);
1860				}
1861
1862				$subst = agents_get_address($event['id_agente']);
1863
1864				if($meta) {
1865					metaconsole_restore_db_force();
1866				}
1867				break;
1868			case '_agent_id_':
1869				$subst = $event['id_agente'];
1870				break;
1871			case '_event_id_':
1872				$subst = $event['id_evento'];
1873				break;
1874			case '_module_address_':
1875				if($meta) {
1876					$server = metaconsole_get_connection_by_id ($server_id);
1877					metaconsole_connect($server);
1878				}
1879
1880				$module = db_get_row("tagente_modulo",'id_agente_modulo', $event['id_agentmodule']);
1881				if ($module['ip_target'] != false)
1882					$subst = $module['ip_target'];
1883
1884				if($meta) {
1885					metaconsole_restore_db_force();
1886				}
1887				break;
1888		}
1889
1890		$target = str_replace($macro,$subst,$target);
1891	}
1892
1893	return $target;
1894}
1895
1896function events_page_custom_fields ($event) {
1897	global $config;
1898
1899	////////////////////////////////////////////////////////////////////
1900	// Custom fields
1901	////////////////////////////////////////////////////////////////////
1902
1903	$table->cellspacing = 2;
1904	$table->cellpadding = 2;
1905	$table->width = '100%';
1906	$table->data = array ();
1907	$table->head = array ();
1908	$table->style[0] = 'width:35%; font-weight: bold; text-align: left; height: 23px;';
1909	$table->style[1] = 'text-align: left; height: 23px;';
1910	$table->class = "alternate rounded_cells";
1911
1912	$all_customs_fields = (bool)check_acl($config["id_user"],
1913	$event["id_grupo"], "AW");
1914
1915	if ($all_customs_fields) {
1916		$fields = db_get_all_rows_filter('tagent_custom_fields');
1917	}
1918	else {
1919		$fields = db_get_all_rows_filter('tagent_custom_fields',
1920			array('display_on_front' => 1));
1921	}
1922
1923	if ($event['id_agente'] == 0) {
1924		$fields_data = array();
1925	}
1926	else {
1927		$fields_data = db_get_all_rows_filter('tagent_custom_data', array('id_agent' => $event['id_agente']));
1928		if(is_array($fields_data)) {
1929			$fields_data_aux = array();
1930			foreach($fields_data as $fd) {
1931				$fields_data_aux[$fd['id_field']] = $fd['description'];
1932			}
1933			$fields_data = $fields_data_aux;
1934		}
1935	}
1936
1937	foreach ($fields as $field) {
1938		// Owner
1939		$data = array();
1940		$data[0] = $field['name'];
1941
1942		$data[1] = empty($fields_data[$field['id_field']]) ? '<i>'.__('N/A').'</i>' : $fields_data[$field['id_field']];
1943
1944		$field['id_field'];
1945
1946		$table->data[] = $data;
1947	}
1948
1949	$custom_fields = '<div id="extended_event_custom_fields_page" class="extended_event_pages">'.html_print_table($table, true).'</div>';
1950
1951	return $custom_fields;
1952}
1953
1954function events_page_details ($event, $server = "") {
1955	global $img_sev;
1956	global $config;
1957
1958	// If server is provided, get the hash parameters
1959	if (!empty($server) && defined("METACONSOLE")) {
1960		$hashdata = metaconsole_get_server_hashdata($server);
1961		$hashstring = "&amp;" .
1962			"loginhash=auto&" .
1963			"loginhash_data=" . $hashdata . "&" .
1964			"loginhash_user=" . str_rot13($config["id_user"]);
1965		$serverstring = $server['server_url'] . "/";
1966
1967		if (metaconsole_connect($server) !== NOERR) {
1968			return ui_print_error_message(__('There was an error connecting to the node'), '', true);
1969		}
1970	}
1971	else {
1972		$hashstring = "";
1973		$serverstring = "";
1974	}
1975
1976	////////////////////////////////////////////////////////////////////
1977	// Details
1978	////////////////////////////////////////////////////////////////////
1979
1980	$table_details->width = '100%';
1981	$table_details->data = array ();
1982	$table_details->head = array ();
1983	$table_details->cellspacing = 2;
1984	$table_details->cellpadding = 2;
1985	$table_details->style[0] = 'width:35%; font-weight: bold; text-align: left; height: 23px;';
1986	$table_details->style[1] = 'text-align: left; height: 23px;';
1987	$table_details->class = "alternate rounded_cells";
1988
1989	switch ($event['event_type']) {
1990		case 'going_unknown':
1991		case 'going_up_warning':
1992		case 'going_down_warning':
1993		case 'going_up_critical':
1994		case 'going_down_critical':
1995
1996			break;
1997	}
1998
1999	if ($event["id_agente"] != 0) {
2000		$agent = db_get_row('tagente','id_agente',$event["id_agente"]);
2001	}
2002	else {
2003		$agent = array();
2004	}
2005
2006	$data = array();
2007	$data[0] = __('Agent details');
2008	$data[1] = empty($agent) ? '<i>' . __('N/A') . '</i>' : '';
2009	$table_details->data[] = $data;
2010
2011	if (!empty($agent)) {
2012		$data = array();
2013		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Name').'</div>';
2014		if (can_user_access_node ()) {
2015			$data[1] = ui_print_agent_name ($event["id_agente"], true, 'agent_medium', '', false, $serverstring, $hashstring, $agent['nombre']);
2016		}
2017		else {
2018			$data[1] = ui_print_truncate_text($agent['nombre'], 'agent_medium', true, true, true);
2019		}
2020		$table_details->data[] = $data;
2021
2022		$data = array();
2023		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('IP Address').'</div>';
2024		$data[1] = empty($agent['direccion']) ? '<i>'.__('N/A').'</i>' : $agent['direccion'];
2025		$table_details->data[] = $data;
2026
2027		$data = array();
2028		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('OS').'</div>';
2029		$data[1] = ui_print_os_icon ($agent["id_os"], true, true).' ('.$agent["os_version"].')';
2030		$table_details->data[] = $data;
2031
2032		$data = array();
2033		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Last contact').'</div>';
2034		$data[1] = $agent["ultimo_contacto"] == "1970-01-01 00:00:00" ? '<i>'.__('N/A').'</i>' : $agent["ultimo_contacto"];
2035		$table_details->data[] = $data;
2036
2037		$data = array();
2038		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Last remote contact').'</div>';
2039		$data[1] = $agent["ultimo_contacto_remoto"] == "1970-01-01 00:00:00" ? '<i>'.__('N/A').'</i>' : $agent["ultimo_contacto_remoto"];
2040		$table_details->data[] = $data;
2041
2042		$data = array();
2043		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Custom fields').'</div>';
2044		$data[1] = html_print_button(__('View custom fields'),'custom_button',false,'$(\'#link_custom_fields\').trigger(\'click\');','class="sub next"',true);
2045		$table_details->data[] = $data;
2046	}
2047
2048	if ($event["id_agentmodule"] != 0) {
2049		$module = db_get_row_filter('tagente_modulo',array('id_agente_modulo' => $event["id_agentmodule"], 'delete_pending' => 0));
2050	}
2051	else {
2052		$module = array();
2053	}
2054
2055	$data = array();
2056	$data[0] = __('Module details');
2057	$data[1] = empty($module) ? '<i>' . __('N/A') . '</i>' : '';
2058	$table_details->data[] = $data;
2059
2060	if (!empty($module)) {
2061		// Module name
2062		$data = array();
2063		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Name').'</div>';
2064		$data[1] = $module['nombre'];
2065		$table_details->data[] = $data;
2066
2067		// Module group
2068		$data = array();
2069		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">' .
2070			__('Module group') . '</div>';
2071		$id_module_group = $module['id_module_group'];
2072		if ($id_module_group == 0) {
2073			$data[1] = __('No assigned');
2074		}
2075		else {
2076			$module_group = db_get_value('name', 'tmodule_group', 'id_mg', $id_module_group);
2077			$data[1] = '<a href="'.$serverstring . 'index.php?sec=estado&amp;sec2=operation/agentes/status_monitor&amp;status=-1&amp;modulegroup=' . $id_module_group . $hashstring.'">';
2078			$data[1] .= $module_group;
2079			$data[1] .= '</a>';
2080		}
2081		$table_details->data[] = $data;
2082
2083		// ACL
2084		$acl_graph = false;
2085		$strict_user = (bool) db_get_value("strict_acl", "tusuario", "id_user", $config['id_user']);
2086
2087		if (!empty($agent['id_grupo'])) {
2088			if ($strict_user) {
2089				$acl_graph = tags_check_acl_by_module($module["id_agente_modulo"], $config['id_user'], 'RR') === true;
2090			}
2091			else {
2092				$acl_graph = check_acl($config['id_user'], $agent['id_grupo'], "RR");
2093			}
2094		}
2095
2096		if ($acl_graph) {
2097			$data = array();
2098			$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Graph').'</div>';
2099
2100			$module_type = -1;
2101			if (isset($module["module_type"])) {
2102				$module_type = $module["module_type"];
2103			}
2104			$graph_type = return_graphtype ($module_type);
2105			$url = ui_get_full_url("operation/agentes/stat_win.php", false, false, false);
2106			$handle = dechex(crc32($module["id_agente_modulo"].$module["nombre"]));
2107			$win_handle = "day_$handle";
2108
2109			$graph_params = array(
2110					"type" => $graph_type,
2111					"period" => SECONDS_1DAY,
2112					"id" => $module["id_agente_modulo"],
2113					"label" => rawurlencode(urlencode(base64_encode($module["nombre"]))),
2114					"refresh" => SECONDS_10MINUTES
2115				);
2116
2117			if (defined('METACONSOLE')) {
2118				$graph_params["avg_only"] = 1;
2119				// Set the server id
2120				$graph_params["server"] = $server["id"];
2121			}
2122
2123			$graph_params_str = http_build_query($graph_params);
2124
2125			$link = "winopeng('$url?$graph_params_str','$win_handle')";
2126
2127			$data[1] = '<a href="javascript:'.$link.'">';
2128			$data[1] .= html_print_image('images/chart_curve.png',true);
2129			$data[1] .= '</a>';
2130			$table_details->data[] = $data;
2131		}
2132	}
2133
2134	$data = array();
2135	$data[0] = __('Alert details');
2136	$data[1] = $event["id_alert_am"] == 0 ? '<i>' . __('N/A') . '</i>' : '';
2137	$table_details->data[] = $data;
2138
2139	if ($event["id_alert_am"] != 0) {
2140		$data = array();
2141		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Source').'</div>';
2142		$data[1] = '<a href="'.$serverstring.'index.php?sec=estado&amp;sec2=operation/agentes/ver_agente&amp;id_agente='.$event["id_agente"].'&amp;tab=alert'.$hashstring.'">';
2143		$standby = db_get_value('standby', 'talert_template_modules', 'id', $event["id_alert_am"]);
2144		if(!$standby) {
2145			$data[1] .= html_print_image ("images/bell.png", true,
2146				array ("title" => __('Go to data overview')));
2147		}
2148		else {
2149			$data[1] .= html_print_image ("images/bell_pause.png", true,
2150				array ("title" => __('Go to data overview')));
2151		}
2152
2153		$sql = 'SELECT name
2154			FROM talert_templates
2155			WHERE id IN (SELECT id_alert_template
2156					FROM talert_template_modules
2157					WHERE id = ' . $event["id_alert_am"] . ');';
2158
2159		$templateName = db_get_sql($sql);
2160
2161		$data[1] .= $templateName;
2162
2163		$data[1] .= '</a>';
2164
2165		$table_details->data[] = $data;
2166
2167		$data = array();
2168		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Priority').'</div>';
2169
2170		$priority_code = db_get_value('priority', 'talert_template_modules', 'id', $event["id_alert_am"]);
2171		$alert_priority = get_priority_name ($priority_code);
2172		$data[1] = html_print_image ($img_sev, true,
2173			array ("class" => "image_status",
2174				"width" => 12,
2175				"height" => 12,
2176				"title" => $alert_priority));
2177		$data[1] .= ' '.$alert_priority;
2178
2179		$table_details->data[] = $data;
2180	}
2181
2182	switch($event['event_type']) {
2183		case 'going_unknown':
2184			$data = array();
2185			$data[0] = __('Instructions');
2186			if ($event["unknown_instructions"] != '') {
2187				$data[1] = str_replace("\n","<br>", io_safe_output($event["unknown_instructions"]));
2188			}
2189			else {
2190				$data[1] = '<i>' . __('N/A') . '</i>';
2191			}
2192			$table_details->data[] = $data;
2193			break;
2194		case 'going_up_warning':
2195		case 'going_down_warning':
2196			$data = array();
2197			$data[0] = __('Instructions');
2198			if ($event["warning_instructions"] != '') {
2199				$data[1] = str_replace("\n","<br>", io_safe_output($event["warning_instructions"]));
2200			}
2201			else {
2202				$data[1] = '<i>' . __('N/A') . '</i>';
2203			}
2204			$table_details->data[] = $data;
2205			break;
2206		case 'going_up_critical':
2207		case 'going_down_critical':
2208			$data = array();
2209			$data[0] = __('Instructions');
2210			if ($event["critical_instructions"] != '') {
2211				$data[1] = str_replace("\n","<br>", io_safe_output($event["critical_instructions"]));
2212			}
2213			else {
2214				$data[1] = '<i>' . __('N/A') . '</i>';
2215			}
2216			$table_details->data[] = $data;
2217			break;
2218		case 'system':
2219			$data = array();
2220			if ($event["critical_instructions"] != '') {
2221				$data[0] = __('Instructions');
2222				$data[1] = str_replace("\n","<br>", io_safe_output($event["critical_instructions"]));
2223			}
2224			else {
2225				if ($event["warning_instructions"] != '') {
2226					$data[0] = __('Instructions');
2227					$data[1] = str_replace("\n","<br>", io_safe_output($event["warning_instructions"]));
2228				}
2229				else {
2230					if ($event["unknown_instructions"] != '') {
2231						$data[0] = __('Instructions');
2232						$data[1] = str_replace("\n","<br>", io_safe_output($event["unknown_instructions"]));
2233					}
2234					else {
2235						$data[0] = __('Instructions');
2236						$data[1] = '<i>' . __('N/A') . '</i>';
2237
2238					}
2239				}
2240			}
2241			$table_details->data[] = $data;
2242			break;
2243	}
2244
2245	$data = array();
2246	$data[0] = __('Extra id');
2247	if ($event["id_extra"] != '') {
2248		$data[1] = $event["id_extra"];
2249	}
2250	else {
2251		$data[1] = '<i>' . __('N/A') . '</i>';
2252	}
2253	$table_details->data[] = $data;
2254
2255	$data = array();
2256	$data[0] = __('Source');
2257	if ($event["source"] != '') {
2258		$data[1] = $event["source"];
2259	}
2260	else {
2261		$data[1] = '<i>' . __('N/A') . '</i>';
2262	}
2263	$table_details->data[] = $data;
2264
2265	$details = '<div id="extended_event_details_page" class="extended_event_pages">'.html_print_table($table_details, true).'</div>';
2266
2267	if (!empty($server) && defined("METACONSOLE"))
2268		metaconsole_restore_db();
2269
2270	return $details;
2271}
2272
2273function events_page_custom_data ($event) {
2274	global $config;
2275
2276	////////////////////////////////////////////////////////////////////
2277	// Custom data
2278	////////////////////////////////////////////////////////////////////
2279	if ($event['custom_data'] == '') {
2280		return '';
2281	}
2282
2283	$table->width = '100%';
2284	$table->data = array ();
2285	$table->head = array ();
2286	$table->style[0] = 'width:35%; font-weight: bold; text-align: left;';
2287	$table->style[1] = 'text-align: left;';
2288	$table->class = "alternate rounded_cells";
2289
2290	$json_custom_data = base64_decode ($event['custom_data']);
2291	$custom_data = json_decode ($json_custom_data);
2292	if ($custom_data === NULL) {
2293		return '<div id="extended_event_custom_data_page" class="extended_event_pages">'.__('Invalid custom data: %s', $json_custom_data).'</div>';
2294	}
2295
2296	$i = 0;
2297	foreach ($custom_data as $field => $value) {
2298		$table->data[$i][0] = io_safe_output ($field);
2299		$table->data[$i][1] = io_safe_output ($value);
2300		$i++;
2301	}
2302
2303	$custom_data = '<div id="extended_event_custom_data_page" class="extended_event_pages">'.html_print_table($table, true).'</div>';
2304
2305	return $custom_data;
2306}
2307
2308function events_page_general ($event) {
2309	global $img_sev;
2310	global $config;
2311
2312	//$group_rep = $event['similar_ids'] == -1 ? 1 : count(explode(',',$event['similar_ids']));
2313	global $group_rep;
2314
2315	////////////////////////////////////////////////////////////////////
2316	// General
2317	////////////////////////////////////////////////////////////////////
2318	$table_general->cellspacing = 2;
2319	$table_general->cellpadding = 2;
2320	$table_general->width = '100%';
2321	$table_general->data = array ();
2322	$table_general->head = array ();
2323	$table_general->style[0] = 'width:35%; font-weight: bold; text-align: left; height: 23px;';
2324	$table_general->style[1] = 'text-align: left; height: 23px;';
2325	$table_general->class = "alternate rounded_cells";
2326
2327	$data = array();
2328	$data[0] = __('Event ID');
2329	$data[1] = "#".$event["id_evento"];
2330	$table_general->data[] = $data;
2331
2332	$data = array();
2333	$data[0] = __('Event name');
2334	$data[1] = io_safe_output(io_safe_output($event["evento"]));
2335	$table_general->data[] = $data;
2336
2337	$data = array();
2338	$data[0] = __('Timestamp');
2339	if ($group_rep == 1 && $event["event_rep"] > 1) {
2340		$data[1] = __('First event').': '.date ($config["date_format"], $event['timestamp_first']).'<br>'.__('Last event').': '.date ($config["date_format"], $event['timestamp_last']);
2341	}
2342	else {
2343		$data[1] = date ($config["date_format"], strtotime($event["timestamp"]));
2344	}
2345	$table_general->data[] = $data;
2346
2347	$data = array();
2348	$data[0] = __('Owner');
2349	if (empty($event["owner_user"])) {
2350		$data[1] = '<i>'.__('N/A').'</i>';
2351	}
2352	else {
2353		$user_owner = db_get_value('fullname', 'tusuario', 'id_user', $event["owner_user"]);
2354		if(empty($user_owner)) {
2355			$user_owner = $event['owner_user'];
2356		}
2357		$data[1] = $user_owner;
2358	}
2359	$table_general->data[] = $data;
2360
2361	$data = array();
2362	$data[0] = __('Type');
2363	$data[1] = events_print_type_img ($event["event_type"], true).' '.events_print_type_description($event["event_type"], true);
2364	$table_general->data[] = $data;
2365
2366	$data = array();
2367	$data[0] = __('Repeated');
2368	if ($group_rep != 0) {
2369		if($event["event_rep"] <= 1) {
2370			$data[1] = '<i>'.__('No').'</i>';
2371		}
2372		else {
2373			$data[1] = sprintf("%d Times",$event["event_rep"]);
2374		}
2375	}
2376	else {
2377		$data[1] = '<i>'.__('No').'</i>';
2378	}
2379	$table_general->data[] = $data;
2380
2381	$data = array();
2382	$data[0] = __('Severity');
2383	$event_criticity = get_priority_name ($event["criticity"]);
2384
2385	$data[1] = html_print_image ($img_sev, true,
2386		array ("class" => "image_status",
2387			"width" => 12,
2388			"height" => 12,
2389			"title" => $event_criticity));
2390	$data[1] .= ' '.$event_criticity;
2391	$table_general->data[] = $data;
2392
2393	// Get Status
2394	switch($event['estado']) {
2395		case 0:
2396			$img_st = "images/star.png";
2397			$title_st = __('New event');
2398			break;
2399		case 1:
2400			$img_st = "images/tick.png";
2401			$title_st = __('Event validated');
2402			break;
2403		case 2:
2404			$img_st = "images/hourglass.png";
2405			$title_st = __('Event in process');
2406			break;
2407	}
2408
2409	$data = array();
2410	$data[0] = __('Status');
2411	$data[1] = html_print_image($img_st,true).' '.$title_st;
2412	$table_general->data[] = $data;
2413
2414	// If event is validated, show who and when acknowleded it
2415	$data = array();
2416	$data[0] = __('Acknowledged by');
2417
2418	if ($event['estado'] == 1) {
2419		$user_ack = db_get_value('fullname', 'tusuario', 'id_user', $event['id_usuario']);
2420		if(empty($user_ack)) {
2421			$user_ack = $event['id_usuario'];
2422		}
2423		$date_ack = date ($config["date_format"], $event['ack_utimestamp']);
2424		$data[1] = $user_ack.' ('.$date_ack.')';
2425	}
2426	else {
2427		$data[1] = '<i>'.__('N/A').'</i>';
2428	}
2429	$table_general->data[] = $data;
2430
2431	$data = array();
2432	$data[0] = __('Group');
2433	$data[1] = "";
2434	if (!$config['show_group_name']) {
2435		$data[1] = ui_print_group_icon ($event["id_grupo"], true);
2436	}
2437	$data[1] .= groups_get_name ($event["id_grupo"]);
2438	$table_general->data[] = $data;
2439
2440	$data = array();
2441	$data[0] = __('Tags');
2442
2443	if ($event["tags"] != '') {
2444		$tags = tags_get_tags_formatted($event["tags"]);
2445
2446		$data[1] = $tags;
2447	}
2448	else {
2449		$data[1] = '<i>' . __('N/A') . '</i>';
2450	}
2451	$table_general->data[] = $data;
2452
2453	$data = array();
2454	$data[0] = __('ID extra');
2455	if ($event["id_extra"] != '') {
2456		$data[1] = $event["id_extra"];
2457	}
2458	else {
2459		$data[1] = '<i>' . __('N/A') . '</i>';
2460	}
2461	$table_general->data[] = $data;
2462
2463	$general = '<div id="extended_event_general_page" class="extended_event_pages">' .
2464		html_print_table($table_general,true) .
2465		'</div>';
2466
2467	return $general;
2468}
2469
2470function events_page_comments ($event, $childrens_ids = array()) {
2471	////////////////////////////////////////////////////////////////////
2472	// Comments
2473	////////////////////////////////////////////////////////////////////
2474	global $config;
2475
2476	$table_comments->width = '100%';
2477	$table_comments->data = array ();
2478	$table_comments->head = array ();
2479	$table_comments->style[0] = 'width:35%; vertical-align: top; text-align: left;';
2480	$table_comments->style[1] = 'text-align: left;';
2481	$table_comments->class = "alternate rounded_cells";
2482
2483	$event_comments = $event["user_comment"];
2484	$event_comments = str_replace( array("\n", '&#x0a;'), "<br>", $event_comments);
2485
2486	// If comments are not stored in json, the format is old
2487	$event_comments_array = json_decode($event_comments, true);
2488
2489	// Show the comments more recent first
2490	$event_comments_array = array_reverse($event_comments_array);
2491
2492	if (is_null($event_comments_array)) {
2493		$comments_format = 'old';
2494	}
2495	else {
2496		$comments_format = 'new';
2497	}
2498
2499	switch($comments_format) {
2500		case 'new':
2501			if (empty($event_comments_array)) {
2502				$table_comments->style[0] = 'text-align:center;';
2503				$table_comments->colspan[0][0] = 2;
2504				$data = array();
2505				$data[0] = __('There are no comments');
2506				$table_comments->data[] = $data;
2507			}
2508
2509			foreach($event_comments_array as $c) {
2510				$data[0] = '<b>' . $c['action'] . ' by ' . $c['id_user'] . '</b>';
2511				$data[0] .= '<br><br><i>' . date ($config["date_format"], $c['utimestamp']) . '</i>';
2512				$data[1] = $c['comment'];
2513				$table_comments->data[] = $data;
2514			}
2515			break;
2516		case 'old':
2517			$comments_array = explode('<br>',$event_comments);
2518
2519			// Split comments and put in table
2520			$col = 0;
2521			$data = array();
2522
2523			foreach ($comments_array as $c) {
2524				switch ($col) {
2525					case 0:
2526						$row_text = preg_replace('/\s*--\s*/',"",$c);
2527						$row_text = preg_replace('/\<\/b\>/',"</i>",$row_text);
2528						$row_text = preg_replace('/\[/',"</b><br><br><i>[",$row_text);
2529						$row_text = preg_replace('/[\[|\]]/',"",$row_text);
2530						break;
2531					case 1:
2532						$row_text = preg_replace("/[\r\n|\r|\n]/","<br>",io_safe_output(strip_tags($c)));
2533						break;
2534				}
2535
2536				$data[$col] = $row_text;
2537
2538				$col++;
2539
2540				if($col == 2) {
2541					$col = 0;
2542					$table_comments->data[] = $data;
2543					$data = array();
2544				}
2545			}
2546
2547			if (count($comments_array) == 1 && $comments_array[0] == '') {
2548				$table_comments->style[0] = 'text-align:center;';
2549				$table_comments->colspan[0][0] = 2;
2550				$data = array();
2551				$data[0] = __('There are no comments');
2552				$table_comments->data[] = $data;
2553			}
2554			break;
2555	}
2556
2557	if ((tags_checks_event_acl($config["id_user"], $event["id_grupo"], "EM", $event['clean_tags'], $childrens_ids)) || (tags_checks_event_acl($config["id_user"], $event["id_grupo"], "EW", $event['clean_tags'],$childrens_ids))) {
2558		$comments_form = '<br><div id="comments_form" style="width:98%;">'.html_print_textarea("comment", 3, 10, '', 'style="min-height: 15px; width: 100%;"', true);
2559		$comments_form .= '<br><div style="text-align:right;">'.html_print_button(__('Add comment'),'comment_button',false,'event_comment();','class="sub next"',true).'</div><br></div>';
2560	}
2561	else {
2562		$comments_form = '';
2563	}
2564
2565	$comments = '<div id="extended_event_comments_page" class="extended_event_pages">'.$comments_form.html_print_table($table_comments, true).'</div>';
2566
2567	return $comments;
2568}
2569
2570function events_clean_tags ($tags) {
2571	if(empty($tags)) {
2572		return array();
2573	}
2574
2575	$event_tags = tags_get_tags_formatted ($tags, false);
2576	return explode(',',str_replace(' ','',$event_tags));
2577}
2578
2579/**
2580 * Get all the events happened in a group during a period of time.
2581 *
2582 * The returned events will be in the time interval ($date - $period, $date]
2583 *
2584 * @param mixed $id_group Group id to get events for.
2585 * @param int $period Period of time in seconds to get events.
2586 * @param int $date Beginning date to get events.
2587 *
2588 * @return array An array with all the events happened.
2589 */
2590function events_get_count_events_by_agent ($id_group, $period, $date,
2591	$filter_event_validated = false, $filter_event_critical = false,
2592	$filter_event_warning = false, $filter_event_no_validated = false,
2593	$filter_event_search = false) {
2594
2595	global $config;
2596
2597	$id_group = groups_safe_acl ($config["id_user"], $id_group, "AR");
2598
2599	if (empty ($id_group)) {
2600		//An empty array means the user doesn't have access
2601		return false;
2602	}
2603
2604	$datelimit = $date - $period;
2605
2606	$sql_where = ' AND 1 = 1 ';
2607	$criticities = array();
2608	if ($filter_event_critical) {
2609		$criticities[] = 4;
2610	}
2611	if ($filter_event_warning) {
2612		$criticities[] = 3;
2613	}
2614	if (!empty($criticities)) {
2615		$sql_where .= ' AND criticity IN (' . implode(', ', $criticities) . ')';
2616	}
2617
2618	if ($filter_event_validated) {
2619		$sql_where .= ' AND estado = 1 ';
2620	}
2621	if ($filter_event_no_validated) {
2622		$sql_where .= ' AND estado = 0 ';
2623	}
2624
2625	if (!empty($filter_event_search)) {
2626		$sql_where .= ' AND (evento LIKE "%%'. io_safe_input($filter_event_search) . '%%"'.
2627			' OR id_evento LIKE "%%' . io_safe_input($filter_event_search) . '%%")';
2628	}
2629
2630	$sql = sprintf ('SELECT id_agente,
2631		(SELECT t2.nombre
2632			FROM tagente t2
2633			WHERE t2.id_agente = t3.id_agente) AS agent_name,
2634		COUNT(*) AS count
2635		FROM tevento t3
2636		WHERE utimestamp > %d AND utimestamp <= %d
2637			AND id_grupo IN (%s) ' . $sql_where . '
2638		GROUP BY id_agente',
2639		$datelimit, $date, implode (",", $id_group));
2640
2641	$rows = db_get_all_rows_sql ($sql);
2642
2643	if ($rows == false)
2644		$rows = array();
2645
2646	$return = array();
2647	foreach ($rows as $row) {
2648		$agent_name = $row['agent_name'];
2649		if (empty($row['agent_name'])) {
2650			$agent_name = __('Pandora System');
2651		}
2652		$return[$agent_name] = $row['count'];
2653	}
2654
2655	return $return;
2656}
2657
2658/**
2659 * Get all the events happened in a group during a period of time.
2660 *
2661 * The returned events will be in the time interval ($date - $period, $date]
2662 *
2663 * @param mixed $id_group Group id to get events for.
2664 * @param int $period Period of time in seconds to get events.
2665 * @param int $date Beginning date to get events.
2666 *
2667 * @return array An array with all the events happened.
2668 */
2669function events_get_count_events_validated_by_user ($filter, $period, $date,
2670	$filter_event_validated = false, $filter_event_critical = false,
2671	$filter_event_warning = false, $filter_event_no_validated = false,
2672	$filter_event_search = false) {
2673
2674	global $config;
2675
2676	$sql_filter = ' AND 1=1 ';
2677	if (isset($filter['id_group'])) {
2678		$id_group = groups_safe_acl ($config["id_user"], $filter['id_group'], "AR");
2679
2680		if (empty ($id_group)) {
2681			//An empty array means the user doesn't have access
2682			return false;
2683		}
2684
2685		$sql_filter .=
2686			sprintf(' AND id_grupo IN (%s) ', implode (",", $id_group));
2687	}
2688	if (!empty($filter['id_agent'])) {
2689		$sql_filter .=
2690			sprintf(' AND id_agente = %d ', $filter['id_agent']);
2691	}
2692
2693	$datelimit = $date - $period;
2694
2695	$sql_where = ' AND 1 = 1 ';
2696	$criticities = array();
2697	if ($filter_event_critical) {
2698		$criticities[] = 4;
2699	}
2700	if ($filter_event_warning) {
2701		$criticities[] = 3;
2702	}
2703	if (!empty($criticities)) {
2704		$sql_where .= ' AND criticity IN (' . implode(', ', $criticities) . ')';
2705	}
2706
2707	if ($filter_event_validated) {
2708		$sql_where .= ' AND estado = 1 ';
2709	}
2710	if ($filter_event_no_validated) {
2711		$sql_where .= ' AND estado = 0 ';
2712	}
2713
2714	if (!empty($filter_event_search)) {
2715		$sql_where .= ' AND (evento LIKE "%%'. io_safe_input($filter_event_search) . '%%"'.
2716			' OR id_evento LIKE "%%' . io_safe_input($filter_event_search) . '%%")';
2717	}
2718
2719	$sql = sprintf ('SELECT id_usuario,
2720		(SELECT t2.fullname
2721			FROM tusuario t2
2722			WHERE t2.id_user = t3.id_usuario) AS user_name,
2723		COUNT(*) AS count
2724		FROM tevento t3
2725		WHERE utimestamp > %d AND utimestamp <= %d
2726			%s ' . $sql_where . '
2727		GROUP BY id_usuario',
2728		$datelimit, $date, $sql_filter);
2729
2730	$rows = db_get_all_rows_sql ($sql);
2731
2732	if ($rows == false)
2733		$rows = array();
2734
2735	$return = array();
2736	foreach ($rows as $row) {
2737		$user_name = $row['user_name'];
2738		if (empty($row['user_name'])) {
2739			$user_name = __('Unknown');
2740		}
2741		$return[$user_name] = $row['count'];
2742	}
2743
2744	return $return;
2745}
2746
2747/**
2748 * Get all the events happened in a group during a period of time.
2749 *
2750 * The returned events will be in the time interval ($date - $period, $date]
2751 *
2752 * @param mixed $id_group Group id to get events for.
2753 * @param int $period Period of time in seconds to get events.
2754 * @param int $date Beginning date to get events.
2755 *
2756 * @return array An array with all the events happened.
2757 */
2758function events_get_count_events_by_criticity ($filter, $period, $date,
2759	$filter_event_validated = false, $filter_event_critical = false,
2760	$filter_event_warning = false, $filter_event_no_validated = false,
2761	$filter_event_search = false) {
2762
2763	global $config;
2764
2765	$sql_filter = ' AND 1=1 ';
2766	if (isset($filter['id_group'])) {
2767		$id_group = groups_safe_acl ($config["id_user"], $filter['id_group'], "AR");
2768
2769		if (empty ($id_group)) {
2770			//An empty array means the user doesn't have access
2771			return false;
2772		}
2773
2774		$sql_filter .=
2775			sprintf(' AND id_grupo IN (%s) ', implode (",", $id_group));
2776	}
2777	if (!empty($filter['id_agent'])) {
2778		$sql_filter .=
2779			sprintf(' AND id_agente = %d ', $filter['id_agent']);
2780	}
2781
2782	$datelimit = $date - $period;
2783
2784	$sql_where = ' AND 1 = 1 ';
2785	$criticities = array();
2786	if ($filter_event_critical) {
2787		$criticities[] = 4;
2788	}
2789	if ($filter_event_warning) {
2790		$criticities[] = 3;
2791	}
2792	if (!empty($criticities)) {
2793		$sql_where .= ' AND criticity IN (' . implode(', ', $criticities) . ')';
2794	}
2795
2796	if ($filter_event_validated) {
2797		$sql_where .= ' AND estado = 1 ';
2798	}
2799	if ($filter_event_no_validated) {
2800		$sql_where .= ' AND estado = 0 ';
2801	}
2802
2803	if (!empty($filter_event_search)) {
2804		$sql_where .= ' AND (evento LIKE "%%'. io_safe_input($filter_event_search) . '%%"'.
2805			' OR id_evento LIKE "%%' . io_safe_input($filter_event_search) . '%%")';
2806	}
2807
2808	$sql = sprintf ('SELECT criticity,
2809		COUNT(*) AS count
2810		FROM tevento
2811		WHERE utimestamp > %d AND utimestamp <= %d
2812			%s ' . $sql_where . '
2813		GROUP BY criticity',
2814		$datelimit, $date, $sql_filter);
2815
2816	$rows = db_get_all_rows_sql ($sql);
2817
2818	if ($rows == false)
2819		$rows = array();
2820
2821	$return = array();
2822	foreach ($rows as $row) {
2823		$return[get_priority_name($row['criticity'])] = $row['count'];
2824	}
2825
2826	return $return;
2827}
2828
2829/**
2830 * Get all the events happened in a group during a period of time.
2831 *
2832 * The returned events will be in the time interval ($date - $period, $date]
2833 *
2834 * @param mixed $id_group Group id to get events for.
2835 * @param int $period Period of time in seconds to get events.
2836 * @param int $date Beginning date to get events.
2837 *
2838 * @return array An array with all the events happened.
2839 */
2840function events_get_count_events_validated ($filter, $period = null, $date = null,
2841	$filter_event_validated = false, $filter_event_critical = false,
2842	$filter_event_warning = false, $filter_event_no_validated = false,
2843	$filter_event_search = false) {
2844
2845	global $config;
2846
2847	$sql_filter = " 1=1 ";
2848	if (isset($filter['id_group'])) {
2849		$id_group = groups_safe_acl ($config["id_user"], $filter['id_group'], "AR");
2850
2851		if (empty ($id_group)) {
2852			//An empty array means the user doesn't have access
2853			return false;
2854		}
2855
2856		$sql_filter .=
2857			sprintf(" AND id_grupo IN (%s) ", implode (",", $id_group));
2858	}
2859	if (!empty($filter['id_agent'])) {
2860		$sql_filter .=
2861			sprintf(" AND id_agente = %d ", $filter['id_agent']);
2862	}
2863
2864	$date_filter = '';
2865	if (!empty($date) && !empty($period)) {
2866		$datelimit = $date - $period;
2867
2868		$date_filter .= sprintf (" AND utimestamp > %d AND utimestamp <= %d ",
2869			$datelimit, $date);
2870	}
2871	else if (!empty($period)) {
2872		$date = time();
2873		$datelimit = $date - $period;
2874
2875		$date_filter .= sprintf (" AND utimestamp > %d AND utimestamp <= %d ",
2876			$datelimit, $date);
2877	}
2878	else if (!empty($date)) {
2879		$date_filter .= sprintf (" AND utimestamp <= %d ", $date);
2880	}
2881
2882	$sql_where = " AND 1=1 ";
2883	$criticities = array();
2884	if ($filter_event_critical) {
2885		$criticities[] = 4;
2886	}
2887	if ($filter_event_warning) {
2888		$criticities[] = 3;
2889	}
2890	if (!empty($criticities)) {
2891		$sql_where .= " AND criticity IN (" . implode(",", $criticities) . ")";
2892	}
2893
2894	if ($filter_event_validated) {
2895		$sql_where .= " AND estado = 1 ";
2896	}
2897	if ($filter_event_no_validated) {
2898		$sql_where .= " AND estado = 0 ";
2899	}
2900
2901	if (!empty($filter_event_search)) {
2902		$sql_where .= " AND (evento LIKE '%%" . io_safe_input($filter_event_search) . "%%'" .
2903			" OR id_evento LIKE '%%" . io_safe_input($filter_event_search) . "%%')";
2904	}
2905
2906	$sql = sprintf ("SELECT estado, COUNT(*) AS count FROM tevento WHERE %s " . $sql_where . " GROUP BY estado", $sql_filter);
2907
2908	$rows = db_get_all_rows_sql ($sql);
2909
2910	if ($rows == false)
2911		$rows = array();
2912
2913	$return = array_reduce($rows, function($carry, $item) {
2914		$status = (int) $item['estado'];
2915		$count = (int) $item['count'];
2916
2917		if ($status === 1) {
2918			$carry[__('Validated')] += $count;
2919		}
2920		else if ($status === 0) {
2921			$carry[__('Not validated')] += $count;
2922		}
2923
2924		return $carry;
2925
2926	}, array(__('Validated') => 0, __('Not validated') => 0));
2927
2928	return $return;
2929}
2930
2931function events_checks_event_tags($event_data, $acltags) {
2932	global $config;
2933
2934	if (empty($acltags[$event_data['id_grupo']])) {
2935			return true;
2936	} else {
2937		$tags_arr_acl = explode(',',$acltags[$event_data['id_grupo']]);
2938		$tags_arr_event = explode(',',$event_data['tags']);
2939
2940		foreach ($tags_arr_acl as $tag) {
2941			$tag_name = tags_get_name($tag);
2942			if (in_array($tag_name, $tags_arr_event)) {
2943				return true;
2944			} else {
2945				$has_tag = false;
2946			}
2947		}
2948		if (!$has_tag) {
2949			return false;
2950		}
2951	}
2952	return false;
2953}
2954?>
2955