8000 add support to multiple files · symfony/symfony@66e8f09 · GitHub
[go: up one dir, main page]

Skip to content

Commit 66e8f09

Browse files
author
Rene
committed
add support to multiple files
1 parent ea50c48 commit 66e8f09

File tree

3 files changed

+46
-16
lines changed

3 files changed

+46
-16
lines changed

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ApiAttributesTest.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
2020
use Symfony\Component\HttpKernel\Attribute\MapUploadedFile;
2121
use Symfony\Component\Validator\Constraints as Assert;
22-
use Symfony\Component\Validator\Constraints\File;
2322

2423
class ApiAttributesTest extends AbstractWebTestCase
2524
{
@@ -460,6 +459,31 @@ public function testMapUploadedFileWithConstraints()
460459
self::assertSame(400, $response->getStatusCode());
461460
self::assertJsonStringEqualsJsonString($content, $response->getContent());
462461
}
462+
463+
public function testMapUploadedFileWithMultipleFiles()
464+
{
465+
$client = self::createClient(['test_case' => 'ApiAttributesTest']);
466+
467+
$client->request(
468+
'POST',
469+
'/map-uploaded-file-with-multiple',
470+
[],
471+
[
472+
'files' => [
473+
new UploadedFile(__DIR__.'/Fixtures/file-small.txt', 'file-small.txt', 'text/plain'),
474+
new UploadedFile(__DIR__.'/Fixtures/file-big.txt', 'file-small.txt', 'text/plain'),
475+
],
476+
],
477+
['HTTP_CONTENT_TYPE' => 'multipart/form-data'],
478+
);
479+
$response = $client->getResponse();
480+
481+
self::assertTrue($response->isSuccessful());
482+
self::assertJsonStringEqualsJsonString(
483+
json_encode([2, UploadedFile::class, UploadedFile::class], \JSON_THROW_ON_ERROR),
484+
$response->getContent()
485+
);
486+
}
463487
}
464488

465489
class WithMapQueryStringController
@@ -516,10 +540,15 @@ public function nullable(#[MapUploadedFile] ?UploadedFile $file): Response
516540
return new Response($file?->getContent());
517541
}
518542

519-
public function withConstraints(#[MapUploadedFile(constraints: new File(maxSize: 50))] ?UploadedFile $file): Response
543+
public function withConstraints(#[MapUploadedFile(constraints: new Assert\File(maxSize: 50))] ?UploadedFile $file): Response
520544
{
521545
return new Response($file->getContent());
522546
}
547+
548+
public function withMultipleFiles(#[MapUploadedFile(constraints: new Assert\All([new Assert\File(maxSize: 100)]))] ?array $files): JsonResponse
549+
{
550+
return new JsonResponse([count($files), \get_class($files[0]), \get_class($files[1])]);
551+
}
523552
}
524553

525554
class QueryString

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ApiAttributesTest/routing.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ map_uploaded_file_nullable:
2121
map_uploaded_file_constraints:
2222
path: /map-uploaded-file-with-constraints
2323
controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\WithMapUploadedFileController::withConstraints
24+
25+
map_uploaded_file_multiple:
26+
path: /map-uploaded-file-with-multiple
27+
controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\WithMapUploadedFileController::withMultipleFiles

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

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
6666
continue;
6767
}
6868

69-
if (!$type = $argument->getType()) {
69+
if (!$argument->getType()) {
7070
throw new \LogicException(sprintf('Could not resolve the "$%s" controller argument: argument should be typed.', $argument->getName()));
7171
}
7272

7373
try {
74-
$payload = $this->$payloadMapper($request, $type, $attributes[0], $argument);
74+
$payload = $this->$payloadMapper($request, $argument, $attributes[0]);
7575
} catch (PartialDenormalizationException $e) {
7676
throw new HttpException($validationFailedCode, implode("\n", array_map(static fn (NotNormalizableValueException $e) => $e->getMessage(), $e->getErrors())), $e);
7777
}
@@ -89,19 +89,19 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
8989
return [];
9090
}
9191

92-
private function mapQueryString(Request $request, string $type, MapQueryString $attribute): ?object
92+
private function mapQueryString(Request $request, ArgumentMetadata $argument, MapQueryString $attribute): ?object
9393
{
9494
if (!$data = $request->query->all()) {
9595
return null;
9696
}
9797

98-
return $this->serializer->denormalize($data, $type, self::DEFAULT_FORMAT, self::CONTEXT_DENORMALIZE + $attribute->context);
98+
return $this->serializer->denormalize($data, $argument->getType(), self::DEFAULT_FORMAT, self::CONTEXT_DENORMALIZE + $attribute->context);
9999
}
100100

101-
private function mapRequestPayload(Request $request, string $type, MapRequestPayload $attribute): ?object
101+
private function mapRequestPayload(Request $request, ArgumentMetadata $argument, MapRequestPayload $attribute): ?object
102102
{
103103
if ($data = $request->request->all()) {
104-
return $this->serializer->denormalize($data, $type, self::DEFAULT_FORMAT, self::CONTEXT_DENORMALIZE + $attribute->context);
104+
return $this->serializer->denormalize($data, $argument->getType(), self::DEFAULT_FORMAT, self::CONTEXT_DENORMALIZE + $attribute->context);
105105
}
106106

107107
if ('' === $data = $request->getContent()) {
@@ -111,24 +111,21 @@ private function mapRequestPayload(Request $request, string $type, MapRequestPay
111111
$format = $request->getRequestFormat(self::DEFAULT_FORMAT);
112112

113113
try {
114-
return $this->serializer->deserialize($data, $type, $format, self::CONTEXT_DESERIALIZE + $attribute->context);
114+
return $this->serializer->deserialize($data, $argument->getType(), $format, self::CONTEXT_DESERIALIZE + $attribute->context);
115115
} catch (UnsupportedFormatException $e) {
116116
throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, sprintf('Unsupported format: "%s".', $format), $e);
117117
} catch (NotEncodableValueException $e) {
118118
throw new HttpException(Response::HTTP_BAD_REQUEST, sprintf('Request payload contains not valid "%s".', $format), $e);
119119
}
120120
}
121121

122-
private function mapUploadedFile(Request $request, string $type, MapUploadedFile $attribute, ArgumentMetadata $argument): ?UploadedFile
122+
private function mapUploadedFile(Request $request, ArgumentMetadata $argument, MapUploadedFile $attribute): UploadedFile|array|null
123123
{
124-
if (UploadedFile::class !== $type) {
125-
throw new \InvalidArgumentException(sprintf('Unexpected type "%s". Expected "%s".', $type, UploadedFile::class));
126-
}
127-
128124
$name = $attribute->name ?? $argument->getName();
129125
$file = $request->files->get($name);
130-
if (!$file instanceof UploadedFile) {
131-
return null;
126+
$type = get_debug_type($file);
127+
if ($type !== $argument->getType() && !('null' === $type && $argument->isNullable())) {
128+
throw new \InvalidArgumentException(sprintf('Unexpected type "%s". Expected "%s".', $type, $argument->getType()));
132129
}
133130

134131
return $file;

0 commit comments

Comments
 (0)
0