--- ./include/menu.inc.php.orig	2015-03-12 10:25:16.000000000 +0100
+++ ./include/menu.inc.php	2015-03-18 14:04:46.000000000 +0100
@@ -138,6 +138,10 @@
 				'sub_pages' => array('popup_period.php', 'popup_bitem.php', 'chart_bar.php')
 			),
 			array(
+				'url' => 'report99.php',
+				'label' => _('Group active triggers')
+			),
+			array(
 				'url' => 'popup.php'
 			),
 			array(
--- ./report99.php.orig	2015-05-08 17:19:13.000000000 +0200
+++ ./report99.php	2015-05-08 17:17:24.000000000 +0200
@@ -0,0 +1,237 @@
+<?php
+/*
+** Zabbix
+** Copyright (C) 2001-2015 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+**/
+
+require_once dirname(__FILE__).'/include/config.inc.php';
+require_once dirname(__FILE__).'/include/triggers.inc.php';
+
+$page['title'] = _('Group active triggers');
+$page['file'] = 'report99.php';
+$page['hist_arg'] = array();
+
+require_once dirname(__FILE__).'/include/page_header.php';
+
+//		VAR			TYPE	OPTIONAL FLAGS	VALIDATION	EXCEPTION
+$fields = array(
+	'show_severity' =>	array(T_ZBX_INT,	O_OPT,	P_SYS,	null,	null),
+	'min_hosts' =>		array(T_ZBX_INT,	O_OPT,	P_SYS,	null,	null),
+	'filter_rst' =>		array(T_ZBX_STR,	O_OPT,	P_SYS,	null,	null),
+	'show_ack' =>		array(T_ZBX_INT,	O_OPT,	P_SYS,	null,	null),
+	'filter_set' =>		array(T_ZBX_STR,	O_OPT,	P_SYS,	null,	null),
+	'sort' =>		array(T_ZBX_STR,	O_OPT,	P_SYS,	IN('"priority","lastchange","hosts","description"'),	null),
+	'sortorder' =>		array(T_ZBX_STR,	O_OPT,	P_SYS,	IN('"ASC","DESC"'),	null),
+	// 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})'),
+	'favstate' =>		array(T_ZBX_INT,	O_OPT,	P_ACT,	NOT_EMPTY,	'isset({favobj})')
+);
+check_fields($fields);
+
+/*
+ * Ajax
+ */
+if (isset($_REQUEST['favobj'])) {
+	if ($_REQUEST['favobj'] == 'filter') {
+		CProfile::update('web.report99.filter.state', $_REQUEST['favstate'], PROFILE_TYPE_INT);
+	}
+}
+
+/*
+ * Filter
+ */
+if (isset($_REQUEST['filter_rst'])) {
+        $_REQUEST['show_severity'] = TRIGGER_SEVERITY_NOT_CLASSIFIED;
+        $_REQUEST['min_hosts'] = 1;
+        $_REQUEST['show_ack'] = 0;
+}
+
+// show severity
+if (isset($_REQUEST['show_severity'])) {
+	CProfile::update('web.report99.filter.show_severity', $_REQUEST['show_severity'], PROFILE_TYPE_INT);
+}
+else {
+	$_REQUEST['show_severity'] = CProfile::get('web.report99.filter.show_severity', TRIGGER_SEVERITY_NOT_CLASSIFIED);
+}
+
+// number of hosts
+if (isset($_REQUEST['min_hosts'])) {
+	CProfile::update('web.report99.filter.min_hosts', $_REQUEST['min_hosts'], PROFILE_TYPE_INT);
+}
+else {
+	$_REQUEST['min_hosts'] = CProfile::get('web.report99.filter.min_hosts', 1);
+}
+
+// show acknowledged events
+if (isset($_REQUEST['show_ack'])) {
+	CProfile::update('web.report99.filter.show_ack', $_REQUEST['show_ack'], PROFILE_TYPE_INT);
+}
+else {
+        if (isset($_REQUEST['filter_set'])) {
+                CProfile::update('web.report99.filter.show_ack', 0, PROFILE_TYPE_INT);
+                $_REQUEST['show_ack'] = 0;
+        }
+        else {
+                $_REQUEST['show_ack'] = CProfile::get('web.report99.filter.show_ack', 0);
+        }
+}
+
+$showSeverity = $_REQUEST['show_severity'];
+$minHosts = $_REQUEST['min_hosts'];
+$showAck = $_REQUEST['show_ack'];
+
+$filterForm = new CFormTable(null, null, 'get');
+$filterForm->setAttribute('name', 'zbx_filter');
+$filterForm->setAttribute('id', 'zbx_filter');
+
+$hostsNumericBox = new CNumericBox('min_hosts', $minHosts, 4, false, false, false);
+$filterForm->addRow(_('Minimum affected hosts'), $hostsNumericBox);
+
+$severityComboBox = new CComboBox('show_severity', $showSeverity);
+$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(_('Consider acknowledged'), new CCheckBox('show_ack', $showAck, null, 1));
+
+$form = new CForm('get');
+$rprt_wdgt = new CWidget();
+$rprt_wdgt->addPageHeader(_('Group active triggers'));
+$rprt_wdgt->addHeader(_('Report'), $form);
+$rprt_wdgt->addHeaderRowNumber();
+$rprt_wdgt->addItem(BR());
+
+validate_sort_and_sortorder('lastchange', ZBX_SORT_DOWN);
+
+$sortField = $_REQUEST['sort'];
+$sortOrder = $_REQUEST['sortorder'];
+
+$table = new CTableInfo(_('No active triggers found.'));
+$table->setHeader(array(
+	make_sorting_header(_('Severity'), 'priority'),
+	make_sorting_header(_('Most recent change'), 'lastchange'),
+	_('Age'),
+	make_sorting_header(_('Number of hosts'), 'hosts'),
+	make_sorting_header(_('Trigger name'), 'description')
+));
+
+// get active triggers grouped by description
+$sql =	' SELECT priority,'.
+	'        lastchange,'.
+	'        hosts,'.
+	'        description'.
+	' FROM'.
+	'    (SELECT t.priority,'.
+	'            max(t.lastchange) AS lastchange,'.
+	'            count(*) AS hosts,'.
+	'            t.description'.
+	'     FROM triggers t'.
+	'     WHERE NOT EXISTS'.
+	'       (SELECT NULL'.
+	'        FROM functions f,'.
+	'             items i,'.
+	'             hosts h'.
+	'        WHERE t.triggerid=f.triggerid'.
+	'          AND f.itemid=i.itemid'.
+	'          AND i.hostid=h.hostid'.
+	'          AND (i.status<>'.ITEM_STATUS_ACTIVE.
+	'            OR h.status<>'.DHOST_STATUS_ACTIVE.'))';
+
+// add permission filter
+if (CWebUser::getType() != USER_TYPE_SUPER_ADMIN) {
+	$userid = CWebUser::$data['userid'];
+	$userGroups = getUserGroupsByUserId($userid);
+	$sql .= ' AND EXISTS'.
+		'   (SELECT NULL'.
+		'    FROM functions f,'.
+		'         items i,'.
+		'         hosts_groups hgg'.
+		'    JOIN rights r ON r.id=hgg.groupid'.
+		'      AND '.dbConditionInt('r.groupid', $userGroups).
+		'    WHERE t.triggerid=f.triggerid'.
+		'      AND f.itemid=i.itemid'.
+		'      AND i.hostid=hgg.hostid'.
+		'    GROUP BY f.triggerid'.
+		'    HAVING MIN(r.permission)>'.PERM_DENY.')';
+}
+
+// withUnacknowledgedEvents
+if (0 == $showAck) {
+	$sql .= 'AND EXISTS ('.
+		'SELECT NULL'.
+		' FROM events e'.
+		' WHERE t.triggerid=e.objectid'.
+		' AND e.source='.EVENT_SOURCE_TRIGGERS.
+		' AND e.object='.EVENT_OBJECT_TRIGGER.
+		' AND e.value='.TRIGGER_VALUE_TRUE.
+		' AND e.acknowledged='.EVENT_NOT_ACKNOWLEDGED.
+	')';
+}
+
+
+$sql .= '   AND t.status='.TRIGGER_STATUS_ENABLED.
+	'   AND t.value='.TRIGGER_VALUE_TRUE.
+	'   AND '.dbConditionInt('t.flags', array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED)).
+	'   AND t.priority>='.$showSeverity.
+	' GROUP BY t.description,'.
+	'          t.priority'.
+	' ORDER BY '.$sortField.' '.$sortOrder.','.
+	'           lastchange DESC,'.
+	'           priority ASC,'.
+	'           hosts ASC,'.
+	'           description ASC) tbl'.
+	' WHERE hosts >= '.$minHosts;
+
+$result = DBselect($sql, $config['search_limit'] + 1);
+
+while ($row = DBfetch($result)) {
+	$lastChangeDate = zbx_date2str(_('d M Y H:i:s'), $row['lastchange']);
+	$age = empty($row['lastchange']) ? '-' : zbx_date2age($row['lastchange']);
+
+	$table->addRow(array(
+		getSeverityCell($row['priority']),
+		$lastChangeDate,
+		$age,
+		$row['hosts'],
+		new CLink($row['description'],
+			'tr_status.php?groupid=0&hostid=0&txt_select='.
+			urlencode($row['description']).'&ack_status='.
+			((1 == $showAck)
+				? ZBX_ACK_STS_ANY
+				: ZBX_ACK_STS_WITH_UNACK).
+			'&show_severity='.
+			$row['priority']
+                )
+	));
+}
+
+$paging = getPagingLine($table->items);
+
+$filterForm->addItemToBottomRow(new CSubmit('filter_set', _('Filter'), 'chkbxRange.clearSelectedOnFilterChange();'));
+$filterForm->addItemToBottomRow(new CSubmit('filter_rst', _('Reset'), 'chkbxRange.clearSelectedOnFilterChange();'));
+
+$rprt_wdgt->addFlicker($filterForm, CProfile::get('web.report99.filter.state', 1));
+$rprt_wdgt->addItem(array($paging, $table, $paging));
+$rprt_wdgt->show();
+
+require_once dirname(__FILE__).'/include/page_footer.php';
