diff --git a/library/Icinga/Data/Filter/FilterChain.php b/library/Icinga/Data/Filter/FilterChain.php
index 7e377d91f..1c5cdf956 100644
--- a/library/Icinga/Data/Filter/FilterChain.php
+++ b/library/Icinga/Data/Filter/FilterChain.php
@@ -21,6 +21,22 @@ abstract class FilterChain extends Filter
protected $allowedColumns;
+ /**
+ * Set the filters
+ *
+ * @param array $filters
+ *
+ * @return $this
+ */
+ public function setFilters(array $filters)
+ {
+ $this->filters = $filters;
+
+ $this->refreshChildIds();
+
+ return $this;
+ }
+
public function hasId($id)
{
foreach ($this->filters() as $filter) {
diff --git a/modules/monitoring/application/controllers/TacticalController.php b/modules/monitoring/application/controllers/TacticalController.php
index c60a373bb..6f9ae7fef 100644
--- a/modules/monitoring/application/controllers/TacticalController.php
+++ b/modules/monitoring/application/controllers/TacticalController.php
@@ -55,11 +55,8 @@ class TacticalController extends Controller
$this->setupFilterControl($stats, null, ['host', 'service'], ['format']);
$this->view->setHelperFunction('filteredUrl', function ($path, array $params) {
$filter = clone $this->view->filterEditor->getFilter();
- foreach ($params as $column => $value) {
- $filter = $filter->andFilter($filter->where($column, $value));
- }
- return $this->view->url($path)->setQueryString($filter->toQueryString());
+ return $this->view->url($path)->setParams($params)->addFilter($filter);
});
$this->handleFormatRequest($stats);
diff --git a/modules/monitoring/application/views/scripts/list/hostgroups.phtml b/modules/monitoring/application/views/scripts/list/hostgroups.phtml
index a2b8a1efb..aab39f800 100644
--- a/modules/monitoring/application/views/scripts/list/hostgroups.phtml
+++ b/modules/monitoring/application/views/scripts/list/hostgroups.phtml
@@ -1,4 +1,5 @@
compact): ?>
@@ -42,12 +43,15 @@ if (! $this->compact): ?>
= $this->qlink(
$hostGroup->hostgroup_alias,
- $this->url('monitoring/list/hosts')->addFilter($this->filterEditor->getFilter()),
- array('hostgroup_name' => $hostGroup->hostgroup_name, 'sort' => 'host_severity'),
- array('title' => sprintf(
+ $this
+ ->url('monitoring/list/hosts')
+ ->setParams(['hostgroup_name' => $hostGroup->hostgroup_name])
+ ->addFilter($this->filterEditor->getFilter()),
+ ['sort' => 'host_severity'],
+ ['title' => sprintf(
$this->translate('List all hosts in the group "%s"'),
$hostGroup->hostgroup_alias
- ))
+ )]
) ?>
|
@@ -140,12 +144,18 @@ if (! $this->compact): ?>
|
= $this->qlink(
$hostGroup->services_total,
- $this->url('monitoring/list/services')->addFilter($this->filterEditor->getFilter()),
- array('hostgroup_name' => $hostGroup->hostgroup_name, 'sort' => 'service_severity'),
- array('title' => sprintf(
- $this->translate('List all services of all hosts in host group "%s"'),
- $hostGroup->hostgroup_alias
- ), 'class' => 'badge')
+ $this
+ ->url('monitoring/list/services')
+ ->setParams(['hostgroup_name' => $hostGroup->hostgroup_name])
+ ->addFilter($this->filterEditor->getFilter()),
+ ['sort' => 'service_severity'],
+ [
+ 'title' => sprintf(
+ $this->translate('List all services of all hosts in host group "%s"'),
+ $hostGroup->hostgroup_alias
+ ),
+ 'class' => 'badge'
+ ]
) ?>
|
diff --git a/modules/monitoring/application/views/scripts/list/servicegroups.phtml b/modules/monitoring/application/views/scripts/list/servicegroups.phtml
index 1e4103f6a..431fc8e56 100644
--- a/modules/monitoring/application/views/scripts/list/servicegroups.phtml
+++ b/modules/monitoring/application/views/scripts/list/servicegroups.phtml
@@ -38,9 +38,12 @@ if (! $this->compact): ?>
|
= $this->qlink(
$serviceGroup->servicegroup_alias,
- $this->url('monitoring/list/services')->addFilter($this->filterEditor->getFilter()),
- array('servicegroup_name' => $serviceGroup->servicegroup_name, 'sort' => 'service_severity'),
- array('title' => sprintf($this->translate('List all services in the group "%s"'), $serviceGroup->servicegroup_alias))
+ $this
+ ->url('monitoring/list/services')
+ ->setParams(['servicegroup_name' => $serviceGroup->servicegroup_name])
+ ->addFilter($this->filterEditor->getFilter()),
+ ['sort' => 'service_severity'],
+ ['title' => sprintf($this->translate('List all services in the group "%s"'), $serviceGroup->servicegroup_alias)]
) ?>
|
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php
index df1de61d1..7a39f48d1 100644
--- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php
@@ -3,6 +3,7 @@
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
+use Icinga\Data\Filter\FilterNot;
use Zend_Db_Expr;
use Icinga\Application\Icinga;
use Icinga\Application\Hook;
@@ -559,7 +560,7 @@ abstract class IdoQuery extends DbQuery
if (count($expr) === 1 && strpos($expr[0], '&') !== false) {
// Our current filter implementation does not specify & as a control character so the count of the
// expression array is always one in this case
- $expr = explode('&', $expr[0]);
+ $expr = array_unique(explode('&', $expr[0]));
$subQueryFilter->setExpression($expr);
$and = true;
} else {
@@ -691,6 +692,60 @@ abstract class IdoQuery extends DbQuery
$filter->setColumn($column);
} else {
+ if (! $filter instanceof FilterNot) {
+ // Allow subquery filters in a filter chain
+ $columns = $filter->listFilteredColumns();
+ if (count($columns) === 1) {
+ $column = $columns[0];
+ $virtualTable = $this->aliasToTableName($column);
+ if (isset($this->subQueryTargets[$virtualTable])) {
+ $lastSign = null;
+ $filters = [];
+ $expressions = [];
+ foreach ($filter->filters() as $child) {
+ switch (true) {
+ case $child instanceof FilterExpression:
+ $expression = $child->getExpression();
+ if (! is_array($expression)) {
+ break;
+ }
+ // Move to default
+ default:
+ $filters[] = $child;
+ continue 2;
+ }
+ if ($lastSign === null) {
+ $lastSign = $child->getSign();
+ } else {
+ $sign = $child->getSign();
+ if ($sign !== $lastSign) {
+ $filters[] = new FilterExpression(
+ $column,
+ $lastSign,
+ $filter->getOperatorSymbol() === '&'
+ ? [implode('&', $expressions)]
+ : $expressions
+ );
+ $expressions = [];
+ $lastSign = $sign;
+ }
+ }
+ $expressions[] = $expression;
+ }
+ if (! empty($expressions)) {
+ $filters[] = new FilterExpression(
+ $column,
+ $lastSign,
+ $filter->getOperatorSymbol() === '&'
+ ? [implode('&', $expressions)]
+ : $expressions
+ );
+ }
+ $filter->setFilters($filters);
+ }
+ }
+ }
+
foreach ($filter->filters() as $child) {
$replacement = $this->requireFilterColumns($child);
if ($replacement !== null) {
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicegroupQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicegroupQuery.php
index bdf08fb38..d43c7d7a3 100644
--- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicegroupQuery.php
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicegroupQuery.php
@@ -298,6 +298,8 @@ class ServicegroupQuery extends IdoQuery
$additionalFilter = clone $filter;
}
+ $this->requireVirtualTable('members');
+
$query->joinVirtualTable('members');
return ['sgm.service_object_id', 'so.object_id'];
|