Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdc068fb

Browse files
Renerenedelima
Rene
authored andcommitted
[HttpKernel] Add MapUploadedFile attribute
1 parent9549cc2 commitdc068fb

File tree

6 files changed

+406
-9
lines changed

6 files changed

+406
-9
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\HttpKernel\Attribute;
13+
14+
useSymfony\Component\HttpFoundation\Response;
15+
useSymfony\Component\HttpKernel\Controller\ArgumentResolver\RequestPayloadValueResolver;
16+
useSymfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
17+
useSymfony\Component\Validator\Constraint;
18+
19+
#[\Attribute(\Attribute::TARGET_PARAMETER)]
20+
class MapUploadedFileextends ValueResolver
21+
{
22+
publicArgumentMetadata$metadata;
23+
24+
publicfunction__construct(
25+
/** @var Constraint|array<Constraint>|null */
26+
publicConstraint|array|null$constraints =null,
27+
public ?string$name =null,
28+
string$resolver = RequestPayloadValueResolver::class,
29+
publicreadonlyint$validationFailedStatusCode = Response::HTTP_UNPROCESSABLE_ENTITY,
30+
) {
31+
parent::__construct($resolver);
32+
}
33+
}

‎src/Symfony/Component/HttpKernel/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGELOG
99
* Add`$validationFailedStatusCode` argument to`#[MapQueryParameter]` that allows setting a custom HTTP status code when validation fails
1010
* Add`NearMissValueResolverException` to let value resolvers report when an argument could be under their watch but failed to be resolved
1111
* Add`$type` argument to`#[MapRequestPayload]` that allows mapping a list of items
12+
* Add`#[MapUploadedFile]` attribute to fetch, validate, and inject uploaded files into controller arguments
1213

1314
7.0
1415
---

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

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
namespaceSymfony\Component\HttpKernel\Controller\ArgumentResolver;
1313

