Created
May 8, 2024 21:16
-
-
Save BoShurik/03aea5a2f374e35b2274a010b596892f to your computer and use it in GitHub Desktop.
Simple Yii ParametersResolver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Model; | |
use App\Model\Attributes\FromBody; | |
use App\Model\Attributes\FromQuery; | |
use App\Model\Attributes\FromRequest; | |
use App\Model\Attributes\Model; | |
use Psr\Http\Message\RequestInterface; | |
use Psr\Http\Message\ServerRequestInterface; | |
use Webmozart\Assert\Assert; | |
use Yiisoft\Hydrator\HydratorInterface; | |
use Yiisoft\Middleware\Dispatcher\ParametersResolverInterface; | |
use Yiisoft\Validator\ValidatorInterface; | |
class ModelParameterResolver implements ParametersResolverInterface | |
{ | |
public function __construct( | |
private HydratorInterface $hydrator, | |
private ValidatorInterface $validator | |
) { | |
} | |
public function resolve(array $parameters, ServerRequestInterface $request): array | |
{ | |
$result = []; | |
foreach ($parameters as $parameter) { | |
$type = $parameter->getType(); | |
if (!$type instanceof \ReflectionNamedType || $type->isBuiltin()) { | |
continue; | |
} | |
$attributes = $parameter->getAttributes(Model::class, \ReflectionAttribute::IS_INSTANCEOF); | |
if ($attributes === []) { | |
continue; | |
} | |
$class = $type->getName(); | |
/** @var \ReflectionAttribute $attribute */ | |
$attribute = current($attributes); | |
$attribute = $attribute->newInstance(); | |
$data = match ($attribute::class) { | |
FromBody::class => $this->getBodyData($request), | |
FromRequest::class => (array) $request->getParsedBody(), | |
FromQuery::class => $request->getQueryParams(), | |
}; | |
$value = $this->hydrator->create($class, $data); | |
if ($attribute->validate) { | |
$violations = $this->validator->validate($value); | |
if (!$violations->isValid()) { | |
throw new ViolationException($violations); | |
} | |
} | |
$result[$parameter->getName()] = $value; | |
} | |
return $result; | |
} | |
private function getBodyData(RequestInterface $request): array | |
{ | |
$data = json_decode($request->getBody()->getContents(), true); | |
Assert::isArray($data); | |
return $data; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment