Bonjour à tous.

Je souhaite avoir des idées quant à l'intégration de VIchUploader Bundle à EasyAdmin 4, car je souhaite uploader des images et des fichiers. J'ai suivi quelques liens sur le net

Création d'un champ de type file

<?php

namespace App\Field;

use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait;
use Vich\UploaderBundle\Form\Type\VichImageType;

class VichFileField implements FieldInterface
{
    use FieldTrait;

    public static function new(string $propertyName, ?string $label = null)
    {
        return (new self())
            ->setProperty($propertyName)
            ->setTemplatePath('')
            ->setLabel($label)
            ->setFormType(VichImageType::class);
    }
}

Controller

<?php

namespace App\Controller\Admin;

use App\Entity\Livre;
use App\Field\VichFileField;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;

class LivreCrudController extends AbstractCrudController
{
    public static function getEntityFqcn(): string
    {
        return Livre::class;
    }

    public function configureFields(string $pageName): iterable
    {
        return [
            TextField::new('titre'),
            TextField::new('livreName')->hideOnForm(),
            TextareaField::new('description'),
            AssociationField::new('langue')->setCrudController(LivreCrudController::class)->renderAsNativeWidget(),
            VichFileField::new('livreFile')->onlyOnForms(),
            // TextareaField::new('livreFile')->setFormType(VichFileType::class)->onlyOnForms(),
        ];
    }
}

Mon entité livre:

<?php

namespace App\Entity;

use App\Repository\LivreRepository;
use App\Trait\addFilesCDUTrait;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\HttpFoundation\File\File;

#[Vich\Uploadable]
#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false, hardDelete: true)]
#[ORM\Entity(repositoryClass: LivreRepository::class)]
class Livre
{
    use addFilesCDUTrait;

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column()]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private ?string $titre = null;

    #[Vich\UploadableField(mapping: 'livre_file', fileNameProperty: 'livreName', size: 'livreSize')]
    private ?File $livreFile = null;

    #[ORM\Column(type: 'string', nullable: true)]
    private ?string $livreName = null;

    #[ORM\Column(type: 'integer', nullable: true)]
    private ?int $livreSize = null;

    #[Vich\UploadableField(mapping: 'couverture_livre_file', fileNameProperty: 'couvertureName', size: 'couvertureSize')]
    private ?File $couvertureFile = null;

    #[ORM\Column(type: 'string', nullable: true)]
    private ?string $couvertureName = null;

    #[ORM\ManyToOne(inversedBy: 'livres')]
    private ?Langue $langue = null;

    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $description = null;

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

    public function getTitre(): ?string
    {
        return $this->titre;
    }

    public function setTitre(string $titre): self
    {
        $this->titre = $titre;

        return $this;
    }

    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile|null $livreFile
     */
    public function setLivreFile(?File $livreFile = null): void
    {
        $this->livreFile = $livreFile;

        if (null !== $livreFile) {
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->updatedAt = new \DateTime();
        }
    }

    public function getLivreFile(): ?File
    {
        return $this->livreFile;
    }

    public function setLivreName(?string $livreName): void
    {
        $this->livreName = $livreName;
    }

    public function getLivreName(): ?string
    {
        return $this->livreName;
    }

    public function setLivreSize(?int $livreSize): void
    {
        $this->livreSize = $livreSize;
    }

    public function getLivreSize(): ?int
    {
        return $this->livreSize;
    }

Apres tout ceci, j'obtiens cette erreur:

The class "App\Entity\Livre" 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't use attributes, check that the configuration files are in the right place. In both cases, clearing the cache can also solve the issue.

Alors que j'ai bien #[Vich\Uploadable] dans mon entité livre et j'ai vider le cache aussi.

Pouvez-vous me donner des pistes de résolution ?

Merci d'avance.

1 réponse


youstra
Auteur
Réponse acceptée

J'ai trouvé la réponse ici: https://stackoverflow.com/questions/71695459/vichuploaderbundle-in-symfony-6.
Il fallait simplement ajouter

vich_uploader:
    metadata:
        type: attribute