1414
useSymfony\Component\EventDispatcher\EventSubscriberInterface;
15+
useSymfony\Component\HttpFoundation\File\UploadedFile;
1516
useSymfony\Component\HttpFoundation\Request;
1617
useSymfony\Component\HttpKernel\Attribute\MapQueryString;
1718
useSymfony\Component\HttpKernel\Attribute\MapRequestPayload;
19+
useSymfony\Component\HttpKernel\Attribute\MapUploadedFile;
1820
useSymfony\Component\HttpKernel\Controller\ValueResolverInterface;
1921
useSymfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
2022
useSymfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
@@ -29,6 +31,7 @@
2931
useSymfony\Component\Serializer\Exception\UnsupportedFormatException;
3032
useSymfony\Component\Serializer\Normalizer\DenormalizerInterface;
3133
useSymfony\Component\Serializer\SerializerInterface;
34+
useSymfony\Component\Validator\ConstraintsasAssert;
3235
useSymfony\Component\Validator\ConstraintViolation;
3336
useSymfony\Component\Validator\ConstraintViolationList;
3437
useSymfony\Component\Validator\Exception\ValidationFailedException;
@@ -69,13 +72,14 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
6972
{
7073
$attribute =$argument->getAttributesOfType(MapQueryString::class, ArgumentMetadata::IS_INSTANCEOF)[0]
7174
??$argument->getAttributesOfType(MapRequestPayload::class, ArgumentMetadata::IS_INSTANCEOF)[0]
75+
??$argument->getAttributesOfType(MapUploadedFile::class, ArgumentMetadata::IS_INSTANCEOF)[0]
7276
??null;
7377

7478
if (!$attribute) {
7579
return [];
7680
}
7781

78-
if ($argument->isVariadic()) {
82+
if (!$attributeinstanceof MapUploadedFile &&$argument->isVariadic()) {
7983
thrownew \LogicException(sprintf('Mapping variadic argument "$%s" is not supported.',$argument->getName()));
8084
}
8185

@@ -105,19 +109,22 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo
105109
}elseif ($argumentinstanceof MapRequestPayload) {
106110
$payloadMapper ='mapRequestPayload';
107111
$validationFailedCode =$argument->validationFailedStatusCode;
112+
}elseif ($argumentinstanceof MapUploadedFile) {
113+
$payloadMapper ='mapUploadedFile';
114+
$validationFailedCode =$argument->validationFailedStatusCode;
108115
}else {
109116
continue;
110117
}
111118
$request =$event->getRequest();
112119

113-
if (!$type =$argument->metadata->getType()) {
120+
if (!$argument->metadata->getType()) {
114121
thrownew \LogicException(sprintf('Could not resolve the "$%s" controller argument: argument should be typed.',$argument->metadata->getName()));
115122
}
116123

117124
if ($this->validator) {
118125
$violations =newConstraintViolationList();
119126
try {
120-
$payload =$this->$payloadMapper($request,$type,$argument);
127+
$payload =$this->$payloadMapper($request,$argument->metadata,$argument);
121128
}catch (PartialDenormalizationException$e) {
122129
$trans =$this->translator ?$this->translator->trans(...) :fn ($m,$p) =>strtr($m,$p);
123130
foreach ($e->getErrors()as$error) {
@@ -137,15 +144,19 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo
137144
}
138145

139146
if (null !==$payload && !\count($violations)) {
140-
$violations->addAll($this->validator->validate($payload,null,$argument->validationGroups ??null));
147+
$constraints =$argument->constraints ??null;
148+
if (\is_array($payload) && !empty($constraints) && !$constraintsinstanceofAssert\All) {
149+
$constraints =newAssert\All($constraints);
150+
}
151+
$violations->addAll($this->validator->validate($payload,$constraints,$argument->validationGroups ??null));
141152
}
142153

143154
if (\count($violations)) {
144155
throw HttpException::fromStatusCode($validationFailedCode,implode("\n",array_map(staticfn ($e) =>$e->getMessage(),iterator_to_array($violations))),newValidationFailedException($payload,$violations));
145156
}
146157
}else {
147158
try {
148-
$payload =$this->$payloadMapper($request,$type,$argument);
159+
$payload =$this->$payloadMapper($request,$argument->metadata,$argument);
149160
}catch (PartialDenormalizationException$e) {
150161
throw HttpException::fromStatusCode($validationFailedCode,implode("\n",array_map(staticfn ($e) =>$e->getMessage(),$e->getErrors())),$e);
151162
}
@@ -172,16 +183,16 @@ public static function getSubscribedEvents(): array
172183
];
173184
}
174185

175-
privatefunctionmapQueryString(Request$request,string$type,MapQueryString$attribute): ?object
186+
privatefunctionmapQueryString(Request$request,ArgumentMetadata$argument,MapQueryString$attribute): ?object
176187
{
177188
if (!$data =$request->query->all()) {
178189
returnnull;
179190
}
180191

181-
return$this->serializer->denormalize($data,$type,null,$attribute->serializationContext +self::CONTEXT_DENORMALIZE + ['filter_bool' =>true]);
192+
return$this->serializer->denormalize($data,$argument->getType(),null,$attribute->serializationContext +self::CONTEXT_DENORMALIZE + ['filter_bool' =>true]);
182193
}
183194

184-
privatefunctionmapRequestPayload(Request$request,string$type,MapRequestPayload$attribute):object|array|null
195+
privatefunctionmapRequestPayload(Request$request,ArgumentMetadata$argument,MapRequestPayload$attribute):object|array|null
185196
{
186197
if (null ===$format =$request->getContentTypeFormat()) {
187198
thrownewUnsupportedMediaTypeHttpException('Unsupported format.');
@@ -191,8 +202,10 @@ private function mapRequestPayload(Request $request, string $type, MapRequestPay
191202
thrownewUnsupportedMediaTypeHttpException(sprintf('Unsupported format, expects "%s", but "%s" given.',implode('", "', (array)$attribute->acceptFormat),$format));
192203
}
193204

194-
if ('array' ===$type &&null !==$attribute->type) {
205+
if ('array' ===$argument->getType() &&null !==$attribute->type) {
195206
$type =$attribute->type.'[]';
207+
}else {
208+
$type =$argument->getType();
196209
}
197210

198211
if ($data =$request->request->all()) {
@@ -217,4 +230,9 @@ private function mapRequestPayload(Request $request, string $type, MapRequestPay
217230
thrownewBadRequestHttpException(sprintf('Request payload contains invalid "%s" property.',$e->property),$e);
218231
}
219232
}
233+
234+
privatefunctionmapUploadedFile(Request$request,ArgumentMetadata$argument,MapUploadedFile$attribute):UploadedFile|array|null
235+
{
236+
return$request->files->get($attribute->name ??$argument->getName(), []);
237+
}
220238
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp