Skip to content

Instantly share code, notes, and snippets.

@grachevko
Last active February 3, 2022 08:06
Show Gist options
  • Save grachevko/103eb304384257b7959a6ebc82c7557c to your computer and use it in GitHub Desktop.
Save grachevko/103eb304384257b7959a6ebc82c7557c to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace App\JsonRpc\ArgumentResolver;
use App\JsonRpc\Exception\ValidationException;
use App\JsonRpc\RpcMethodRequest;
use Premier\ArgumentResolver\ArgumentMetadata;
use Premier\ArgumentResolver\ArgumentValueResolverInterface;
use Symfony\Component\DependencyInjection\Attribute\AsTaggedItem;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use function assert;
use function class_exists;
use function count;
use function is_string;
use function is_subclass_of;
#[AsTaggedItem(priority: -100)]
final class RequestArgumentValueResolver implements ArgumentValueResolverInterface
{
public function __construct(
private DenormalizerInterface $denormalizer,
private ValidatorInterface $validator,
private bool $debug,
) {
}
/**
* {@inheritdoc}
*/
public function supports(mixed $data, ArgumentMetadata $argument): bool
{
$type = $argument->getType();
if (!is_string($type) || !class_exists($type)) {
return false;
}
return is_subclass_of($type, RpcMethodRequest::class);
}
/**
* {@inheritdoc}
*/
public function resolve(mixed $data, ArgumentMetadata $argument): iterable
{
$class = $argument->getType();
assert(is_string($class) && class_exists($class));
$context = [
'disable_type_enforcement' => true,
'allow_extra_attributes' => !$this->debug,
];
$dto = $this->denormalizer->denormalize($data['request'], $class, null, $context);
$errors = $this->validator->validate($dto);
if (0 !== count($errors)) {
throw new ValidationException($errors);
}
yield $dto;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment