ulmus/src/SearchRequest/SearchRequestFromRequestTrait.php
2024-05-21 13:00:19 +00:00

142 lines
5.0 KiB
PHP

<?php
namespace Ulmus\SearchRequest;
use Psr\Http\Message\ServerRequestInterface;
use Ulmus\SearchRequest\Attribute\{ SearchParameter, SearchWhere, SearchLike, SearchOrderBy, SearchGroupBy, SearchRequestParameter, };
trait SearchRequestFromRequestTrait
{
protected array $wheres = [];
protected array $likes = [];
protected array $groups = [];
protected array $orders = [];
public function fromRequest(ServerRequestInterface $request)
{
$queryParams = new \ArrayObject(array_filter($request->getQueryParams(), function($i) { return ! is_null($i) && $i !== ""; }));
$this->page = $queryParams->offsetExists('page') ? $queryParams['page'] : 1;
$classReflection = new \ReflectionClass($this);
foreach($classReflection->getProperties() as $property) {
$attributeList = $property->getAttributes();
$attributeReflection = array_filter($attributeList, fn($e) => $e->newInstance() instanceof Attribute\SearchParameter);
if ($attributeReflection) {
$attribute = $attributeReflection[0]->newInstance();
$propertyName = $property->getName();
$fieldName = $attribute->field ?? $propertyName;
$queryParamName = $attribute->parameter ?? $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]->newInstance();
$className = $searchRequestAttribute->class;
$field = $className::field($fieldName, $searchRequestAttribute->alias);
}
# Untouched string from the attribute
else {
$field = $fieldName;
}
$value = $queryParams->offsetExists($queryParamName) ? $this->transformValue($attributeList, $queryParams[$queryParamName]) : null;
if ($attribute instanceof SearchWhere || $attribute instanceof SearchLike) {
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;
}
$this->parseAttributeOrderBy($attribute, $field, $propertyName);
}
elseif ($attribute instanceof SearchGroupBy) {
$this->parseAttributeGroupBy($attribute, $field, $propertyName);
}
}
}
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
{
if (! isset($this->$propertyName)) {
return;
}
switch ($attribute->method) {
case SearchMethodEnum::Where:
$this->wheres[$field] = $this->$propertyName;
break;
case SearchMethodEnum::Like:
$this->likes[$field] = "%{$this->$propertyName}%";
break;
case SearchMethodEnum::LikeLeft:
$this->likes[$field] = "%{$this->$propertyName}";
break;
case SearchMethodEnum::LikeRight:
$this->likes[$field] = "{$this->$propertyName}%";
break;
}
}
protected function parseAttributeOrderBy(object $attribute, string $field, mixed $propertyName,) : void
{
$this->orders[$field] = $this->$propertyName;
}
protected function parseAttributeGroupBy(object $attribute, string $field, mixed $propertyName,) : void
{
if (! empty($this->$propertyName)) {
$this->groups[] = $field;
}
}
# @TODO !
/* protected function parseAttributeGroupBy(object $attribute, string $field, string $propertyName,) : void
{
switch ($attribute->order) {
case SearchMethodEnum::GroupBy:
$this->groups[$field];
break;
}
}*/
}