mirror of
https://github.com/grocy/grocy.git
synced 2025-08-13 17:27:23 +00:00
Filtering of API-Results (#985)
* Add FilteredApiResponse * Use FilteredApiResponse for Generic-Entity-Search * Use FilteredApiResponse for Recipe-Fullfillment * Use FilteredApiResponse for GetUsers * Use FilteredApiResponse for current Tasks * Use FilteredApiResponse for ProductStockEntries & ProductStockLocations * Use FilteredApiResponse for current chores * Use FilteredApiResponse for batteries-current * Fix missing highlighting of "< X days" * Keep to use existing views Co-authored-by: Bernd Bestel <bernd@berrnd.de>
This commit is contained in:
committed by
GitHub
parent
60f3d900e8
commit
32a4f81f62
@@ -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<field>' . self::PATTERN_FIELD . ')'
|
||||
. '(?P<op>' . self::PATTERN_OPERATOR . ')'
|
||||
. '(?P<value>' . 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)
|
||||
|
Reference in New Issue
Block a user