vichuploader avec symfony et docker

Petit tuto pour installer le bundle vich/uploader-bunder qui permet d’ajouter la gestion d’upload de fichier dans un projet symfony 5.

Nous ajoutons la notion d’image à l’entité nommée « person », notons que dans le cas ci-dessous, notre projet tourne avec des containers docker : ngnix, php, mysql.

Installation du bundle

N’oubliez surtout pas de vous positionner dans le container php pour ne pas interférer avec la version php de votre système local.

$ docker exec -it arbre_php sh

Une fois dans le container vous pouvez procéder à l’installation du bundle via composer.

# composer require vich/uploader-bundle

Paramétrage du bundle

Ajouter le fichier vich_uploader.yaml dans /config/packages

vich_uploader:
  db_driver: orm
  mappings:
    person_images:
      uri_prefix:         '%app.path.person_images%'
      upload_destination: '%kernel.project_dir%/public%app.path.person_images%'

Dans le fichier services.yaml on ajoute le paramètre suivant :

parameters:
    app.path.person_images: /uploads/images/person

Votre entité

Dans l’entité « person », on injecte les dépendances et on ajoute l’annotation

use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
 * @ORM\Entity
 * @Vich\Uploadable
 */

Ajout des getter et setter (accesseurs)
/**
     * @ORM\Column(type="string", length=255)
     * @var string
     */
    private $image;

    /**
     * @Vich\UploadableField(mapping="product_images", fileNameProperty="image")
     * @var File
     */
    private $imageFile;

    /**
     * @ORM\Column(type="datetime")
     * @var \DateTime
     */
    private $updatedAt;

    // ...

    public function setImageFile(File $image = null)
    {
        $this->imageFile = $image;

        // VERY IMPORTANT:
        // 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
        if ($image) {
            // if 'updatedAt' is not defined in your entity, use another property
            $this->updatedAt = new \DateTime('now');
        }
    }

    public function getImageFile()
    {
        return $this->imageFile;
    }

    public function setImage($image)
    {
        $this->image = $image;
    }

    public function getImage()
    {
        return $this->image;
    }

Premières erreurs rencontrées !

Je tente juste l’accès au front :

ERREUR : There is no extension able to load the configuration for « vich_uploader »

Dans config/bunddle.yaml, il faut ajouter

Vich\UploaderBundle\VichUploaderBundle :: class => [‘all’ => true],

make:migration doctrine:migration:migrate

ERREUR : Invalid datetime format: 1292 Incorrect datetime value: ‘0000-00-00 00:00:00’ for column ‘updated_at’ at row 1

Migration xxx failed during Execution. Error An exception occurred while executing ‘ALTER TABLE person ADD image VARCHAR(255) NOT NULL, ADD updated_at DATETIME NOT NULL’:

SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: ‘0000-00-00 00:00:00’ for column ‘updated_at’ at row 1

Il manque une valeur par défaut ! Pour corriger le problème, dans les annotations de la propriété, on accepte la valeur nul.

", nullable=true"

La migration passe mieux 😉

Ajout du champ dans votre formulaire

->add('imageFile', VichImageType::class)

Ajout de l’image dans le template TWIG

<img src="{{ vich_uploader_asset(person, 'imageFile') }}" width="50px">

Si vous faites une erreur dans l’appel vous aurez l’erreur suivante :
An exception has been thrown during the rendering of a template (« Impossible to determine the class name. Either specify it explicitly or give an object »).

PrestaShop

Prestashop

Platinium partner

Shoppingfeed

Partner

Google

Premier Partner

Google Suite

Partner

Office 365

Partner

Recherche