Skip to content

Commit

Permalink
[HttpKernel] Support variadic with #[MapRequestPayload]
Browse files Browse the repository at this point in the history
  • Loading branch information
DjordyKoert committed May 2, 2024
1 parent 4c84578 commit c08c101
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/Symfony/Component/HttpKernel/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ CHANGELOG
* Add `$type` argument to `#[MapRequestPayload]` that allows mapping a list of items
* Deprecate `Extension::addAnnotatedClassesToCompile()` and related code infrastructure
* Add `#[MapUploadedFile]` attribute to fetch, validate, and inject uploaded files into controller arguments
* Support variadic argument with `#[MapRequestPayload]`

7.0
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
return [];
}

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

Expand Down Expand Up @@ -170,7 +170,11 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo
};
}

$arguments[$i] = $payload;
if ($argument->metadata->isVariadic() && is_array($payload)) {
array_splice($arguments, $i, 1, $payload);
} else {
$arguments[$i] = $payload;
}
}

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

if ('array' === $argument->getType() && null !== $attribute->type) {
$type = $attribute->type.'[]';
} elseif ($argument->isVariadic()) {
$type = $argument->getType().'[]';
} else {
$type = $argument->getType();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ public function testItThrowsOnVariadicArgument()
$resolver = new RequestPayloadValueResolver($serializer, $validator);

$argument = new ArgumentMetadata('variadic', RequestPayload::class, true, false, null, false, [
MapRequestPayload::class => new MapRequestPayload(),
MapQueryString::class => new MapQueryString(),
]);
$request = Request::create('/', 'POST');

Expand Down Expand Up @@ -874,6 +874,40 @@ public function testBoolArgumentInJsonBody()

$this->assertTrue($event->getArguments()[0]->value);
}

public function testMapRequestPayloadVariadic()
{
$input = [
['price' => '50'],
['price' => '23'],
];
$payload = [
new RequestPayload(50),
new RequestPayload(23),
];

$serializer = new Serializer([new ArrayDenormalizer(), new ObjectNormalizer()], ['json' => new JsonEncoder()]);

$validator = $this->createMock(ValidatorInterface::class);
$validator->expects($this->once())
->method('validate')
->willReturn(new ConstraintViolationList());

$resolver = new RequestPayloadValueResolver($serializer, $validator);

$argument = new ArgumentMetadata('prices', RequestPayload::class, true, false, null, false, [
MapRequestPayload::class => new MapRequestPayload(),
]);
$request = Request::create('/', 'POST', $input);

$kernel = $this->createMock(HttpKernelInterface::class);
$arguments = $resolver->resolve($request, $argument);
$event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST);

$resolver->onKernelControllerArguments($event);

$this->assertEquals($payload, $event->getArguments());
}
}

class RequestPayload
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ static function () {},
$resolver->onKernelControllerArguments($event);

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

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

0 comments on commit c08c101

Please sign in to comment.