input mapping
This commit is contained in:
parent
bba10b455f
commit
fc46fe20ee
29 changed files with 193 additions and 887 deletions
|
|
@ -13,6 +13,8 @@ use Illuminate\Support\Facades\Log;
|
|||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ReflectionNamedType;
|
||||
use phpDocumentor\Reflection\Types\AbstractList;
|
||||
|
||||
class DataObjectFactory
|
||||
{
|
||||
|
|
@ -21,7 +23,8 @@ class DataObjectFactory
|
|||
*/
|
||||
public static function fromRequest(string $class, Request $request): ?object
|
||||
{
|
||||
$routeParameters = $request->route() instanceof Route ? $request->route()->parameters() : [];
|
||||
$route = $request->route();
|
||||
$routeParameters = $route instanceof Route ? $route->parameters() : [];
|
||||
return static::fromArray($class, $request->input(), $routeParameters);
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +55,6 @@ class DataObjectFactory
|
|||
return ValueFactory::make($class, $validator->validated());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param class-string $class
|
||||
* @param array<string,mixed> $rawInput
|
||||
|
|
@ -67,6 +69,7 @@ class DataObjectFactory
|
|||
): array {
|
||||
$input = [];
|
||||
$parameters = ReflectionHelper::getParametersMeta($class);
|
||||
|
||||
foreach ($parameters as $parameter) {
|
||||
$parameterName = $parameter->reflection->getName();
|
||||
|
||||
|
|
@ -77,17 +80,51 @@ class DataObjectFactory
|
|||
}
|
||||
}
|
||||
|
||||
$reflectionType = $parameter->reflection->getType();
|
||||
$namedType = $reflectionType instanceof ReflectionNamedType ? $reflectionType->getName() : null;
|
||||
$annotatedType = $parameter->tag?->getType();
|
||||
|
||||
$isListType
|
||||
= $parameter->reflection->isArray()
|
||||
|| in_array($namedType, config('dto.listTypes', []))
|
||||
|| in_array($annotatedType?->__toString(), config('dto.listTypes', []))
|
||||
|| $annotatedType instanceof AbstractList;
|
||||
|
||||
foreach ($parameter->reflection->getAttributes(FromInput::class) as $attr) {
|
||||
if ($value = $rawInput[$attr->newInstance()->name] ?? null) {
|
||||
$input[$parameterName] = $value;
|
||||
if ($valueType = ReflectionHelper::getListParameterValueType($parameter->tag)) {
|
||||
$input[$parameterName] = $isListType
|
||||
? array_map(
|
||||
fn($element) => self::mapInput($valueType, $element, $routeParameters, $logger),
|
||||
$value,
|
||||
)
|
||||
: self::mapInput($valueType, $value, $routeParameters, $logger);
|
||||
} else {
|
||||
$input[$parameterName] = $value;
|
||||
}
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ($value = $rawInput[$parameterName] ?? null) {
|
||||
$input[$parameterName] = $value;
|
||||
if ($valueType = ReflectionHelper::getListParameterValueType($parameter->tag)) {
|
||||
$input[$parameterName] = $isListType
|
||||
? array_map(
|
||||
fn($element) => self::mapInput($valueType, $element, $routeParameters, $logger),
|
||||
$rawInput[$parameterName],
|
||||
)
|
||||
: self::mapInput($valueType, $rawInput[$parameterName], $routeParameters, $logger);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($reflectionType instanceof ReflectionNamedType) {
|
||||
$input[$parameterName] = $reflectionType->isBuiltin()
|
||||
? $rawInput[$parameterName]
|
||||
: self::mapInput($reflectionType->__toString(), $rawInput[$parameterName], $routeParameters, $logger);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$input[$parameterName] = $rawInput[$parameterName];
|
||||
}
|
||||
$logger->debug('input', $input);
|
||||
return $input;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace Icefox\DTO;
|
|||
use ReflectionParameter;
|
||||
use phpDocumentor\Reflection\DocBlock\Tag;
|
||||
use phpDocumentor\Reflection\DocBlock\Tags\Param;
|
||||
use phpDocumentor\Reflection\PseudoTypes\Generic;
|
||||
use phpDocumentor\Reflection\Types\AbstractList;
|
||||
use phpDocumentor\Reflection\Types\ContextFactory;
|
||||
use phpDocumentor\Reflection\DocBlockFactory;
|
||||
use ReflectionClass;
|
||||
|
|
@ -44,4 +46,21 @@ class ReflectionHelper
|
|||
);
|
||||
return self::$cache[$class];
|
||||
}
|
||||
|
||||
public static function getListParameterValueType(?Param $param): ?string
|
||||
{
|
||||
$type = $param?->getType();
|
||||
|
||||
if ($type instanceof AbstractList) {
|
||||
return $type->getValueType()->__toString();
|
||||
}
|
||||
|
||||
if (!$type instanceof Generic) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$subtypes = $type->getTypes();
|
||||
return count($subtypes) > 1 ? $subtypes[1]->__toString() : $subtypes[0]->__toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue