2424use Symfony \Component \Serializer \Exception \UnsupportedFormatException ;
2525use Symfony \Component \Serializer \Normalizer \DenormalizerInterface ;
2626use Symfony \Component \Serializer \SerializerInterface ;
27+ use Symfony \Component \Translation \IdentityTranslator ;
28+ use Symfony \Component \Validator \ConstraintViolation ;
2729use Symfony \Component \Validator \ConstraintViolationInterface ;
30+ use Symfony \Component \Validator \ConstraintViolationList ;
2831use Symfony \Component \Validator \Exception \ValidationFailedException ;
2932use Symfony \Component \Validator \Validator \ValidatorInterface ;
33+ use Symfony \Contracts \Translation \TranslatorInterface ;
3034
3135/**
3236 * @author Konstantin Myakshin <molodchick@gmail.com>
@@ -51,7 +55,8 @@ final class RequestPayloadValueResolver implements ValueResolverInterface
5155
5256public function __construct (
5357private readonly SerializerInterface &DenormalizerInterface $ serializer ,
54- private readonly ?ValidatorInterface $ validator ,
58+ private readonly ?ValidatorInterface $ validator =null ,
59+ private readonly ?TranslatorInterface $ translator =null ,
5560 ) {
5661 }
5762
@@ -71,14 +76,37 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
7176throw new \LogicException (sprintf ('Could not resolve the "$%s" controller argument: argument should be typed. ' ,$ argument ->getName ()));
7277 }
7378
74- try {
75- $ payload =$ this ->$ payloadMapper ($ request ,$ type ,$ attributes [0 ]);
76- }catch (PartialDenormalizationException $ e ) {
77- throw new HttpException ($ validationFailedCode ,implode ("\n" ,array_map (static fn (NotNormalizableValueException $ e ) =>$ e ->getMessage (),$ e ->getErrors ())),$ e );
78- }
79-
80- if (null !==$ payload &&\count ($ violations =$ this ->validator ?->validate($ payload ) ?? [])) {
81- throw new HttpException ($ validationFailedCode ,implode ("\n" ,array_map (static fn (ConstraintViolationInterface $ e ) =>$ e ->getMessage (),iterator_to_array ($ violations ))),new ValidationFailedException ($ payload ,$ violations ));
79+ if ($ this ->validator ) {
80+ $ violations =new ConstraintViolationList ();
81+ try {
82+ $ payload =$ this ->$ payloadMapper ($ request ,$ type ,$ attributes [0 ]);
83+ }catch (PartialDenormalizationException $ e ) {
84+ $ trans =$ this ->translator ?$ this ->translator ->trans (...) :fn ($ m ,$ p ) =>strtr ($ m ,$ p );
85+ foreach ($ e ->getErrors ()as $ error ) {
86+ $ parameters = ['{{ type }} ' =>implode ('| ' ,$ error ->getExpectedTypes ())];
87+ if ($ error ->canUseMessageForUser ()) {
88+ $ parameters ['hint ' ] =$ error ->getMessage ();
89+ }
90+ $ template ='This value should be of type {{ type }}. ' ;
91+ $ message =$ trans ($ template ,$ parameters ,'validators ' );
92+ $ violations ->add (new ConstraintViolation ($ message ,$ template ,$ parameters ,null ,$ error ->getPath (),null ));
93+ }
94+ $ payload =$ e ->getData ();
95+ }
96+
97+ if (null !==$ payload ) {
98+ $ violations ->addAll ($ this ->validator ->validate ($ payload ));
99+ }
100+
101+ if (\count ($ violations )) {
102+ throw new HttpException ($ validationFailedCode ,implode ("\n" ,array_map (static fn ($ e ) =>$ e ->getMessage (),iterator_to_array ($ violations ))),new ValidationFailedException ($ payload ,$ violations ));
103+ }
104+ }else {
105+ try {
106+ $ payload =$ this ->$ payloadMapper ($ request ,$ type ,$ attributes [0 ]);
107+ }catch (PartialDenormalizationException $ e ) {
108+ throw new HttpException ($ validationFailedCode ,implode ("\n" ,array_map (static fn ($ e ) =>$ e ->getMessage (),$ e ->getErrors ())),$ e );
109+ }
82110 }
83111
84112if (null !==$ payload ||$ argument ->isNullable ()) {