From cbbf7e8363c4103544a532f3fc41142324bb9386 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Volker=20Fr=C3=B6hlich?= <volker.froehlich@meduniwien.ac.at>
Date: Tue, 26 Mar 2013 14:20:47 +0100
Subject: [PATCH] ZBXNEXT-410 (both patches)
 - Event filtering

Fix duration column on events page (ZBXNEXT-410)

The durations were wrong due to API filtering and the way they are calculated.
---
 api/classes/CEvent.php  |   25 +++++++++++++
 events.php              |   92 +++++++++++++++++++++++++++++++++++++++++++++-
 include/defines.inc.php |   10 +++++
 3 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/api/classes/CEvent.php b/api/classes/CEvent.php
index ef0c5e0..185a2c6 100644
--- a/api/classes/CEvent.php
+++ b/api/classes/CEvent.php
@@ -95,6 +95,7 @@ class CEvent extends CZBXAPI {
 			'object'					=> EVENT_OBJECT_TRIGGER,
 			'source'					=> EVENT_SOURCE_TRIGGERS,
 			'acknowledged'				=> null,
+			'severity'					=> null,
 			'nopermissions'				=> null,
 			// filter
 			'value'						=> null,
@@ -105,6 +106,7 @@ class CEvent extends CZBXAPI {
 			// filter
 			'filter'					=> null,
 			'search'					=> null,
+			'description'					=> null,
 			'searchByAny'				=> null,
 			'startSearch'				=> null,
 			'excludeSearch'				=> null,
@@ -299,6 +301,29 @@ class CEvent extends CZBXAPI {
 			$sqlParts['where'][] = 'e.acknowledged='.($options['acknowledged'] ? 1 : 0);
 		}
 
+		// severity
+		if (!is_null($options['severity'])) {
+			zbx_value2array($options['severity']);
+			$sqlParts['from']['triggers'] = 'triggers t';
+			$sqlParts['where'][] = 'e.objectid=t.triggerid';
+			$sqlParts['where'][] = dbConditionInt('t.priority', $options['severity']);
+		}
+
+        // description
+        if (!is_null($options['description'])) {
+            $sqlParts['from']['triggers'] = 'triggers t';
+            $sqlParts['where'][] = 'e.objectid=t.triggerid';
+            $descriptionSearch = array(
+                'search' => array(
+                    'description' => $options['description'],
+                    ),
+                'startSearch' => null,
+                'searchByAny' => null,
+                'excludeSearch' => null
+            );
+            zbx_db_search('triggers t', $descriptionSearch, $sqlParts);
+        }
+            
 		// time_from
 		if (!is_null($options['time_from'])) {
 			$sqlParts['where'][] = 'e.clock>='.zbx_dbstr($options['time_from']);
diff --git a/events.php b/events.php
index ea4dad8..491d9e7 100644
--- a/events.php
+++ b/events.php
@@ -74,6 +74,12 @@ $fields = array(
 	'csv_export'=>		array(T_ZBX_STR, O_OPT, P_SYS,	null,		null),
 	'filter_rst'=>		array(T_ZBX_INT, O_OPT, P_SYS,	IN(array(0,1)), null),
 	'filter_set'=>		array(T_ZBX_STR, O_OPT, P_SYS,	null,		null),
+	'txt_select'=>		array(T_ZBX_STR, O_OPT,	null,	null,	null),
+// Severity filters
+	'show_triggers'=>	array(T_ZBX_INT, O_OPT, P_SYS,  IN(array(0,1,2,3)), null),
+	'ack_status'=>		array(T_ZBX_INT, O_OPT, P_SYS,  IN(array(0,1,2)), null),
+	'show_severity'=>	array(T_ZBX_INT, O_OPT, P_SYS,  IN(array(-1,0,1,2,3,4,5)), null),
+//ajax
 	// ajax
 	'favobj'=>			array(T_ZBX_STR, O_OPT, P_ACT,	null,		null),
 	'favref'=>			array(T_ZBX_STR, O_OPT, P_ACT,	NOT_EMPTY,	'isset({favobj})&&"filter"=={favobj}'),
@@ -120,6 +126,10 @@ if ($page['type'] == PAGE_TYPE_JS || $page['type'] == PAGE_TYPE_HTML_BLOCK) {
  */
 if (isset($_REQUEST['filter_rst'])) {
 	$_REQUEST['triggerid'] = 0;
+ 	$_REQUEST['txt_select'] = '';
+	$_REQUEST['show_triggers'] = EVENTS_SHOW_TRIGGERS_ALL;
+	$_REQUEST['ack_status'] = EVENTS_SHOW_ALL;
+	$_REQUEST['show_severity'] = TRIGGER_SEVERITY_NOT_CLASSIFIED;
 }
 
 $source = (get_request('triggerid') > 0)
@@ -127,6 +137,10 @@ $source = (get_request('triggerid') > 0)
 	: get_request('source', CProfile::get('web.events.source', EVENT_SOURCE_TRIGGERS));
 
 $_REQUEST['triggerid'] = get_request('triggerid', CProfile::get('web.events.filter.triggerid', 0));
+$_REQUEST['txt_select'] = get_request('txt_select', CProfile::get('web.events.filter.txt_select', ''));
+$_REQUEST['show_triggers'] = get_request('show_triggers', CProfile::get('web.events.filter.show_triggers', EVENTS_SHOW_TRIGGERS_ALL));
+$_REQUEST['ack_status'] = get_request('ack_status', CProfile::get('web.events.filter.ack_status', EVENTS_SHOW_ALL));
+$_REQUEST['show_severity'] = get_request('show_severity', CProfile::get('web.events.filter.show_severity', TRIGGER_SEVERITY_NOT_CLASSIFIED));
 
 // change triggerId filter if change hostId
 if ($_REQUEST['triggerid'] > 0 && isset($_REQUEST['hostid'])) {
@@ -213,6 +227,10 @@ if ($_REQUEST['triggerid'] > 0 && isset($_REQUEST['hostid'])) {
 
 if (isset($_REQUEST['filter_set']) || isset($_REQUEST['filter_rst'])) {
 	CProfile::update('web.events.filter.triggerid', $_REQUEST['triggerid'], PROFILE_TYPE_ID);
+	CProfile::update('web.events.filter.txt_select', $_REQUEST['txt_select'], PROFILE_TYPE_STR);
+	CProfile::update('web.events.filter.show_triggers',$_REQUEST['show_triggers'], PROFILE_TYPE_INT);
+	CProfile::update('web.events.filter.ack_status',$_REQUEST['ack_status'], PROFILE_TYPE_INT);
+	CProfile::update('web.events.filter.show_severity',$_REQUEST['show_severity'], PROFILE_TYPE_INT);
 }
 
 CProfile::update('web.events.source', $source, PROFILE_TYPE_INT);
@@ -353,6 +371,35 @@ if ($source == EVENT_SOURCE_TRIGGERS) {
 		), 'form_row_r')
 	)));
 
+	$triggerStatusComboBox = new CComboBox('show_triggers', $_REQUEST['show_triggers']);
+	$triggerStatusComboBox->addItem(EVENTS_SHOW_TRIGGERS_ALL, _('Any'));
+	$triggerStatusComboBox->addItem(EVENTS_SHOW_TRIGGERS_OK, _('Ok'));
+	$triggerStatusComboBox->additem(EVENTS_SHOW_TRIGGERS_PROBLEM, _('Problem'));
+	$filterForm->addRow(_('Triggers status'), $triggerStatusComboBox);
+
+	$config = select_config();
+	if($config['event_ack_enable']){
+		$ackStatusComboBox = new CComboBox('ack_status', $_REQUEST['ack_status']);
+		$ackStatusComboBox->addItem(EVENTS_SHOW_ALL, _('Any'));
+		$ackStatusComboBox->additem(EVENTS_SHOW_ZBX_ACK, _('Yes'));
+		$ackStatusComboBox->additem(EVENTS_SHOW_ZBX_UNACK, _('No'));
+		$filterForm->addRow(_('Acknowledge status'), $ackStatusComboBox);
+	}
+	$severityComboBox = new CComboBox('show_severity', $_REQUEST['show_severity']);
+	$severityComboBox->addItems(array(
+		TRIGGER_SEVERITY_NOT_CLASSIFIED => getSeverityCaption(TRIGGER_SEVERITY_NOT_CLASSIFIED),
+		TRIGGER_SEVERITY_INFORMATION => getSeverityCaption(TRIGGER_SEVERITY_INFORMATION),
+		TRIGGER_SEVERITY_WARNING => getSeverityCaption(TRIGGER_SEVERITY_WARNING),
+		TRIGGER_SEVERITY_AVERAGE => getSeverityCaption(TRIGGER_SEVERITY_AVERAGE),
+		TRIGGER_SEVERITY_HIGH => getSeverityCaption(TRIGGER_SEVERITY_HIGH),
+		TRIGGER_SEVERITY_DISASTER => getSeverityCaption(TRIGGER_SEVERITY_DISASTER)
+	));
+
+	$filterForm->addRow(_('Minimum trigger severity'), $severityComboBox);
+	$filterForm->addRow(_('Filter by name'), new CTextBox('txt_select', $_REQUEST['txt_select'], 40));
+
+	$reset = new CButton('filter_rst', _('Reset'), 'javascript: var uri = new Curl(location.href); uri.setArgument("filter_rst",1); location.href = uri.getUrl();');
+
 	$filterForm->addItemToBottomRow(new CSubmit('filter_set', _('Filter')));
 	$filterForm->addItemToBottomRow(new CButton('filter_rst', _('Reset'),
 		'javascript: var uri = new Curl(location.href); uri.setArgument("filter_rst", 1); location.href = uri.getUrl();'));
@@ -614,10 +661,11 @@ else {
 			else if ($pageFilter->groupid > 0) {
 				$options['groupids'] = $pageFilter->groupid;
 			}
+			
 			$triggers = API::Trigger()->get($options);
 
 			// query event with short data
-			$events = API::Event()->get(array(
+			$eventOptions = array(
 				'source' => EVENT_SOURCE_TRIGGERS,
 				'object' => EVENT_OBJECT_TRIGGER,
 				'nodeids' => get_current_nodeid(),
@@ -628,11 +676,45 @@ else {
 				'sortfield' => array('clock', 'eventid'),
 				'sortorder' => ZBX_SORT_DOWN,
 				'limit' => $config['search_limit'] + 1
-			));
+			);
+
+			if($_REQUEST['show_triggers'] == EVENTS_SHOW_TRIGGERS_OK) {
+				$eventOptions['value'] = array(0, 2);
+			}
+
+			if($_REQUEST['show_triggers'] == EVENTS_SHOW_TRIGGERS_PROBLEM) {
+				$eventOptions['value'] = array(1, 2);
+			}
+
+			if($_REQUEST['ack_status'] == EVENTS_SHOW_ZBX_ACK) {
+				$eventOptions['acknowledged'] = EVENTS_SHOW_ZBX_ACK;
+			}
+
+			if($_REQUEST['ack_status'] == EVENTS_SHOW_ZBX_UNACK) {
+				$eventOptions['acknowledged'] = EVENTS_SHOW_ZBX_UNACK;
+			}
+
+            #TODO: Use $config instead
+			if(isset($_REQUEST['show_severity'])) {
+                # There's no min_severity option as there is for triggers
+				$eventOptions['severity'] = range($_REQUEST['show_severity'], TRIGGER_SEVERITY_DISASTER);
+			}
+
+            // Trigger description filter string
+            if(!zbx_empty($_REQUEST['txt_select'])){
+                $eventOptions['description'] = $_REQUEST['txt_select'];
+			}
+
+			$events = API::Event()->get($eventOptions);
 
 			// get pagging
 			$paging = getPagingLine($events);
 
+			// Remove value filtering and query again
+			// This allows for a correct counter and correct status filtering results
+			unset($eventOptions['value']);
+			$events = API::Event()->get($eventOptions);
+
 			// query event with extend data
 			$events = API::Event()->get(array(
 				'source' => EVENT_SOURCE_TRIGGERS,
@@ -713,6 +795,12 @@ else {
 					? zbx_date2age($event['clock'], $nextEvent['clock'])
 					: zbx_date2age($event['clock']);
 
+				// Only abandon an event after calculating the duration
+				// if it doesn't match the status filter
+				if (!($_REQUEST['show_triggers'] == $event['value'] || $_REQUEST['show_triggers'] == EVENTS_SHOW_TRIGGERS_ALL)) {
+					continue;
+				}
+
 				$statusSpan = new CSpan(trigger_value2str($event['value']));
 
 				// add colors and blinking to span depending on configuration and trigger parameters
diff --git a/include/defines.inc.php b/include/defines.inc.php
index 9ca43ca..f413156 100644
--- a/include/defines.inc.php
+++ b/include/defines.inc.php
@@ -85,6 +85,16 @@ define('EVENTS_OPTION_NOEVENT', 1);
 define('EVENTS_OPTION_ALL',		2);
 define('EVENTS_OPTION_NOT_ACK', 3);
 
+// Event tracking
+define('EVENTS_SHOW_ZBX_UNACK',        0);
+define('EVENTS_SHOW_ZBX_ACK',  1);
+define('EVENTS_SHOW_ALL',      2);
+
+define('EVENTS_SHOW_TRIGGERS_OK',      0);
+define('EVENTS_SHOW_TRIGGERS_PROBLEM', 1);
+define('EVENTS_SHOW_TRIGGERS_UNKNOWN', 2);
+define('EVENTS_SHOW_TRIGGERS_ALL',     3);
+
 define('ZBX_FONT_NAME', 'DejaVuSans');
 
 define('ZBX_AUTH_INTERNAL',	0);
-- 
1.7.1

