<?php
declare(strict_types=1);
namespace App\Serializer;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
final class UploadedFileDenormalizer implements DenormalizerInterface
{
public function denormalize($data, string $type, string $format = null, array $context = []): File
{
return $data;
}
public function supportsDenormalization($data, $type, $format = null, array $context = []): bool
{
return $data instanceof File;
}
public function getSupportedTypes(?string $format): array
{
return [
File::class => true,
];
}
}
<?php
declare(strict_types = 1);
namespace App\Encoder;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Serializer\Encoder\DecoderInterface;
final class MultipartDecoder implements DecoderInterface
{
public const FORMAT = 'multipart';
public function __construct(private readonly RequestStack $requestStack)
{
}
public function decode(string $data, string $format, array $context = []): ?array
{
$request = $this->requestStack->getCurrentRequest();
if (!$request) {
return null;
}
return array_map(static function (string $element) {
// Multipart form values will be encoded in JSON.
return json_decode($element, true, flags: \JSON_THROW_ON_ERROR);
}, $request->request->all()) + $request->files->all();
}
public function supportsDecoding(string $format): bool
{
return self::FORMAT === $format;
}
}
<?php
namespace App\State;
use App\Entity\Parameter;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use ApiPlatform\Doctrine\Common\State\PersistProcessor;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ParameterStateProcessor implements ProcessorInterface
{
public function __construct(
private PersistProcessor $persistProcessor,
private ParameterBagInterface $parameterBag
)
{
}
public function process(mixed $parameter, Operation $operation, array $uriVariables = [], array $context = []): void
{
if ($operation instanceof Post) {
$this->uploadFile($parameter);
}
$this->persistProcessor->process($parameter, $operation, $uriVariables, $context);
}
private function uploadFile(Parameter $parameter): void
{
/** @var UploadedFile $file */
$file = $parameter->file;
dump($file);
if ($file) {
$filename = sprintF('favicon.%s', $file->guessExtension());
$directories = [$this->parameterBag->get('project_directory'), 'public', 'uploads'];
dump(get_current_user());
$debug = $file->move(implode(DIRECTORY_SEPARATOR, $directories), $filename);
$parameter->setValue($filename);
dump($parameter, $debug);
}
}
}