Reputation: 952
I am trying to set up uploading to an API Platform server using this documentation:
https://api-platform.com/docs/core/file-upload/
However, following all of these steps gives me an error when trying to upload using curl.
curl -k -X POST -H "Content-Type: multipart/form-data" -F "file=@/XXXXX/something.png" https://localhost/media_objects
{
"@context":"/contexts/Error",
"@type":"hydra:Error",
"hydra:title":"An error occurred",
"hydra:description":"The class \u0022App\Entity\MediaObject\u0022 is not uploadable. If you use attributes to configure VichUploaderBundle, you probably just forgot to add #[Vich\\Uploadable] on top of your entity. If you don\u0027t use attributes, check that the configuration files are in the right place. In both cases, clearing the cache can also solve the issue."
}
......
The important part:
The class \u0022App\Entity\MediaObject\u0022 is not uploadable. If you use attributes to configure VichUploaderBundle, you probably just forgot to add #[Vich\Uploadable] on top of your entity. If you don\u0027t use attributes, check that the configuration files are in the right place. In both cases, clearing the cache can also solve the issue.
My code was pulled fully from API Platform's example:
<?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 ApiPlatform\OpenApi\Model;
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;
#[Vich\Uploadable]
#[ORM\Entity]
#[ApiResource(
normalizationContext: ['groups' => ['media_object:read']],
types: ['https://schema.org/MediaObject'],
operations: [
new Get(),
new GetCollection(),
new Post(
controller: CreateMediaObjectAction::class,
deserialize: false,
validationContext: ['groups' => ['Default', 'media_object_create']],
openapi: new Model\Operation(
requestBody: new Model\RequestBody(
content: new \ArrayObject([
'multipart/form-data' => [
'schema' => [
'type' => 'object',
'properties' => [
'file' => [
'type' => 'string',
'format' => 'binary'
]
]
]
]
])
)
)
)
]
)]
class MediaObject
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
private ?int $id = null;
#[ApiProperty(types: ['https://schema.org/contentUrl'])]
#[Groups(['media_object:read'])]
public ?string $contentUrl = null;
#[Vich\UploadableField(mapping: "media_object", fileNameProperty: "filePath")]
#[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;
}
}
And as you can clearly see we have the proper attribute and include:
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[Vich\Uploadable]
and our VICH yaml config is set to use attributes:
vich_uploader:
db_driver: orm
metadata:
type: attribute
mappings:
media_object:
uri_prefix: /media
upload_destination: '%kernel.project_dir%/public/media'
# Will rename uploaded files using a uniqueid as a prefix.
namer: Vich\UploaderBundle\Naming\OrignameNamer
So why am I getting the error? How do I fix this?
Upvotes: 0
Views: 645
Reputation: 1201
I solved it by explicitly setting the metadata type to attributes.
vich_uploader:
metadata:
type: attribute
Upvotes: 0
Reputation: 952
There is a gotcha for VICH Bundle and Doctrine 2.8+
Doctrine/annotations package required when using doctrine-bundle >= 2.8 If your project is using doctrine-bundle:>=2.8, you must require doctrine/annotations package from your project as it is not required in doctrine-bundle anymore from this version. This bundle is using a Reader interface from this package in order to work for both annotations and attributes mapping.
So in my case the solution was simply including the doctrine-annotations
bundle in my docker api platform implementation:
docker compose exec php composer require doctrine/annotations
Upvotes: 0