<?php
declare(strict_types=1);
namespace Slivki\ArgumentResolver;
use Slivki\Request\QueryStringRequestInterface;
use Slivki\Validator\ApiValidatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
final class QueryStringRequestResolver implements ArgumentValueResolverInterface
{
private DenormalizerInterface $denormalizer;
private ApiValidatorInterface $validator;
public function __construct(DenormalizerInterface $denormalizer, ApiValidatorInterface $validator)
{
$this->denormalizer = $denormalizer;
$this->validator = $validator;
}
public function supports(Request $request, ArgumentMetadata $argument): bool
{
$type = $argument->getType();
if (null === $type || !\class_exists($type)) {
return false;
}
$interfaces = \class_implements($type);
return isset($interfaces[QueryStringRequestInterface::class]);
}
public function resolve(Request $request, ArgumentMetadata $argument): \Generator
{
$queryStringRequest = $this->denormalizer->denormalize(
$request->query->all(),
$argument->getType(),
null,
[AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT => true],
);
$this->validator->validate($queryStringRequest);
yield $queryStringRequest;
}
}