diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver.php index 7b8d5b521d123..3b0f89509f65c 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver.php @@ -71,7 +71,10 @@ public function getArguments(Request $request, callable $controller, \Reflection throw new ResolverNotFoundException($resolverName, $this->namedResolvers instanceof ServiceProviderInterface ? array_keys($this->namedResolvers->getProvidedServices()) : []); } - $argumentValueResolvers = [$this->namedResolvers->get($resolverName)]; + $argumentValueResolvers = [ + $this->namedResolvers->get($resolverName), + new DefaultValueResolver(), + ]; } } diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/QueryParameterValueResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/QueryParameterValueResolver.php index 7255a792ba754..f2e4bee812d79 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/QueryParameterValueResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/QueryParameterValueResolver.php @@ -31,12 +31,8 @@ public function resolve(Request $request, ArgumentMetadata $argument): array $name = $attribute->name ?? $argument->getName(); if (!$request->query->has($name)) { - if ($argument->hasDefaultValue()) { - return [$argument->getDefaultValue()]; - } - - if ($argument->isNullable()) { - return [null]; + if ($argument->isNullable() || $argument->hasDefaultValue()) { + return []; } throw new NotFoundHttpException(sprintf('Missing query parameter "%s".', $name)); diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/QueryParameterValueResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/QueryParameterValueResolverTest.php index 1383475988b52..539aaac78ee65 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/QueryParameterValueResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/QueryParameterValueResolverTest.php @@ -179,14 +179,14 @@ public static function provideTestResolve(): iterable yield 'parameter not found but nullable' => [ Request::create('/', 'GET'), new ArgumentMetadata('firstName', 'string', false, false, false, true, [new MapQueryParameter()]), - [null], + [], null, ]; yield 'parameter not found but optional' => [ Request::create('/', 'GET'), new ArgumentMetadata('firstName', 'string', false, true, false, attributes: [new MapQueryParameter()]), - [false], + [], null, ]; diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverTest.php index e62001633ca93..ef44f45bae078 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverTest.php @@ -296,6 +296,26 @@ public function testTargetedResolver() $this->assertSame([1], $resolver->getArguments($request, $controller)); } + public function testTargetedResolverWithDefaultValue() + { + $resolver = self::getResolver([], [RequestAttributeValueResolver::class => new RequestAttributeValueResolver()]); + + $request = Request::create('/'); + $controller = $this->controllerTargetingResolverWithDefaultValue(...); + + $this->assertSame([2], $resolver->getArguments($request, $controller)); + } + + public function testTargetedResolverWithNullableValue() + { + $resolver = self::getResolver([], [RequestAttributeValueResolver::class => new RequestAttributeValueResolver()]); + + $request = Request::create('/'); + $controller = $this->controllerTargetingResolverWithNullableValue(...); + + $this->assertSame([null], $resolver->getArguments($request, $controller)); + } + public function testDisabledResolver() { $resolver = self::getResolver(namedResolvers: []); @@ -373,6 +393,14 @@ public function controllerTargetingResolver(#[ValueResolver(DefaultValueResolver { } + public function controllerTargetingResolverWithDefaultValue(#[ValueResolver(RequestAttributeValueResolver::class)] int $foo = 2) + { + } + + public function controllerTargetingResolverWithNullableValue(#[ValueResolver(RequestAttributeValueResolver::class)] ?int $foo) + { + } + public function controllerDisablingResolver(#[ValueResolver(RequestAttributeValueResolver::class, disabled: true)] int $foo = 1) { }