- Heavy rework on search request handling of entities
This commit is contained in:
parent
a9b9c2cce9
commit
11e436236c
@ -196,9 +196,9 @@ class SQLite implements AdapterInterface, MigrateInterface, SqlAdapterInterface
|
|||||||
$pdo->sqliteCreateFunction('day', fn($date) => ( new \DateTime($date) )->format('j'), 1);
|
$pdo->sqliteCreateFunction('day', fn($date) => ( new \DateTime($date) )->format('j'), 1);
|
||||||
$pdo->sqliteCreateFunction('month', fn($date) => ( new \DateTime($date) )->format('n'), 1);
|
$pdo->sqliteCreateFunction('month', fn($date) => ( new \DateTime($date) )->format('n'), 1);
|
||||||
$pdo->sqliteCreateFunction('year', fn($date) => ( new \DateTime($date) )->format('Y'), 1);
|
$pdo->sqliteCreateFunction('year', fn($date) => ( new \DateTime($date) )->format('Y'), 1);
|
||||||
|
$pdo->sqliteCreateFunction('str_to_date', fn($value, $format) => ($f = \DateTime::createFromFormat($format, $value)) ? $f->format('Y-m-d H:i:s') : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function exportCollations(PdoObject $pdo) : void
|
public function exportCollations(PdoObject $pdo) : void
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,13 @@ class Datetime extends \DateTime implements EntityObjectInterface {
|
|||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setTime($hour, $minute, $second = 0, $microsecond = 0) : \DateTimeInterface
|
||||||
|
{
|
||||||
|
$fromParent = parent::setTime($hour, $minute, $second, $microsecond);
|
||||||
|
|
||||||
|
return new static($fromParent);
|
||||||
|
}
|
||||||
|
|
||||||
public function save()
|
public function save()
|
||||||
{
|
{
|
||||||
return $this->__toString();
|
return $this->__toString();
|
||||||
@ -45,7 +52,7 @@ class Datetime extends \DateTime implements EntityObjectInterface {
|
|||||||
|
|
||||||
public function formatLocaleIntl(int $dateFormatter = \IntlDateFormatter::LONG, int $timeFormatter = \IntlDateFormatter::NONE) : string
|
public function formatLocaleIntl(int $dateFormatter = \IntlDateFormatter::LONG, int $timeFormatter = \IntlDateFormatter::NONE) : string
|
||||||
{
|
{
|
||||||
$formatter = new \IntlDateFormatter(\Locale::getDefault(), $dateFormatter, $timeFormatter, \Locale::getRegion());
|
$formatter = new \IntlDateFormatter(\Locale::getDefault(), $dateFormatter, $timeFormatter);
|
||||||
|
|
||||||
return $formatter->format($this->getTimestamp());
|
return $formatter->format($this->getTimestamp());
|
||||||
}
|
}
|
||||||
@ -54,4 +61,5 @@ class Datetime extends \DateTime implements EntityObjectInterface {
|
|||||||
{
|
{
|
||||||
return (int) ( (int) ($dateTime ?: new DateTime())->format('Ymd') - (int) $this->format('Ymd') ) / 10000;
|
return (int) ( (int) ($dateTime ?: new DateTime())->format('Ymd') - (int) $this->format('Ymd') ) / 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -681,20 +681,12 @@ class Repository implements RepositoryInterface
|
|||||||
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
|
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
|
||||||
{
|
{
|
||||||
if ($count) {
|
if ($count) {
|
||||||
$searchRequest->count = $searchRequest->filter($this->serverRequestCountRepository())
|
$searchRequest->applyCount($this->serverRequestCountRepository());
|
||||||
->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
|
|
||||||
->likes($searchRequest->likes(), Query\Where::CONDITION_OR)
|
|
||||||
->groups($searchRequest->groups())
|
|
||||||
->count();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $searchRequest->filter($this)
|
$searchRequest->apply($this);
|
||||||
->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
|
|
||||||
->likes($searchRequest->likes(), Query\Where::CONDITION_OR)
|
return $this;
|
||||||
->orders($searchRequest->orders())
|
|
||||||
->groups($searchRequest->groups())
|
|
||||||
->offset($searchRequest->offset())
|
|
||||||
->limit($searchRequest->limit());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function serverRequestCountRepository() : Repository
|
protected function serverRequestCountRepository() : Repository
|
||||||
|
|||||||
@ -32,10 +32,10 @@ trait ConditionTrait
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function wheres(array $fieldValues, string $operator = Query\Where::OPERATOR_EQUAL) : self
|
public function wheres(array $fieldValues, string|array $operator = Query\Where::OPERATOR_EQUAL, string|array $condition = Query\Where::CONDITION_AND) : self
|
||||||
{
|
{
|
||||||
foreach($fieldValues as $field => $value) {
|
foreach($fieldValues as $field => $value) {
|
||||||
$this->where($field, $value, $operator);
|
$this->where($field, $value, is_array($operator) ? ( $operator[$field] ?? Query\Where::OPERATOR_EQUAL ) : $operator, is_array($condition) ? ( $condition[$field] ?? Query\Where::CONDITION_AND ) : $condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -142,7 +142,7 @@ trait ConditionTrait
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function likes(array $fieldValues, string $condition = Query\Where::CONDITION_AND) : self
|
public function likes(array $fieldValues, string|array $condition = Query\Where::CONDITION_AND) : self
|
||||||
{
|
{
|
||||||
foreach($fieldValues as $field => $value) {
|
foreach($fieldValues as $field => $value) {
|
||||||
$this->like($field, $value);
|
$this->like($field, $value);
|
||||||
|
|||||||
@ -9,4 +9,6 @@ enum SearchMethodEnum
|
|||||||
case Like;
|
case Like;
|
||||||
case LikeLeft;
|
case LikeLeft;
|
||||||
case LikeRight;
|
case LikeRight;
|
||||||
|
case OrderBy;
|
||||||
|
case GroupBy;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,9 +9,108 @@ class SearchRequest implements SearchRequestInterface
|
|||||||
{
|
{
|
||||||
use SearchRequestPaginationTrait, SearchRequestFromRequestTrait;
|
use SearchRequestPaginationTrait, SearchRequestFromRequestTrait;
|
||||||
|
|
||||||
|
protected array $wheres = [];
|
||||||
|
|
||||||
|
protected array $wheresConditions = [];
|
||||||
|
|
||||||
|
protected array $wheresOperators = [];
|
||||||
|
|
||||||
|
protected array $likes = [];
|
||||||
|
|
||||||
|
protected array $likesOperators = [];
|
||||||
|
|
||||||
|
protected array $likesConditions = [];
|
||||||
|
|
||||||
|
protected array $groups = [];
|
||||||
|
|
||||||
|
protected array $orders = [];
|
||||||
|
|
||||||
|
/* [[ Boilerplates which are ready to be copied */
|
||||||
|
public function wheres() : iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->wheres + [
|
||||||
|
|
||||||
|
], fn($i) => ! is_null($i) ) + [ ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function wheresConditions() : iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->wheresConditions + [
|
||||||
|
|
||||||
|
], fn($i) => ! is_null($i) ) + [ ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function wheresOperators() : iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->wheresOperators + [
|
||||||
|
|
||||||
|
], fn($i) => ! is_null($i) ) + [ ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function likes(): iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->likes + [
|
||||||
|
|
||||||
|
], fn($i) => ! is_null($i) ) + [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function likesConditions() : iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->likesConditions + [
|
||||||
|
|
||||||
|
], fn($i) => ! is_null($i) ) + [ ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function likesOperators() : iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->likesOperators + [
|
||||||
|
|
||||||
|
], fn($i) => ! is_null($i) ) + [ ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function groups(): iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->groups + [
|
||||||
|
|
||||||
|
], fn($e) => ! is_null($e) && $e !== "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function orders(): iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->orders + [
|
||||||
|
|
||||||
|
], fn($e) => ! is_null($e) && $e !== "" );
|
||||||
|
}
|
||||||
|
/* ]] */
|
||||||
|
|
||||||
public function filter(Repository $repository) : Repository
|
public function filter(Repository $repository) : Repository
|
||||||
{
|
{
|
||||||
return $repository;
|
return $repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function applyCount(Repository\RepositoryInterface $repository): SearchRequestInterface
|
||||||
|
{
|
||||||
|
$this->count = $this->fromParsedParameters($repository)
|
||||||
|
->filter($repository)
|
||||||
|
->wheres($this->wheres(), $this->wheresOperators(), $this->wheresConditions())
|
||||||
|
->likes($this->likes(), $this->likesConditions())
|
||||||
|
->groups($this->groups())
|
||||||
|
->count();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function apply(Repository\RepositoryInterface $repository): SearchRequestInterface
|
||||||
|
{
|
||||||
|
$this->fromParsedParameters($repository)
|
||||||
|
->filter($repository)
|
||||||
|
->wheres($this->wheres(), $this->wheresOperators(), $this->wheresConditions())
|
||||||
|
->likes($this->likes(), $this->likesConditions())
|
||||||
|
->orders($this->orders())
|
||||||
|
->groups($this->groups())
|
||||||
|
->offset($this->offset())
|
||||||
|
->limit($this->limit());
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Ulmus\SearchRequest;
|
namespace Ulmus\SearchRequest;
|
||||||
|
|
||||||
|
use Notes\Common\ReflectedClass;
|
||||||
use Notes\ObjectReflection;
|
use Notes\ObjectReflection;
|
||||||
use Psr\Http\Message\RequestInterface;
|
use Psr\Http\Message\RequestInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
@ -14,103 +15,65 @@ use Ulmus\SearchRequest\Attribute\{PropertyValueSource,
|
|||||||
SearchOrderBy,
|
SearchOrderBy,
|
||||||
SearchGroupBy,
|
SearchGroupBy,
|
||||||
SearchRequestParameter};
|
SearchRequestParameter};
|
||||||
|
use Ulmus\Repository;
|
||||||
|
|
||||||
trait SearchRequestFromRequestTrait
|
trait SearchRequestFromRequestTrait
|
||||||
{
|
{
|
||||||
protected array $wheres = [];
|
protected ReflectedClass $objectReflection;
|
||||||
|
|
||||||
protected array $likes = [];
|
protected array $parsedParameters = [];
|
||||||
|
|
||||||
protected array $groups = [];
|
public function fromParsedParameters(Repository $repository) : SearchRequestInterface
|
||||||
|
|
||||||
protected array $orders = [];
|
|
||||||
|
|
||||||
public function fromArray(array|\ArrayAccess $data) : static
|
|
||||||
{
|
{
|
||||||
$this->page = $data['page'] ?? 1;
|
foreach($this->parsedParameters as $property => $param) {
|
||||||
|
switch($param->searchMethod) {
|
||||||
|
case SearchMethodEnum::Like:
|
||||||
|
case SearchMethodEnum::LikeLeft:
|
||||||
|
case SearchMethodEnum::LikeRight:
|
||||||
|
$repository->like($param->field, $param->value());
|
||||||
|
break;
|
||||||
|
|
||||||
$classReflection = ObjectReflection::fromClass(static::class)->reflectClass();
|
case SearchMethodEnum::Where:
|
||||||
|
$repository->where($param->field, $param->value(), $param->operator(), $param->condition());
|
||||||
|
break;
|
||||||
|
|
||||||
foreach($classReflection->getProperties() as $propertyName => $property) {
|
case SearchMethodEnum::OrderBy:
|
||||||
$attributeList = $property->getAttributes(Attribute\SearchParameter::class);
|
$repository->orderBy($param->field, $param->value());
|
||||||
|
break;
|
||||||
|
|
||||||
if ($attributeList) {
|
case SearchMethodEnum::GroupBy:
|
||||||
$attribute = $attributeList[0]->object;
|
$repository->groupBy($param->field);
|
||||||
|
break;
|
||||||
$fieldName = $attribute->field ?? $propertyName;
|
|
||||||
|
|
||||||
# Field could be defined for another entity class
|
|
||||||
if (is_array($fieldName)) {
|
|
||||||
$field = \Ulmus\Attribute\Attribute::handleArrayField($fieldName, false);
|
|
||||||
}
|
|
||||||
# Default class using it, if SearchRequestParameter is defined
|
|
||||||
elseif ($classAttributes = $classReflection->getAttributes(SearchRequestParameter::class)) {
|
|
||||||
$searchRequestAttribute = $classAttributes[0]->object;
|
|
||||||
$className = $searchRequestAttribute->class;
|
|
||||||
$field = $className::field($fieldName, $searchRequestAttribute->alias);
|
|
||||||
}
|
|
||||||
# Untouched string from the attribute
|
|
||||||
else {
|
|
||||||
$field = $fieldName;
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = $data[$propertyName] ?? null;
|
|
||||||
|
|
||||||
if ($value !== null) {
|
|
||||||
$value = $this->transformValue($property->getAttributes(Attribute\PropertyValueModifier::class), $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(true) {
|
|
||||||
case $attribute instanceof SearchGroupBy:
|
|
||||||
$this->parseAttributeGroupBy($attribute, $field, $propertyName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case $attribute instanceof SearchWhere:
|
|
||||||
case $attribute instanceof SearchLike:
|
|
||||||
case $attribute instanceof SearchManual:
|
|
||||||
if ($attribute->toggle) {
|
|
||||||
$this->$propertyName = ! empty($value);
|
|
||||||
}
|
|
||||||
elseif ($value !== null) {
|
|
||||||
foreach ($property->getTypes() as $type) {
|
|
||||||
$enum = $type->type;
|
|
||||||
|
|
||||||
if (enum_exists($enum)) {
|
|
||||||
try {
|
|
||||||
$this->$propertyName = $value instanceof \UnitEnum ? $value : $type->type::from($value);
|
|
||||||
} catch (\ValueError $ex) {
|
|
||||||
$cases = implode(', ', array_map(fn($e) => $e->name, $enum::cases()));
|
|
||||||
|
|
||||||
throw new \ValueError(
|
|
||||||
sprintf("Given value '%s' do not exists within enum '%s'. Try one of those values instead : %s", $value, $enum, $cases)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif ($type->builtIn || $value instanceof \Stringable ) {
|
|
||||||
$this->$propertyName = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->parseAttributeMethod($attribute, $field, $propertyName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case $attribute instanceof SearchOrderBy:
|
|
||||||
if ($value !== null) {
|
|
||||||
$this->$propertyName = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->parseAttributeOrderBy($attribute, $field, $propertyName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fromArray(array|\ArrayAccess $data) : static
|
||||||
|
{
|
||||||
|
$this->objectReflection = ObjectReflection::fromClass(static::class)->reflectClass();
|
||||||
|
|
||||||
|
$this->page = $data['page'] ?? 1;
|
||||||
|
|
||||||
|
$this->applyValues(
|
||||||
|
fn($propertyName, $attribute) => $data[$propertyName] ?? null
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->applyOperators(
|
||||||
|
fn($propertyName) => $data["$propertyName:operator"] ?? null
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->applyConditions(
|
||||||
|
fn($propertyName) => $data["$propertyName:condition"] ?? null
|
||||||
|
);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function fromRequest(ServerRequestInterface $request) : static
|
public function fromRequest(ServerRequestInterface $request) : static
|
||||||
{
|
{
|
||||||
|
$this->objectReflection = ObjectReflection::fromClass(static::class)->reflectClass();
|
||||||
|
|
||||||
if (method_exists($this, 'prepare')) {
|
if (method_exists($this, 'prepare')) {
|
||||||
$this->prepare($request);
|
$this->prepare($request);
|
||||||
}
|
}
|
||||||
@ -119,32 +82,81 @@ trait SearchRequestFromRequestTrait
|
|||||||
|
|
||||||
$this->page = $queryParams->offsetExists('page') ? $queryParams['page'] : 1;
|
$this->page = $queryParams->offsetExists('page') ? $queryParams['page'] : 1;
|
||||||
|
|
||||||
$classReflection = ObjectReflection::fromClass(static::class)->reflectClass();
|
$this->applyValues(
|
||||||
|
fn($propertyName, $attribute) => $this->getValueFromSource($request, $propertyName, $attribute)
|
||||||
|
);
|
||||||
|
|
||||||
foreach($classReflection->getProperties() as $propertyName => $property) {
|
$operators = $request->getAttribute(SearchRequestInterface::SEARCH_REQUEST_OPERATORS);
|
||||||
$attributeList = $property->getAttributes(Attribute\SearchParameter::class);
|
|
||||||
|
|
||||||
if ($attributeList) {
|
if ($operators) {
|
||||||
$attribute = $attributeList[0]->object;
|
$this->applyOperators(
|
||||||
|
fn($propertyName) => $operators[$propertyName] ?? null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$fieldName = $attribute->field ?? $propertyName;
|
$conditions = $request->getAttribute(SearchRequestInterface::SEARCH_REQUEST_CONDITIONS);
|
||||||
|
|
||||||
# Field could be defined for another entity class
|
if ($conditions) {
|
||||||
if (is_array($fieldName)) {
|
$this->applyConditions(
|
||||||
$field = \Ulmus\Attribute\Attribute::handleArrayField($fieldName, false);
|
fn($propertyName) => $conditions[$propertyName] ?? null
|
||||||
}
|
);
|
||||||
# Default class using it, if SearchRequestParameter is defined
|
}
|
||||||
elseif ($classAttributes = $classReflection->getAttributes(SearchRequestParameter::class)) {
|
|
||||||
$searchRequestAttribute = $classAttributes[0]->object;
|
return $this;
|
||||||
$className = $searchRequestAttribute->class;
|
}
|
||||||
$field = $className::field($fieldName, $searchRequestAttribute->alias);
|
|
||||||
}
|
protected function applyConditions(\Closure $getCondition) : void
|
||||||
# Untouched string from the attribute
|
{
|
||||||
else {
|
foreach($this->objectReflection->getProperties() as $propertyName => $property) {
|
||||||
$field = $fieldName;
|
if (! isset($this->parsedParameters[$propertyName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$attribute = $property->getAttribute(Attribute\SearchParameter::class)->object ?? false;
|
||||||
|
|
||||||
|
if ( $condition = $getCondition($propertyName) ) {
|
||||||
|
match(true) {
|
||||||
|
$attribute instanceof SearchManual => throw new \LogicException("Impossible to add a condition to a manually filtered elements."),
|
||||||
|
$attribute instanceof SearchGroupBy => throw new \LogicException("Impossible to add a condition to a group by field."),
|
||||||
|
$attribute instanceof SearchOrderBy => throw new \LogicException("Impossible to add a condition to a order by field."),
|
||||||
|
default => $this->parsedParameters[$propertyName]->condition = $condition,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyOperators(\Closure $getOperator) : void
|
||||||
|
{
|
||||||
|
foreach($this->objectReflection->getProperties() as $propertyName => $property) {
|
||||||
|
if (! isset($this->parsedParameters[$propertyName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$attribute = $property->getAttribute(Attribute\SearchParameter::class)->object ?? false;
|
||||||
|
|
||||||
|
if ($attribute) {
|
||||||
|
if ($operator = $getOperator($propertyName)) {
|
||||||
|
match (true) {
|
||||||
|
$attribute instanceof SearchManual => throw new \LogicException("Impossible to add an operator to a manually filtered elements."),
|
||||||
|
$attribute instanceof SearchGroupBy => throw new \LogicException("Impossible to add an operator to a group by field."),
|
||||||
|
$attribute instanceof SearchOrderBy => throw new \LogicException("Impossible to add an operator to a order by field."),
|
||||||
|
default => $this->parsedParameters[$propertyName]->operator = $operator,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$value = $this->getValueFromSource($request, $propertyName, $attribute);
|
protected function applyValues(\Closure $getValue) : void
|
||||||
|
{
|
||||||
|
foreach($this->objectReflection->getProperties() as $propertyName => $property) {
|
||||||
|
$attribute = $property->getAttribute(Attribute\SearchParameter::class)->object ?? false;
|
||||||
|
|
||||||
|
if ($attribute) {
|
||||||
|
$field = $this->getEntityField($attribute->field ?? $propertyName);
|
||||||
|
$field = $this->transformField($property->getAttributes(Attribute\FieldValueModifier::class), $field);
|
||||||
|
|
||||||
|
$value = $getValue($propertyName, $attribute);
|
||||||
|
|
||||||
if ($value !== null) {
|
if ($value !== null) {
|
||||||
$value = $this->transformValue($property->getAttributes(Attribute\PropertyValueModifier::class), $value);
|
$value = $this->transformValue($property->getAttributes(Attribute\PropertyValueModifier::class), $value);
|
||||||
@ -195,40 +207,24 @@ trait SearchRequestFromRequestTrait
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [[ Boilerplates which are ready to be copied */
|
protected function getEntityField(array|string $fieldName) : string|\Stringable
|
||||||
public function wheres() : iterable
|
|
||||||
{
|
{
|
||||||
return array_filter($this->wheres + [
|
# Field could be defined for another entity class
|
||||||
|
if (is_array($fieldName)) {
|
||||||
|
$field = \Ulmus\Attribute\Attribute::handleArrayField($fieldName, false);
|
||||||
|
}
|
||||||
|
# Default class using it, if SearchRequestParameter is defined
|
||||||
|
elseif ($classAttributes = $this->objectReflection->getAttributes(SearchRequestParameter::class)) {
|
||||||
|
$searchRequestAttribute = $classAttributes[0]->object;
|
||||||
|
$className = $searchRequestAttribute->class;
|
||||||
|
$field = $className::field($fieldName, $searchRequestAttribute->alias);
|
||||||
|
}
|
||||||
|
|
||||||
], fn($i) => ! is_null($i) ) + [ ];
|
return $field ?? $fieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function likes(): iterable
|
|
||||||
{
|
|
||||||
return array_filter($this->likes + [
|
|
||||||
|
|
||||||
], fn($i) => ! is_null($i) ) + [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function groups(): iterable
|
|
||||||
{
|
|
||||||
return array_filter($this->groups + [
|
|
||||||
|
|
||||||
], fn($e) => ! is_null($e) && $e !== "" );
|
|
||||||
}
|
|
||||||
|
|
||||||
public function orders(): iterable
|
|
||||||
{
|
|
||||||
return array_filter($this->orders + [
|
|
||||||
|
|
||||||
], fn($e) => ! is_null($e) && $e !== "" );
|
|
||||||
}
|
|
||||||
/* ]] */
|
|
||||||
|
|
||||||
protected function getValueFromSource(RequestInterface $request, string $propertyName, SearchParameter $attribute) : mixed
|
protected function getValueFromSource(RequestInterface $request, string $propertyName, SearchParameter $attribute) : mixed
|
||||||
{
|
{
|
||||||
$queryParamName = $attribute->getParameters() ?: [ $propertyName ];
|
$queryParamName = $attribute->getParameters() ?: [ $propertyName ];
|
||||||
@ -262,7 +258,16 @@ trait SearchRequestFromRequestTrait
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function transformValue(array $valueModifierAttributes, mixed $value, ) : mixed
|
protected function transformField(array $fieldModifierAttributes, mixed $field) : mixed
|
||||||
|
{
|
||||||
|
foreach($fieldModifierAttributes as $transform) {
|
||||||
|
$field = $transform->object->run($field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function transformValue(array $valueModifierAttributes, mixed $value) : mixed
|
||||||
{
|
{
|
||||||
foreach($valueModifierAttributes as $transform) {
|
foreach($valueModifierAttributes as $transform) {
|
||||||
$value = $transform->object->run($value);
|
$value = $transform->object->run($value);
|
||||||
@ -271,42 +276,44 @@ trait SearchRequestFromRequestTrait
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function parseAttributeMethod(object $attribute, string $field, string $propertyName,) : void
|
protected function parseAttributeMethod(object $attribute, string|\Stringable $field, string $propertyName) : void
|
||||||
{
|
{
|
||||||
if (! isset($this->$propertyName)) {
|
if (! isset($this->$propertyName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($attribute->method) {
|
switch ($attribute->method) {
|
||||||
case SearchMethodEnum::Where:
|
|
||||||
$this->wheres[$field] = $this->$propertyName;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SearchMethodEnum::Like:
|
case SearchMethodEnum::Like:
|
||||||
$this->likes[$field] = "%{$this->$propertyName}%";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SearchMethodEnum::LikeLeft:
|
case SearchMethodEnum::LikeLeft:
|
||||||
$this->likes[$field] = "%{$this->$propertyName}";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SearchMethodEnum::LikeRight:
|
case SearchMethodEnum::LikeRight:
|
||||||
$this->likes[$field] = "{$this->$propertyName}%";
|
case SearchMethodEnum::Where:
|
||||||
break;
|
$this->parsedParameters[$propertyName] = new ParsedSearchParameter(
|
||||||
|
searchMethod: $attribute->method,
|
||||||
|
field: $field,
|
||||||
|
value: $this->$propertyName,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function parseAttributeOrderBy(object $attribute, string $field, mixed $propertyName,) : void
|
protected function parseAttributeOrderBy(object $attribute, string $field, mixed $propertyName) : void
|
||||||
{
|
{
|
||||||
if ( ! empty($this->$propertyName) ) {
|
if ( ! empty($this->$propertyName) ) {
|
||||||
$this->orders[$field] = $this->$propertyName;
|
$this->parsedParameters[$propertyName] = new ParsedSearchParameter(
|
||||||
|
searchMethod: SearchMethodEnum::OrderBy,
|
||||||
|
field: $field,
|
||||||
|
value: $this->$propertyName,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function parseAttributeGroupBy(object $attribute, string $field, mixed $propertyName,) : void
|
protected function parseAttributeGroupBy(object $attribute, string $field, mixed $propertyName) : void
|
||||||
{
|
{
|
||||||
if (! empty($this->$propertyName)) {
|
if (! empty($this->$propertyName)) {
|
||||||
$this->groups[] = $field;
|
$this->parsedParameters[$propertyName] = new ParsedSearchParameter(
|
||||||
|
searchMethod: SearchMethodEnum::GroupBy,
|
||||||
|
field: $field,
|
||||||
|
value: null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,9 +5,8 @@ namespace Ulmus\SearchRequest;
|
|||||||
use Ulmus\Repository;
|
use Ulmus\Repository;
|
||||||
|
|
||||||
interface SearchRequestInterface {
|
interface SearchRequestInterface {
|
||||||
|
|
||||||
/* HOW TO IMPLEMENT THIS !!? */
|
|
||||||
public const SEARCH_REQUEST_OPERATORS = "searchRequest:operators";
|
public const SEARCH_REQUEST_OPERATORS = "searchRequest:operators";
|
||||||
|
public const SEARCH_REQUEST_OPERATOR_LIKE = "LIKE";
|
||||||
public const SEARCH_REQUEST_OPERATOR_EQUAL = "=";
|
public const SEARCH_REQUEST_OPERATOR_EQUAL = "=";
|
||||||
public const SEARCH_REQUEST_OPERATOR_NOT_EQUAL = "!=";
|
public const SEARCH_REQUEST_OPERATOR_NOT_EQUAL = "!=";
|
||||||
public const SEARCH_REQUEST_OPERATOR_GREATER_THAN = ">";
|
public const SEARCH_REQUEST_OPERATOR_GREATER_THAN = ">";
|
||||||
@ -15,12 +14,24 @@ interface SearchRequestInterface {
|
|||||||
public const SEARCH_REQUEST_OPERATOR_SMALLER_THAN = "<";
|
public const SEARCH_REQUEST_OPERATOR_SMALLER_THAN = "<";
|
||||||
public const SEARCH_REQUEST_OPERATOR_SMALLER_OR_EQUAL_THAN = "<=";
|
public const SEARCH_REQUEST_OPERATOR_SMALLER_OR_EQUAL_THAN = "<=";
|
||||||
|
|
||||||
|
public const SEARCH_REQUEST_CONDITIONS = "searchRequest:conditions";
|
||||||
|
public const SEARCH_REQUEST_CONDITION_AND = "AND";
|
||||||
|
public const SEARCH_REQUEST_CONDITION_OR= "OR";
|
||||||
|
|
||||||
public function filter(Repository $repository) : Repository;
|
public function filter(Repository $repository) : Repository;
|
||||||
|
|
||||||
public function wheres() : iterable;
|
public function wheres() : iterable;
|
||||||
|
|
||||||
|
public function wheresConditions() : iterable;
|
||||||
|
|
||||||
|
public function wheresOperators() : iterable;
|
||||||
|
|
||||||
public function likes() : iterable;
|
public function likes() : iterable;
|
||||||
|
|
||||||
|
public function likesConditions() : iterable;
|
||||||
|
|
||||||
|
public function likesOperators() : iterable;
|
||||||
|
|
||||||
public function orders() : iterable;
|
public function orders() : iterable;
|
||||||
|
|
||||||
public function groups() : iterable;
|
public function groups() : iterable;
|
||||||
@ -28,4 +39,8 @@ interface SearchRequestInterface {
|
|||||||
public function limit() : int;
|
public function limit() : int;
|
||||||
|
|
||||||
public function offset() : int;
|
public function offset() : int;
|
||||||
|
|
||||||
|
public function applyCount(Repository\RepositoryInterface $repository) : SearchRequestInterface;
|
||||||
|
|
||||||
|
public function apply(Repository\RepositoryInterface $repository) : SearchRequestInterface;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user