Skip to content

Commit fc7b7c8

Browse files
committed
[HttpKernel] Support variadic with #[MapRequestPayload]
1 parent 4c84578 commit fc7b7c8

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CHANGELOG
1111
* Add `$type` argument to `#[MapRequestPayload]` that allows mapping a list of items
1212
* Deprecate `Extension::addAnnotatedClassesToCompile()` and related code infrastructure
1313
* Add `#[MapUploadedFile]` attribute to fetch, validate, and inject uploaded files into controller arguments
14+
* Support variadic argument with `#[MapRequestPayload]`
1415

1516
7.0
1617
---

src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
7979
return [];
8080
}
8181

82-
if (!$attribute instanceof MapUploadedFile && $argument->isVariadic()) {
82+
if ($attribute instanceof MapQueryString && $argument->isVariadic()) {
8383
throw new \LogicException(sprintf('Mapping variadic argument "$%s" is not supported.', $argument->getName()));
8484
}
8585

@@ -170,7 +170,11 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo
170170
};
171171
}
172172

173-
$arguments[$i] = $payload;
173+
if ($argument->metadata->isVariadic() && \is_array($payload)) {
174+
array_splice($arguments, $i, 1, $payload);
175+
} else {
176+
$arguments[$i] = $payload;
177+
}
174178
}
175179

176180
$event->setArguments($arguments);
@@ -204,6 +208,8 @@ private function mapRequestPayload(Request $request, ArgumentMetadata $argument,
204208

205209
if ('array' === $argument->getType() && null !== $attribute->type) {
206210
$type = $attribute->type.'[]';
211+
} elseif ($argument->isVariadic()) {
212+
$type = $argument->getType().'[]';
207213
} else {
208214
$type = $argument->getType();
209215
}

src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestPayloadValueResolverTest.php

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ public function testItThrowsOnVariadicArgument()
498498
$resolver = new RequestPayloadValueResolver($serializer, $validator);
499499

500500
$argument = new ArgumentMetadata('variadic', RequestPayload::class, true, false, null, false, [
501-
MapRequestPayload::class => new MapRequestPayload(),
501+
MapQueryString::class => new MapQueryString(),
502502
]);
503503
$request = Request::create('/', 'POST');
504504

@@ -874,6 +874,40 @@ public function testBoolArgumentInJsonBody()
874874

875875
$this->assertTrue($event->getArguments()[0]->value);
876876
}
877+
878+
public function testMapRequestPayloadVariadic()
879+
{
880+
$input = [
881+
['price' => '50'],
882+
['price' => '23'],
883+
];
884+
$payload = [
885+
new RequestPayload(50),
886+
new RequestPayload(23),
887+
];
888+
889+
$serializer = new Serializer([new ArrayDenormalizer(), new ObjectNormalizer()], ['json' => new JsonEncoder()]);
890+
891+
$validator = $this->createMock(ValidatorInterface::class);
892+
$validator->expects($this->once())
893+
->method('validate')
894+
->willReturn(new ConstraintViolationList());
895+
896+
$resolver = new RequestPayloadValueResolver($serializer, $validator);
897+
898+
$argument = new ArgumentMetadata('prices', RequestPayload::class, true, false, null, false, [
899+
MapRequestPayload::class => new MapRequestPayload(),
900+
]);
901+
$request = Request::create('/', 'POST', $input);
902+
903+
$kernel = $this->createMock(HttpKernelInterface::class);
904+
$arguments = $resolver->resolve($request, $argument);
905+
$event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST);
906+
907+
$resolver->onKernelControllerArguments($event);
908+
909+
$this->assertEquals($payload, $event->getArguments());
910+
}
877911
}
878912

879913
class RequestPayload

src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/UploadedFileValueResolverTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ static function () {},
269269
$resolver->onKernelControllerArguments($event);
270270

271271
/** @var UploadedFile[] $data */
272-
$data = $event->getArguments()[0];
272+
$data = $event->getArguments();
273273

274274
$this->assertCount(2, $data);
275275
$this->assertSame('file-small.txt', $data[0]->getFilename());

0 commit comments

Comments
 (0)