- Continued work on SearchRequest migration and fixed some more QueryBuilder migration too

This commit is contained in:
Dave M. 2024-04-18 19:59:28 +00:00
parent 9fdebf454d
commit 950df5eb99
15 changed files with 122 additions and 48 deletions

View File

@ -5,6 +5,8 @@ namespace Ulmus\Query;
use Ulmus\Common\EntityField, use Ulmus\Common\EntityField,
Ulmus\Common\Sql; Ulmus\Common\Sql;
use Ulmus\QueryBuilder\QueryBuilderInterface;
class Having extends Fragment { class Having extends Fragment {
const SQL_TOKEN = "HAVING"; const SQL_TOKEN = "HAVING";

View File

@ -4,6 +4,8 @@ namespace Ulmus\Query;
use Ulmus\Repository\ConditionTrait; use Ulmus\Repository\ConditionTrait;
use Ulmus\QueryBuilder\QueryBuilderInterface;
class Join extends Fragment class Join extends Fragment
{ {
use ConditionTrait; use ConditionTrait;

View File

@ -2,6 +2,8 @@
namespace Ulmus\Query; namespace Ulmus\Query;
use Ulmus\QueryBuilder\QueryBuilderInterface;
class Set extends Fragment { class Set extends Fragment {
public int $order = 0; public int $order = 0;
@ -25,7 +27,7 @@ class Set extends Fragment {
return $this; return $this;
} }
public function render() /* : mixed */ public function render() : mixed
{ {
return $this->renderSegments([ return $this->renderSegments([
'SET', $this->renderParameterPlaceholders(), 'SET', $this->renderParameterPlaceholders(),

View File

@ -2,6 +2,8 @@
namespace Ulmus\Query; namespace Ulmus\Query;
use Ulmus\QueryBuilder\QueryBuilderInterface;
class Values extends Fragment { class Values extends Fragment {
public int $order = 0; public int $order = 0;

View File

@ -4,6 +4,8 @@ namespace Ulmus\Query;
use Ulmus\Common\Sql; use Ulmus\Common\Sql;
use Ulmus\QueryBuilder\QueryBuilderInterface;
class Where extends Fragment { class Where extends Fragment {
const OPERATOR_LIKE = "LIKE"; const OPERATOR_LIKE = "LIKE";
const OPERATOR_EQUAL = "="; const OPERATOR_EQUAL = "=";

View File

@ -507,6 +507,15 @@ class MysqlQueryBuilder extends SqlQueryBuilder
$key = ":p" . $this->parameterIndex++; $key = ":p" . $this->parameterIndex++;
} }
if ($value instanceof \UnitEnum) {
if ($value instanceof \BackedEnum) {
$value = $value->value;
}
else {
throw new \InvalidArgumentException("Using UnitEnum as a parameter is currently unsupported. Try using a BackedEnum instead.");
}
}
$this->parameters[$key] = $value; $this->parameters[$key] = $value;
return $key; return $key;

View File

@ -0,0 +1,9 @@
<?php
namespace Ulmus\SearchRequest\Attribute;
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)]
abstract class PropertyValueModifier
{
public abstract function run(mixed $value) : mixed;
}

View File

@ -0,0 +1,18 @@
<?php
namespace Ulmus\SearchRequest\Attribute\PropertyValueModifier;
use Ulmus\SearchRequest\Attribute\PropertyValueModifier;
#[\Attribute(\Attribute::TARGET_PROPERTY)]
class Split extends PropertyValueModifier
{
public function __construct(
public string $delimiter = ',',
) {}
public function run(mixed $value) : mixed
{
return explode($this->delimiter, $value);
}
}

View File

@ -9,8 +9,7 @@ class SearchGroupBy extends SearchParameter
{ {
public function __construct( public function __construct(
public ? string $parameter = null, public ? string $parameter = null,
public ? string $field = null, public null|string|\Stringable|array $field = null,
public bool $toggle = false,
public SearchMethodEnum $method = SearchMethodEnum::GroupBy, public SearchMethodEnum $method = SearchMethodEnum::GroupBy,
) {} ) {}
} }

View File

@ -9,7 +9,7 @@ class SearchLike extends SearchParameter
{ {
public function __construct( public function __construct(
public ? string $parameter = null, public ? string $parameter = null,
public ? string $field = null, public null|string|\Stringable|array $field = null,
public bool $toggle = false, public bool $toggle = false,
public SearchMethodEnum $method = SearchMethodEnum::Like, public SearchMethodEnum $method = SearchMethodEnum::Like,
) {} ) {}

View File

@ -7,10 +7,13 @@ use Ulmus\SearchRequest\SearchMethodEnum;
#[\Attribute(\Attribute::TARGET_PROPERTY)] #[\Attribute(\Attribute::TARGET_PROPERTY)]
class SearchOrderBy extends SearchParameter class SearchOrderBy extends SearchParameter
{ {
public const ASCENDING = "ASC";
public const DESCENDING = "DESC";
public function __construct( public function __construct(
public ? string $parameter = null, public ? string $parameter = null,
public ? string $field = null, public null|string|\Stringable|array $field = null,
public bool $toggle = false, public null|SearchMethodEnum $order = null,
public SearchMethodEnum $method = SearchMethodEnum::OrderByAsc,
) {} ) {}
} }

View File

@ -7,10 +7,6 @@ use Ulmus\SearchRequest\SearchMethodEnum;
#[\Attribute(\Attribute::TARGET_PROPERTY)] #[\Attribute(\Attribute::TARGET_PROPERTY)]
class SearchParameter class SearchParameter
{ {
public function __construct(
public ? string $parameter = null,
public ? string $field = null,
public bool $toggle = false,
public SearchMethodEnum $method = SearchMethodEnum::Manual,
) {}
} }

View File

@ -9,7 +9,7 @@ class SearchWhere extends SearchParameter
{ {
public function __construct( public function __construct(
public ? string $parameter = null, public ? string $parameter = null,
public ? string $field = null, public null|string|\Stringable|array $field = null,
public bool $toggle = false, public bool $toggle = false,
public SearchMethodEnum $method = SearchMethodEnum::Where, public SearchMethodEnum $method = SearchMethodEnum::Where,
) {} ) {}

View File

@ -9,7 +9,4 @@ enum SearchMethodEnum
case Like; case Like;
case LikeLeft; case LikeLeft;
case LikeRight; case LikeRight;
case OrderByAsc;
case OrderByDesc;
case GroupBy;
} }

View File

@ -3,6 +3,8 @@
namespace Ulmus\SearchRequest; namespace Ulmus\SearchRequest;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Ulmus\SearchRequest\Attribute\SearchGroupBy;
use Ulmus\SearchRequest\Attribute\SearchOrderBy;
use Ulmus\SearchRequest\Attribute\SearchParameter; use Ulmus\SearchRequest\Attribute\SearchParameter;
use Ulmus\SearchRequest\Attribute\SearchWhere; use Ulmus\SearchRequest\Attribute\SearchWhere;
@ -18,43 +20,71 @@ trait SearchRequestFromRequestTrait
public function fromRequest(ServerRequestInterface $request) public function fromRequest(ServerRequestInterface $request)
{ {
$get = new \ArrayObject(array_filter($request->getQueryParams(), function($i) { return $i !== ""; })); $queryParams = new \ArrayObject(array_filter($request->getQueryParams(), function($i) { return ! is_null($i) && $i !== ""; }));
$this->page = $get->offsetExists('page') ? $get['page'] : 1; $this->page = $queryParams->offsetExists('page') ? $queryParams['page'] : 1;
$classReflection = new \ReflectionClass($this); $classReflection = new \ReflectionClass($this);
foreach($classReflection->getProperties() as $property) { foreach($classReflection->getProperties() as $property) {
$attributeList = $property->getAttributes();
foreach($property->getAttributes() as $attributeReflection) { $attributeReflection = array_filter($attributeList, fn($e) => $e->newInstance() instanceof Attribute\SearchParameter);
$attribute = $attributeReflection->newInstance();
# We can't simply pass this class as first arguments of getAttributes() since it do not check for inheritance if ($attributeReflection) {
if (! $attribute instanceof Attribute\SearchParameter) { $attribute = $attributeReflection[0]->newInstance();
continue;
$propertyName = $property->getName();
$fieldName = $attribute->field ?? $propertyName;
$queryParamName = $attribute->parameter ?? $propertyName;
$field = \Ulmus\Attribute\Attribute::handleArrayField($fieldName, false);;
$value = $queryParams->offsetExists($queryParamName) ? $this->transformValue($attributeList, $queryParams[$queryParamName]) : null;
if ($attribute instanceof SearchWhere) {
if ($attribute->toggle) {
$this->$propertyName = $queryParams->offsetExists($queryParamName);
}
elseif ($value !== null) {
$this->$propertyName = $value;
}
$this->parseAttributeMethod($attribute, $field, $propertyName);
} }
elseif ($attribute instanceof SearchOrderBy) {
if ($value !== null) {
$this->$propertyName = $value;
}
$propertyName = $property->getName(); $this->parseAttributeDefaultOrder($attribute, $field, $propertyName);
$fieldName = $attribute->field ?? $property->getName();
$queryParamName = $attribute->parameter ?? $property->getName();
if ($attribute->toggle) {
$this->$propertyName = $get->offsetExists('rental');
} else {
$this->$propertyName = $get->offsetExists($queryParamName) ? $get[$queryParamName] : null;
} }
$field = (string) $fieldName;
$this->parseAttributeMethod($attribute, $field, $propertyName);
} }
} }
return $this; return $this;
} }
protected function transformValue(array $attributeList, mixed $value, ) : mixed
{
$transforms = array_map(function($e) {
$instance = $e->newInstance();
return $instance instanceof Attribute\PropertyValueModifier ? $e->newInstance() : null;
}, $attributeList);
foreach(array_filter($transforms) as $transform) {
$value = $transform->run($value);
}
return $value;
}
protected function parseAttributeMethod(object $attribute, string $field, string $propertyName,) : void protected function parseAttributeMethod(object $attribute, string $field, string $propertyName,) : void
{ {
if (! isset($this->$propertyName)) {
return;
}
switch ($attribute->method) { switch ($attribute->method) {
case SearchMethodEnum::Where: case SearchMethodEnum::Where:
$this->wheres[$field] = $this->$propertyName; $this->wheres[$field] = $this->$propertyName;
@ -71,18 +101,21 @@ trait SearchRequestFromRequestTrait
case SearchMethodEnum::LikeRight: case SearchMethodEnum::LikeRight:
$this->likes[$field] = "{$this->$propertyName}%"; $this->likes[$field] = "{$this->$propertyName}%";
break; break;
case SearchMethodEnum::OrderByAsc:
$this->orders[$field] = "ASC";
break;
case SearchMethodEnum::OrderByDesc:
$this->orders[$field] = "DESC";
break;
case SearchMethodEnum::GroupBy:
$this->groups[$field] = "DESC";
break;
} }
} }
protected function parseAttributeDefaultOrder(object $attribute, string $field, mixed $propertyName,) : void
{
$this->orders[$field] = $this->$propertyName;
}
# @TODO !
/* protected function parseAttributeGroupBy(object $attribute, string $field, string $propertyName,) : void
{
switch ($attribute->order) {
case SearchMethodEnum::GroupBy:
$this->groups[$field];
break;
}
}*/
} }