FilterQueryString: Automatically detect nested chains

i.e. `host=foo&service=bar|servicegroup=foobar` is
now interpreted as `(host=foo&service=bar)|servicegroup=foobar`
and `servicegroup=foobar|host=foo&service=bar` as
`servicegroup=foobar|(host=foo&service=bar)`
This commit is contained in:
Johannes Meyer 2020-07-02 13:40:18 +02:00
parent adae4bfd06
commit 94218a3263

View File

@ -141,9 +141,9 @@ class FilterQueryString
); );
} }
protected function readFilters($nestingLevel = 0, $op = null) protected function readFilters($nestingLevel = 0, $op = null, $filters = null)
{ {
$filters = array(); $filters = empty($filters) ? [] : $filters;
while ($this->pos < $this->length) { while ($this->pos < $this->length) {
if ($op === '!' && count($filters) === 1) { if ($op === '!' && count($filters) === 1) {
break; break;
@ -190,6 +190,17 @@ class FilterQueryString
if ($next === $op) { if ($next === $op) {
continue; continue;
} }
if (in_array($next, ['&', '|'])) {
if ($op === '&') {
$this->debug('Setting op to ' . $next, $nestingLevel, $op);
$filters = [Filter::matchAll($filters)];
$op = $next;
} else if ($op === '|') {
$filters[] = $this->readFilters($nestingLevel + 1, $next, [array_pop($filters)]);
}
continue;
}
$this->parseError($next, "$op level $nestingLevel"); $this->parseError($next, "$op level $nestingLevel");
} else { } else {
$this->debug('Got new expression: ' . $filter, $nestingLevel, $op); $this->debug('Got new expression: ' . $filter, $nestingLevel, $op);
@ -218,9 +229,18 @@ class FilterQueryString
} }
$this->parseError($next); $this->parseError($next);
} }
if ($op === null && in_array($next, array('&', '|'))) { if (in_array($next, ['&', '|'])) {
$this->debug('Setting op to ' . $next, $nestingLevel, $op); if ($op === null || $op === '&') {
$op = $next; if ($op === '&') {
$filters = [Filter::matchAll($filters)];
}
$this->debug('Setting op to ' . $next, $nestingLevel, $op);
$op = $next;
} else if ($op === '|') {
$filters[] = $this->readFilters($nestingLevel + 1, $next, [array_pop($filters)]);
}
continue; continue;
} }
$this->parseError($next); $this->parseError($next);