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 »).