api-platform / docs

API Platform documentation
https://api-platform.com/docs/
165 stars 1.08k forks source link

Update file-upload.md to support VichUploaderBundle's PHP 8 attributes #1512

Open Syndesi opened 2 years ago

Syndesi commented 2 years ago

Hi,

VichUploaderBundle now supports PHP 8 attributes as well, therefore the documentation on uploading files can be updated. Although I'm not sure if the old way via annotations should be kept.

The following steps are required to get it working:

# api/config/packages/vich_uploader.yaml
vich_uploader:

    # new, see also https://github.com/dustin10/VichUploaderBundle/issues/1272#issuecomment-1047613035
    metadata:
        type: attribute
<?php
// api/src/Entity/MediaObject.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use App\Controller\CreateMediaObjectAction;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * @ORM\Entity
 * #@Vich\Uploadable // old way ----------------------------------------------------------------------------
 */
#[Vich\Uploadable]   // new way ----------------------------------------------------------------------------
#[ApiResource(
    normalizationContext: ['groups' => ['media_object:read']], 
    types: ['http://schema.org/MediaObject']
)]
#[Get]
#[GetCollection]
#[Post(
    controller: CreateMediaObjectAction::class, 
    deserialize: false, 
    validationContext: ['groups' => ['Default', 'media_object_create']], 
    openapiContext: [
        'requestBody' => [
            'content' => [
                'multipart/form-data' => [
                    'schema' => [
                        'type' => 'object', 
                        'properties' => [
                            'file' => [
                                'type' => 'string', 
                                'format' => 'binary'
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
)]
class MediaObject
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     * @ORM\Id
     */
    private ?int $id = null;

    #[ApiProperty(types: ['http://schema.org/contentUrl'])]
    #[Groups(['media_object:read'])]
    public ?string $contentUrl = null;

    /**
     * #@Vich\UploadableField(mapping="media_object", fileNameProperty="filePath")  // old way ----------
     */
    #[Vich\UploadableField(mapping:"media_object", fileNameProperty:"filePath")]    // new way ----------
    #[Assert\NotNull(groups: ['media_object_create'])]
    public ?File $file = null;

    /**
     * @ORM\Column(nullable=true)
     */
    public ?string $filePath = null;

    public function getId(): ?int
    {
        return $this->id;
    }
}

Furthermore, the Doctrine annotations could be updated as well. Should I create a new PR?

alanpoulain commented 2 years ago

Hello, Yes you can do it on the 2.6 branch.