This repository has been archived on 2025-02-26. You can view files and clone it, but cannot push or open issues or pull requests.
szurubooru/src/SearchServices/Parsers/AbstractSearchParser.php

96 lines
2.5 KiB
PHP
Raw Normal View History

2014-09-23 20:45:59 +02:00
<?php
namespace Szurubooru\SearchServices\Parsers;
abstract class AbstractSearchParser
{
2014-09-26 19:14:34 +02:00
public function createFilterFromInputReader(\Szurubooru\Helpers\InputReader $inputReader)
2014-09-23 20:45:59 +02:00
{
$filter = $this->createFilter();
2014-09-26 19:14:34 +02:00
$filter->setOrder(array_merge($this->getOrder($inputReader->order), $filter->getOrder()));
2014-09-23 20:45:59 +02:00
2014-09-26 19:14:34 +02:00
if ($inputReader->page)
{
$filter->setPageNumber($inputReader->page);
$filter->setPageSize(25);
}
$tokens = $this->tokenize($inputReader->query);
2014-09-23 20:45:59 +02:00
foreach ($tokens as $token)
{
if ($token instanceof \Szurubooru\SearchServices\NamedSearchToken)
$this->decorateFilterFromNamedToken($filter, $token);
2014-09-26 19:14:34 +02:00
elseif ($token instanceof \Szurubooru\SearchServices\SearchToken)
2014-09-23 20:45:59 +02:00
$this->decorateFilterFromToken($filter, $token);
else
2014-09-26 19:14:34 +02:00
throw new \RuntimeException('Invalid search token type: ' . get_class($token));
2014-09-23 20:45:59 +02:00
}
return $filter;
}
protected abstract function createFilter();
protected abstract function decorateFilterFromToken($filter, $token);
protected abstract function decorateFilterFromNamedToken($filter, $namedToken);
protected abstract function getOrderColumn($token);
private function getOrder($query)
{
$order = [];
2014-09-26 19:14:34 +02:00
$tokens = array_filter(preg_split('/\s+/', trim($query)));
2014-09-23 20:45:59 +02:00
foreach ($tokens as $token)
{
$token = preg_split('/,|\s+/', $token);
$orderToken = $token[0];
$orderDir = (count($token) === 2 and $token[1] === 'desc')
2014-09-26 19:14:34 +02:00
? \Szurubooru\SearchServices\Filters\IFilter::ORDER_DESC
: \Szurubooru\SearchServices\Filters\IFilter::ORDER_ASC;
2014-09-23 20:45:59 +02:00
$orderColumn = $this->getOrderColumn($orderToken);
if ($orderColumn === null)
throw new \InvalidArgumentException('Invalid search order token: ' . $orderToken);
$order[$orderColumn] = $orderDir;
}
return $order;
}
private function tokenize($query)
{
$searchTokens = [];
2014-09-26 19:14:34 +02:00
foreach (array_filter(preg_split('/\s+/', trim($query))) as $tokenText)
2014-09-23 20:45:59 +02:00
{
$negated = false;
if (substr($tokenText, 0, 1) === '-')
{
$negated = true;
$tokenText = substr($tokenText, 1);
}
if (strpos($tokenText, ':') !== false)
{
$searchToken = new \Szurubooru\SearchServices\NamedSearchToken();
2014-09-24 20:13:16 +02:00
list ($tokenKey, $tokenValue) = explode(':', $tokenText, 1);
$searchToken->setKey($tokenKey);
$searchToken->setValue($tokenValue);
2014-09-23 20:45:59 +02:00
}
else
{
$searchToken = new \Szurubooru\SearchServices\SearchToken();
2014-09-24 20:13:16 +02:00
$searchToken->setValue($tokenText);
2014-09-23 20:45:59 +02:00
}
2014-09-24 20:13:16 +02:00
$searchToken->setNegated($negated);
2014-09-23 20:45:59 +02:00
$searchTokens[] = $searchToken;
}
return $searchTokens;
}
}