@@ -394,10 +394,15 @@ We need to create our own decoder to do it:
394394<?php
395395// api/src/Encoder/MultipartDecoder.php
396396
397+ declare(strict_types=1);
398+
397399namespace App\Encoder;
398400
401+ use Doctrine\Common\Collections\Collection;
399402use Symfony\Component\HttpFoundation\RequestStack;
400403use Symfony\Component\Serializer\Encoder\DecoderInterface;
404+ use ReflectionClass;
405+ use ReflectionNamedType;
401406
402407final class MultipartDecoder implements DecoderInterface
403408{
@@ -411,23 +416,77 @@ final class MultipartDecoder implements DecoderInterface
411416 {
412417 $request = $this->requestStack->getCurrentRequest();
413418
414- if (!$request) {
419+ if (!$request || !isset($context['resource_class']) ) {
415420 return null;
416421 }
417422
418- return array_map(static function (string $element) {
423+ // Retrieve the target class from the context
424+ $targetClass = $context['resource_class'];
425+
426+ // Get the expected types for the target entity
427+ $expectedTypes = $this->getPropertyTypes($targetClass);
428+
429+ $arrayMapWithKeys = function (callable $callback, array $array) {
430+ $result = [];
431+
432+ foreach ($array as $key => $value) {
433+ $result[$key] = $callback($value, $key);
434+ }
435+
436+ return $result;
437+ };
438+
439+ $map = $arrayMapWithKeys(static function (string $element, string $key) use ($expectedTypes) {
419440 // Multipart form values will be encoded in JSON.
420441 $decoded = json_decode($element, true);
421442
422- return \is_array($decoded) ? $decoded : $element;
423- }, $request->request->all()) + $request->files->all();
443+ if (is_array($decoded)) {
444+ return $decoded;
445+ }
446+
447+ if ('null' == $element) {
448+ return null;
449+ }
450+
451+ if (!isset($expectedTypes[$key])) {
452+ return $element;
453+ }
454+
455+ return match ($expectedTypes[$key]) {
456+ 'bool' => filter_var($element, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE),
457+ 'int' => is_numeric($element) ? (int) $element : $element,
458+ 'float' => is_numeric($element) ? (float) $element : $element,
459+ Collection::class => !is_array($element) ? [] : $element,
460+ default => $element,
461+ };
462+ }, $request->request->all());
463+
464+ // dd($map + $request->files->all());
465+
466+ return $map + $request->files->all();
424467 }
425468
426469 public function supportsDecoding(string $format): bool
427470 {
428471 return self::FORMAT === $format;
429472 }
473+
474+ private function getPropertyTypes(string $className): array
475+ {
476+ $reflectionClass = new ReflectionClass($className);
477+ $types = [];
478+
479+ foreach ($reflectionClass->getProperties() as $property) {
480+ $type = $property->getType();
481+ if ($type instanceof ReflectionNamedType) {
482+ $types[$property->getName()] = $type->getName();
483+ }
484+ }
485+
486+ return $types;
487+ }
430488}
489+
431490```
432491
433492If you're not using ` autowiring ` and ` autoconfiguring ` , don't forget to register the service and tag it as ` serializer.encoder ` .
0 commit comments