Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. QueryParameterValueResolver.php

function QueryParameterValueResolver::resolve

Overrides ValueResolverInterface::resolve

File

vendor/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php, line 30

Class

QueryParameterValueResolver
Resolve arguments of type: array, string, int, float, bool, \BackedEnum from query parameters.

Namespace

Symfony\Component\HttpKernel\Controller\ArgumentResolver

Code

public function resolve(Request $request, ArgumentMetadata $argument) : array {
    if (!($attribute = $argument->getAttributesOfType(MapQueryParameter::class)[0] ?? null)) {
        return [];
    }
    $name = $attribute->name ?? $argument->getName();
    $validationFailedCode = $attribute->validationFailedStatusCode;
    if (!$request->query
        ->has($name)) {
        if ($argument->isNullable() || $argument->hasDefaultValue()) {
            return [];
        }
        throw HttpException::fromStatusCode($validationFailedCode, \sprintf('Missing query parameter "%s".', $name));
    }
    $value = $request->query
        ->all()[$name];
    $type = $argument->getType();
    if (null === $attribute->filter && 'array' === $type) {
        if (!$argument->isVariadic()) {
            return [
                (array) $value,
            ];
        }
        $filtered = array_values(array_filter((array) $value, \is_array(...)));
        if ($filtered !== $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) {
            throw HttpException::fromStatusCode($validationFailedCode, \sprintf('Invalid query parameter "%s".', $name));
        }
        return $filtered;
    }
    $options = [
        'flags' => $attribute->flags | \FILTER_NULL_ON_FAILURE,
        'options' => $attribute->options,
    ];
    if ('array' === $type || $argument->isVariadic()) {
        $value = (array) $value;
        $options['flags'] |= \FILTER_REQUIRE_ARRAY;
    }
    else {
        $options['flags'] |= \FILTER_REQUIRE_SCALAR;
    }
    $enumType = null;
    $filter = match ($type) {    'array' => \FILTER_DEFAULT,
        'string' => \FILTER_DEFAULT,
        'int' => \FILTER_VALIDATE_INT,
        'float' => \FILTER_VALIDATE_FLOAT,
        'bool' => \FILTER_VALIDATE_BOOL,
        default => match ($enumType = is_subclass_of($type, \BackedEnum::class) ? (new \ReflectionEnum($type))->getBackingType()
            ->getName() : null) {    'int' => \FILTER_VALIDATE_INT,
            'string' => \FILTER_DEFAULT,
            default => throw new \LogicException(\sprintf('#[MapQueryParameter] cannot be used on controller argument "%s$%s" of type "%s"; one of array, string, int, float, bool or \\BackedEnum should be used.', $argument->isVariadic() ? '...' : '', $argument->getName(), $type ?? 'mixed')),
        
        },
    
    };
    $value = filter_var($value, $attribute->filter ?? $filter, $options);
    if (null !== $enumType && null !== $value) {
        $enumFrom = static function ($value) use ($type) {
            if (!\is_string($value) && !\is_int($value)) {
                return null;
            }
            try {
                return $type::from($value);
            } catch (\ValueError) {
                return null;
            }
        };
        $value = \is_array($value) ? array_map($enumFrom, $value) : $enumFrom($value);
    }
    if (null === $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) {
        throw HttpException::fromStatusCode($validationFailedCode, \sprintf('Invalid query parameter "%s".', $name));
    }
    if (!\is_array($value)) {
        return [
            $value,
        ];
    }
    $filtered = array_filter($value, static fn($v) => null !== $v);
    if ($argument->isVariadic()) {
        $filtered = array_values($filtered);
    }
    if ($filtered !== $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) {
        throw HttpException::fromStatusCode($validationFailedCode, \sprintf('Invalid query parameter "%s".', $name));
    }
    return $argument->isVariadic() ? $filtered : [
        $filtered,
    ];
}
RSS feed
Powered by Drupal