From e6f93b51bf09fca8196e8b864d6c49aefe2ef427 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Volker=20Fr=C3=B6hlich?= <volker27@gmx.at>
Date: Wed, 27 Nov 2013 15:32:21 +0100
Subject: [PATCH] ZBXNEXT-1810 -- Filter Latest Data by item value

Ported latest 2.0 patch
---
 include/defines.inc.php |    5 ++
 latest.php              |  109 ++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 93 insertions(+), 21 deletions(-)

diff --git a/include/defines.inc.php b/include/defines.inc.php
index 9ca43ca..c394ffa 100644
--- a/include/defines.inc.php
+++ b/include/defines.inc.php
@@ -563,6 +563,11 @@ define('SCREEN_REFRESH_RESPONSIVENESS',	10);
 
 define('DEFAULT_LATEST_ISSUES_CNT', 20);
 
+define('LATEST_DATA_MATCH_SUBSTRING', 0);
+define('LATEST_DATA_MATCH_NOT_SUBSTRING', 1);
+define('LATEST_DATA_MATCH_REGEX', 2);
+define('LATEST_DATA_MATCH_NOT_REGEX', 3);
+
 // alignes
 define('HALIGN_DEFAULT',	0);
 define('HALIGN_CENTER',		0);
diff --git a/latest.php b/latest.php
index db3d753..d85e3ef 100644
--- a/latest.php
+++ b/latest.php
@@ -45,6 +45,8 @@ $fields = array(
 	'fullscreen'=>			array(T_ZBX_INT, O_OPT,	P_SYS,	IN('0,1'),	NULL),
 // filter
 	'select'=>				array(T_ZBX_STR, O_OPT, NULL,	NULL,		NULL),
+	'select_val'=>			array(T_ZBX_STR, O_OPT, NULL,	NULL,		NULL),
+	'select_val_opts'=>			array(T_ZBX_INT, O_OPT, NULL,	NULL,		NULL),
 	'show_without_data'=>	array(T_ZBX_INT, O_OPT, NULL,	IN('0,1'),	NULL),
 	'show_details'=>		array(T_ZBX_INT, O_OPT, NULL,	IN('0,1'),	NULL),
 	'filter_rst'=>			array(T_ZBX_INT, O_OPT,	P_SYS,	IN('0,1'),	NULL),
@@ -114,22 +116,30 @@ require_once dirname(__FILE__).'/include/views/js/monitoring.latest.js.php';
  * Filter
  */
 $filterSelect = getRequest('select');
+$filterSelectVal = getRequest('select_val');
+$filterSelectValOpts = getRequest('select_val_opts');
 $filterShowWithoutData = getRequest('show_without_data', 0);
 $filterShowDetails = getRequest('show_details', 0);
 
 if (hasRequest('filter_rst')) {
 	$filterSelect = '';
+	$filterSelectVal= '';
+	$filterSelectValOpts = LATEST_DATA_MATCH_SUBSTRING;
 	$filterShowWithoutData = 0;
 	$filterShowDetails = 0;
 }
 
 if (hasRequest('filter_set') || hasRequest('filter_rst')) {
 	CProfile::update('web.latest.filter.select', $filterSelect, PROFILE_TYPE_STR);
+	CProfile::update('web.latest.filter.select_val', $filterSelectVal, PROFILE_TYPE_STR);
+	CProfile::update('web.latest.filter.select_val_opts', $filterSelectValOpts, PROFILE_TYPE_STR);
 	CProfile::update('web.latest.filter.show_without_data', $filterShowWithoutData, PROFILE_TYPE_INT);
 	CProfile::update('web.latest.filter.show_details', $filterShowDetails, PROFILE_TYPE_INT);
 }
 else {
 	$filterSelect = CProfile::get('web.latest.filter.select', '');
+	$filterSelectVal = CProfile::get('web.latest.filter.select_val', '');
+	$filterSelectValOpts = CProfile::get('web.latest.filter.select_val_opts', '');
 	$filterShowWithoutData = CProfile::get('web.latest.filter.show_without_data', 0);
 	$filterShowDetails = CProfile::get('web.latest.filter.show_details', 0);
 }
@@ -297,6 +307,7 @@ $filterForm = new CFormTable(null, null, 'get');
 $filterForm->setAttribute('name',' zbx_filter');
 $filterForm->setAttribute('id', 'zbx_filter');
 $filterForm->addRow(_('Show items with name like'), new CTextBox('select', $filterSelect, 20));
+$filterForm->addRow(array(_('Show items with values matching'),SPACE, new CComboBox('select_val_opts', $filterSelectValOpts, null, array('substring', 'not substring', 'regex', 'not regex'))), new CTextBox('select_val',$filterSelectVal,20));
 $filterForm->addRow(_('Show items without data'), new CCheckBox('show_without_data', $filterShowWithoutData, null, 1));
 $filterForm->addRow(_('Show details'), new CCheckBox('show_details', $filterShowDetails, null, 1));
 $filterForm->addItemToBottomRow(new CSubmit('filter_set', _('Filter')));
@@ -377,6 +388,31 @@ foreach ($items as $key => $item){
 		$lastValue = UNKNOWN_VALUE;
 	}
 
+	if(!empty($filterSelectVal)) {
+		switch ($filterSelectValOpts) {
+		case LATEST_DATA_MATCH_SUBSTRING:
+			$zbxMatch = zbx_stristr($lastValue, $filterSelectVal);
+			break;
+		case LATEST_DATA_MATCH_NOT_SUBSTRING:
+			$zbxMatch = !zbx_stristr($lastValue, $filterSelectVal);
+			break;
+		case LATEST_DATA_MATCH_REGEX:
+			$zbxMatch = preg_match('|'.$filterSelectVal.'|', $lastValue);
+			break;
+		case LATEST_DATA_MATCH_NOT_REGEX:
+			$zbxMatch = !preg_match('|'.$filterSelectVal.'|', $lastValue);
+			break;
+		}
+	}
+	else {
+		$zbxMatch = true;
+	}
+
+	// Remove items from application if the value doesn't match the filter
+	if(!$zbxMatch) {
+		continue;
+	}
+
 	// change
 	$digits = ($item['value_type'] == ITEM_VALUE_TYPE_FLOAT) ? 2 : 0;
 	if ($lastHistory && $prevHistory
@@ -474,12 +510,15 @@ foreach ($items as $key => $item){
 
 		$applications[$applicationId]['item_cnt']++;
 		$tab_rows[$applicationId][] = $row;
+		if(!$zbxMatch) {
+			$applications[$applicationId]['item_cnt']--;
+		}
 	}
 
 	// remove items with applications from the collection
 	unset($items[$key]);
 }
-unset($app_rows, $db_app);
+unset($app_rows, $dbApp);
 
 foreach ($applications as $appid => $dbApp) {
 	$host = $hosts[$dbApp['hostid']];
@@ -558,6 +597,32 @@ foreach ($items as $item) {
 		$lastValue = UNKNOWN_VALUE;
 	}
 
+	if(!empty($filterSelectVal)) {
+		switch ($filterSelectValOpts) {
+		case LATEST_DATA_MATCH_SUBSTRING:
+			$zbxMatch = zbx_stristr($lastValue, $filterSelectVal);
+			break;
+		case LATEST_DATA_MATCH_NOT_SUBSTRING:
+			$zbxMatch = !zbx_stristr($lastValue, $filterSelectVal);
+			break;
+		case LATEST_DATA_MATCH_REGEX:
+			$zbxMatch = preg_match('|'.$filterSelectVal.'|', $lastValue);
+			break;
+		case LATEST_DATA_MATCH_NOT_REGEX:
+			$zbxMatch = !preg_match('|'.$filterSelectVal.'|', $lastValue);
+			break;
+		}
+	}
+	else {
+		$zbxMatch = true;
+	}
+
+	// Remove items from application if the value doesn't match the filter
+	if(!$zbxMatch) {
+		$host['item_cnt']--;
+		continue;
+	}
+
 	// column "change"
 	$digits = ($item['value_type'] == ITEM_VALUE_TYPE_FLOAT) ? 2 : 0;
 	if (isset($lastHistory['value']) && isset($prevHistory['value'])
@@ -670,28 +735,30 @@ foreach ($hosts as $hostId => $dbHost) {
 	$toggle->setAttribute('data-app-id', '0_'.$host['hostid']);
 	$toggle->setAttribute('data-open-state', $openState);
 
-	$hostName = null;
+	if ($dbHost['item_cnt'] != 0) {
+		$hostName = null;
 
-	if ($_REQUEST['hostid'] == 0) {
-		$hostName = new CSpan($host['name'],
-			'link_menu menu-host'.(($host['status'] == HOST_STATUS_NOT_MONITORED) ? ' not-monitored' : '')
-		);
-		$hostName->setMenuPopup(getMenuPopupHost($host, $hostScripts[$host['hostid']]));
-	}
+		if ($_REQUEST['hostid'] == 0) {
+			$hostName = new CSpan($host['name'],
+				'link_menu menu-host'.(($host['status'] == HOST_STATUS_NOT_MONITORED) ? ' not-monitored' : '')
+			);
+			$hostName->setMenuPopup(getMenuPopupHost($host, $hostScripts[$host['hostid']]));
+		}
 
-	// add toggle row
-	$table->addRow(array(
-		$toggle,
-		get_node_name_by_elid($dbHost['hostid']),
-		$hostName,
-		new CCol(
-			array(
-				bold('- '.('other').' -'),
-				SPACE.'('._n('%1$s Item', '%1$s Items', $dbHost['item_cnt']).')'
-			),
-			null, $filterShowDetails ? 10 : 5
-		)
-	), 'odd_row');
+		// add toggle row
+		$table->addRow(array(
+			$toggle,
+			get_node_name_by_elid($dbHost['hostid']),
+			$hostName,
+			new CCol(
+				array(
+					bold('- '.('other').' -'),
+					SPACE.'('._n('%1$s Item', '%1$s Items', $dbHost['item_cnt']).')'
+				),
+				null, $filterShowDetails ? 10 : 5
+			)
+		), 'odd_row');
+	}
 
 	// add toggle sub rows
 	foreach($appRows as $row) {
-- 
1.7.1

