@@ -169,43 +169,53 @@ A [normalizer](serialization.md#normalization) could be used to set the `content
169169
170170` ` ` php
171171<?php
172- // api/src/Serializer/MediaObjectNormalizer.php
173172
174173namespace App\S erializer;
175174
176175use App\E ntity\M ediaObject;
177- use Symfony\C omponent\S erializer\N ormalizer\N ormalizerAwareInterface;
178- use Symfony\C omponent\S erializer\N ormalizer\N ormalizerAwareTrait;
179176use Vich\UploaderB undle\S torage\S torageInterface;
177+ use Symfony\C omponent\D ependencyInjection\A ttribute\A utowire;
178+ use Symfony\C omponent\S erializer\N ormalizer\N ormalizerInterface;
180179
181- final class MediaObjectNormalizer implements NormalizerAwareInterface
180+ class MediaObjectNormalizer implements NormalizerInterface
182181{
183- use NormalizerAwareTrait;
184182
185- private const ALREADY_CALLED = 'MEDIA_OBJECT_NORMALIZER_ALREADY_CALLED';
183+ private const ALREADY_CALLED = 'MEDIA_OBJECT_NORMALIZER_ALREADY_CALLED';
186184
187- public function __construct(private StorageInterface $storage)
188- {
189- }
185+ public function __construct(
186+ #[Autowire(service: 'serializer.normalizer.object')]
187+ private readonly NormalizerInterface $normalizer,
188+ private readonly StorageInterface $storage
189+ ) {
190+ }
190191
191- public function normalize($object, ?string $format = null, array $context = []): array|string|int|float|bool|\A rrayObject|null
192- {
193- $context[self::ALREADY_CALLED] = true;
192+ public function normalize($object, ?string $format = null, array $context = []): array|string|int|float|bool|\A rrayObject|null
193+ {
194+ $context[self::ALREADY_CALLED] = true;
194195
195- $object->contentUrl = $this->storage->resolveUri($object, 'file');
196+ $object->contentUrl = $this->storage->resolveUri($object, 'file');
196197
197- return $this->normalizer->normalize($object, $format, $context);
198- }
198+ return $this->normalizer->normalize($object, $format, $context);
199+ }
199200
200- public function supportsNormalization($data, ?string $format = null, array $context = []): bool
201- {
202- if (isset($context[self::ALREADY_CALLED])) {
203- return false;
204- }
201+ public function supportsNormalization($data, ?string $format = null, array $context = []): bool
202+ {
205203
206- return $data instanceof MediaObject;
204+ if (isset($context[self::ALREADY_CALLED])) {
205+ return false;
207206 }
207+
208+ return $data instanceof MediaObject;
209+ }
210+
211+ public function getSupportedTypes(?string $format): array
212+ {
213+ return [
214+ MediaObject::class => true,
215+ ];
216+ }
208217}
218+
209219` ` `
210220
211221# ## Making a Request to the `/media_objects` Endpoint
@@ -234,8 +244,8 @@ You will need to modify your `Caddyfile` to allow the above `contentUrl` to be a
234244 @pwa expression ` (
235245 header({'Accept': '*text/html*'})
236246 && !path(
237- - ' /docs*' , '/graphql*', '/bundles*', '/media*', '/ contexts*', '/_profiler*', '/_wdt*',
238- + '/media*', '/docs*', '/graphql*', '/bundles*', '/media*', '/ contexts*', '/_profiler*', '/_wdt*',
247+ - ' /docs*' , '/graphql*', '/bundles*', '/contexts*', '/_profiler*', '/_wdt*',
248+ + '/media*', '/docs*', '/graphql*', '/bundles*', '/contexts*', '/_profiler*', '/_wdt*',
239249 ' *.json*' , '*.html', '*.csv', '*.yml', '*.yaml', '*.xml'
240250 )
241251 )
@@ -313,25 +323,26 @@ class MediaObjectTest extends ApiTestCase
313323
314324 public function testCreateAMediaObject(): void
315325 {
316- $file = new UploadedFile('fixtures/files/image.png', 'image.png');
326+ // The file "image.jpg" is the folder fixtures which is in the project dir
327+ $file = new UploadedFile(__DIR__ . '/../fixtures/image.jpg', 'image.jpg');
317328 $client = self::createClient();
318329
319- $client->request('POST', '/media_objects', [
320- 'headers' => ['Content-Type' => 'multipart/form-data'],
321- 'extra' => [
322- // If you have additional fields in your MediaObject entity, use the parameters.
323- 'parameters' => [
324- 'title' => 'My file uploaded',
325- ],
326- 'files' => [
327- 'file' => $file,
328- ],
329- ]
330+ $client->request('POST', 'http://localhost:8888/api /media_objects', [
331+ 'headers' => ['Content-Type' => 'multipart/form-data'],
332+ 'extra' => [
333+ // If you have additional fields in your MediaObject entity, use the parameters.
334+ 'parameters' => [
335+ // 'title' => 'title'
336+ ],
337+ 'files' => [
338+ 'file' => $file,
339+ ],
340+ ]
330341 ]);
331342 $this->assertResponseIsSuccessful();
332343 $this->assertMatchesResourceItemJsonSchema(MediaObject::class);
333344 $this->assertJsonContains([
334- 'title' => 'My file uploaded',
345+ // 'title' => 'My file uploaded',
335346 ]);
336347 }
337348}
@@ -451,19 +462,28 @@ We also need to make sure the field containing the uploaded file is not denormal
451462
452463namespace App\Serializer;
453464
454- use Symfony\Component\HttpFoundation\File\UploadedFile ;
465+ use Symfony\Component\HttpFoundation\File\File ;
455466use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
456467
457468final class UploadedFileDenormalizer implements DenormalizerInterface
458469{
459- public function denormalize($data, string $type, string $format = null, array $context = []): UploadedFile
470+ public function denormalize($data, string $type, string $format = null, array $context = []): File
460471 {
461472 return $data;
462473 }
463474
464- public function supportsDenormalization($data, $type, $format = null): bool
475+ public function supportsDenormalization($data, $type, $format = null, array $context = []): bool
476+ {
477+ return $data instanceof File;
478+ }
479+
480+ public function getSupportedTypes(?string $format): array
465481 {
466- return $data instanceof UploadedFile;
482+ return [
483+ 'object' => null,
484+ '*' => false,
485+ File::class => true,
486+ ];
467487 }
468488}
469489```
0 commit comments