|
<?php |
|
|
|
namespace Kanboard\Core\Filter; |
|
|
|
use PicoDb\Table; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LexerBuilder |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $lexer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $query; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $filters; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $queryBuilder; |
|
|
|
|
|
|
|
|
|
|
|
|
|
public function __construct() |
|
{ |
|
$this->lexer = new Lexer(); |
|
$this->queryBuilder = new QueryBuilder(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function withFilter(FilterInterface $filter, $default = false) |
|
{ |
|
$attributes = $filter->getAttributes(); |
|
|
|
foreach ($attributes as $attribute) { |
|
$this->filters[$attribute] = $filter; |
|
$this->lexer->addToken(sprintf("/^(%s:)/i", $attribute), $attribute); |
|
|
|
if ($default) { |
|
$this->lexer->setDefaultToken($attribute); |
|
} |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function withQuery(Table $query) |
|
{ |
|
$this->query = $query; |
|
$this->queryBuilder->withQuery($this->query); |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function build($input) |
|
{ |
|
$tokens = $this->lexer->tokenize($input); |
|
|
|
foreach ($tokens as $token => $values) { |
|
if (isset($this->filters[$token])) { |
|
$this->applyFilters($this->filters[$token], $values); |
|
} |
|
} |
|
|
|
return $this->queryBuilder; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function applyFilters(FilterInterface $filter, array $values) |
|
{ |
|
$len = count($values); |
|
|
|
if ($len > 1) { |
|
$criteria = new OrCriteria(); |
|
$criteria->withQuery($this->query); |
|
|
|
foreach ($values as $value) { |
|
$currentFilter = clone($filter); |
|
$criteria->withFilter($currentFilter->withValue($value)); |
|
} |
|
|
|
$this->queryBuilder->withCriteria($criteria); |
|
} elseif ($len === 1) { |
|
$this->queryBuilder->withFilter($filter->withValue($values[0])); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
public function __clone() |
|
{ |
|
$this->lexer = clone $this->lexer; |
|
$this->query = clone $this->query; |
|
$this->queryBuilder = clone $this->queryBuilder; |
|
} |
|
} |
|
|