protected function filterChainToArray(Filter $filter) { if ($filter instanceof FilterAnd) { $op = 'and'; } elseif ($filter instanceof FilterOr) { $op = 'or'; } elseif ($filter instanceof FilterNot) { $op = 'not'; } else { throw new QueryException('Cannot render filter: %s', $filter); } $parts = array($op); if (!$filter->isEmpty()) { foreach ($filter->filters() as $f) { $parts[] = $this->filterToArray($f); } } return $parts; }
protected function validateFilterColumns(Filter $filter) { if ($filter->isExpression()) { $valid = false; foreach ($this->allowedColumns as $column) { if (is_callable($column)) { if (call_user_func($column, $filter->getColumn())) { $valid = true; break; } } elseif ($filter->getColumn() === $column) { $valid = true; break; } } if (!$valid) { throw new QueryException('Invalid filter column provided: %s', $filter->getColumn()); } } else { foreach ($filter->filters() as $subFilter) { $this->validateFilterColumns($subFilter); } } }
protected function resetSearchColumns(Filter &$filter) { if ($filter->isChain()) { $filters =& $filter->filters(); if (!($empty = empty($filters))) { foreach ($filters as $k => &$f) { if (false === $this->resetSearchColumns($f)) { unset($filters[$k]); } } } return $empty || !empty($filters); } return $filter->isExpression() ? !(in_array($filter->getColumn(), $this->searchColumns) && $filter->getSign() === '=') : true; }
protected function requireFilterColumns(Filter $filter) { if ($filter instanceof FilterExpression) { if ($filter->getExpression() === '*') { return; // Wildcard only filters are ignored so stop early here to avoid joining a table for nothing } $alias = $filter->getColumn(); $this->requireColumn($alias); if ($this->isCustomvar($alias)) { $column = $this->getCustomvarColumnName($alias); } else { $column = $this->aliasToColumnName($alias); } if (isset($this->columnsWithoutCollation[$alias])) { $expression = $filter->getExpression(); if (is_array($expression)) { $filter->setExpression(array_map('strtolower', $expression)); } else { $filter->setExpression(strtolower($expression)); } } $filter->setColumn($column); } else { foreach ($filter->filters() as $filter) { $this->requireFilterColumns($filter); } } }
/** * Recurse the given filter and ensure that any string conversion is case-insensitive * * @param Filter $filter */ protected function lowerColumnsWithoutCollation(Filter $filter) { if ($filter instanceof FilterExpression) { if (in_array($filter->getColumn(), $this->columnsWithoutCollation) && strpos($filter->getColumn(), 'LOWER') !== 0) { $filter->setColumn('LOWER(' . $filter->getColumn() . ')'); $expression = $filter->getExpression(); if (is_array($expression)) { $filter->setExpression(array_map('strtolower', $expression)); } else { $filter->setExpression(strtolower($expression)); } } } else { foreach ($filter->filters() as $chainedFilter) { $this->lowerColumnsWithoutCollation($chainedFilter); } } }
/** * Filter rendering * * Happens recursively, useful for filters and for Stats expressions * * @param Filter $filter The filter that should be rendered * @param string $type Filter type. Usually "Filter" or "Stats" * @param int $level Nesting level during recursion. Don't touch * @param bool $keylookup Whether to resolve alias names * * @return string */ protected function renderFilter(Filter $filter, $type = 'Filter', $level = 0, $keylookup = true) { $str = ''; if ($filter instanceof FilterChain) { if ($filter instanceof FilterAnd) { $op = 'And'; } elseif ($filter instanceof FilterOr) { $op = 'Or'; } elseif ($filter instanceof FilterNot) { $op = 'Negate'; } else { throw new IcingaException('Cannot render filter: %s', $filter); } $parts = array(); if (!$filter->isEmpty()) { foreach ($filter->filters() as $f) { $parts[] = $this->renderFilter($f, $type, $level + 1, $keylookup); } $str .= implode("\n", $parts); if ($type === 'Filter') { if (count($parts) > 1) { $str .= "\n" . $op . ': ' . count($parts); } } else { $str .= "\n" . $type . $op . ': ' . count($parts); } } } else { $str .= $type . ': ' . $this->renderFilterExpression($filter, $keylookup); } return $str; }
public function addFilter(Filter $filter) { // TODO: This should be considered a quick fix only. // Drop this entirely once support for Icinga\Data\Filter is available if ($filter->isExpression()) { $this->where($filter->getColumn(), $filter->getExpression()); } elseif ($filter->isChain()) { foreach ($filter->filters() as $chainOrExpression) { $this->addFilter($chainOrExpression); } } }