142 lines
5.0 KiB
PHP
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;
|
|
}
|
|
}*/
|
|
} |