filter = $filter; } public static function forFilter(Filter $filter) { return new static($filter); } public function renderAssign() { return 'assign where ' . $this->renderFilter($this->filter); } public function renderIgnore() { return 'ignore where ' . $this->renderFilter($this->filter); } protected function renderFilter(Filter $filter) { if ($filter->isChain()) { return $this->renderFilterChain($filter); } else { return $this->renderFilterExpression($filter); } } protected function renderFilterExpression($filter) { $column = $filter->getColumn(); $expression = $filter->getExpression(); if ($filter instanceof FilterEqual) { return sprintf( '%s == %s', $column, $expression ); } elseif ($filter instanceof FilterMatch) { if (strpos($expression, '*') === false) { return sprintf( '%s == %s', $column, $expression ); } else { return sprintf( 'match(%s, %s)', $expression, $column ); } } elseif ($filter instanceof FilterNotEqual) { return sprintf( '%s != %s', $column, $expression ); } elseif ($filter instanceof FilterEqualOrGreaterThan) { return sprintf( '%s >= %s', $column, $expression ); } elseif ($filter instanceof FilterEqualOrLessThan) { return sprintf( '%s <= %s', $column, $expression ); } elseif ($filter instanceof FilterGreaterThan) { return sprintf( '%s > %s', $column, $expression ); } elseif ($filter instanceof FilterLessThan) { return sprintf( '%s < %s', $column, $expression ); } else { throw new QueryException( 'Filter expression of type "%s" is not supported', get_class($filter) ); } } protected function renderFilterChain(Filter $filter) { // TODO: brackets if deeper level? if ($filter instanceof FilterAnd) { $op = ' && '; } elseif ($filter instanceof FilterOr) { $op = ' || '; } elseif ($filter instanceof FilterNot) { $op = ' !'; // TODO -> different } else { throw new QueryException('Cannot render filter: %s', $filter); } $parts = array(); if (! $filter->isEmpty()) { foreach ($filter->filters() as $f) { if ($f->isChain()) { if ($f instanceof FilterNot) { $parts[] = '! (' . $this->renderFilter($f) . ')'; } else { $parts[] = '(' . $this->renderFilter($f) . ')'; } } else { $parts[] = $this->renderFilter($f); } } } if ($filter instanceof FilterNot) { return implode(' && ', $parts); } else { return implode($op, $parts); } } }