diff --git a/controllers/BaseApiController.php b/controllers/BaseApiController.php index f6755d24..37171a1e 100644 --- a/controllers/BaseApiController.php +++ b/controllers/BaseApiController.php @@ -2,10 +2,16 @@ namespace Grocy\Controllers; +use LessQL\Result; + class BaseApiController extends BaseController { protected $OpenApiSpec = null; + const PATTERN_FIELD = '[A-Za-z_][A-Za-z0-9_]+'; + const PATTERN_OPERATOR = '!?(=|~|<|>|(>=)|(<=))'; + const PATTERN_VALUE = '[A-Za-z_0-9.]+'; + public function __construct(\DI\Container $container) { parent::__construct($container); @@ -29,6 +35,68 @@ class BaseApiController extends BaseController ]); } + public function FilteredApiResponse(\Psr\Http\Message\ResponseInterface $response, Result $data, array $query) + { + $data = $this->queryData($data, $query); + return $this->ApiResponse($response, $data); + } + + protected function queryData(Result $data, array $query) + { + if (isset($query['query'])) + $data = $this->filter($data, $query['query']); + if (isset($query['limit'])) + $data = $data->limit(intval($query['limit']), intval($query['offset'] ?? 0)); + if (isset($query['order'])) + $data = $data->orderBy($query['order']); + return $data; + } + + protected function filter(Result $data, array $query): Result + { + foreach ($query as $q) { + $matches = array(); + preg_match('/(?P' . self::PATTERN_FIELD . ')' + . '(?P' . self::PATTERN_OPERATOR . ')' + . '(?P' . self::PATTERN_VALUE . ')/', + $q, $matches + ); + error_log(var_export($matches, true)); + switch ($matches['op']) { + case '=': + $data = $data->where($matches['field'], $matches['value']); + break; + case '!=': + $data = $data->whereNot($matches['field'], $matches['value']); + break; + case '~': + $data = $data->where($matches['field'] . ' LIKE ?', '%' . $matches['value'] . '%'); + break; + case '!~': + $data = $data->where($matches['field'] . ' NOT LIKE ?', '%' . $matches['value'] . '%'); + break; + case '!>=': + case '<': + $data = $data->where($matches['field'] . ' < ?', $matches['value']); + break; + case '!<=': + case '>': + $data = $data->where($matches['field'] . ' > ?', $matches['value']); + break; + case '!<': + case '>=': + $data = $data->where($matches['field'] . ' >= ?', $matches['value']); + break; + case '!>': + case '<=': + $data = $data->where($matches['field'] . ' <= ?', $matches['value']); + break; + + } + } + return $data; + } + protected function getOpenApispec() { if ($this->OpenApiSpec == null)