Gérer simplement l'upload avec Symfony

Publié le

Gérer simplement l'upload avec Symfony

1 - Présentation et installation

Pour gérer simplement l'upload d'un fichier et sa persistance en base de données, il n'est pas rare de devoir faire appel à VichUploaderBundle. Son efficacité est à la hauteur de sa popularité. 

Pour l'installer, on n'échappe pas à notre gestionnaire de dépendances favori, composer.

composer require vich/uploader-bundle

On ajoute dans la foulée le bundle à notre Kernel.

// app/AppKernel.php
new Vich\UploaderBundle\VichUploaderBundle(),

On se rend ensuite dans notre fichier de configuration afin de définir nos premières préférences. Nous renseignons ici notre moteur de persistance. Vous pouvez utiliser phpcr, mongo, propel ou doctrine (noté orm ici).

# app/config/config.yml
vich_uploader:
    db_driver: orm

L'installation est terminée.

2 - Configuration

Dans un premier temps, nous allons configurer la destination de notre fichier, le dossier public où la ressource sera accessible et enfin donner un nom à cette méthode d'upload, ici devis.

# app/config/config.yml 
vich_uploader: 
    db_driver: orm 
    mappings: 
        devis: 
            uri_prefix: /devis/ 
            upload_destination: '%kernel.root_dir%/../web/devis/' 
            namer: vich_uploader.namer_uniqid

La dernière ligne que je n'ai pas explicitée sert tout simplement à définir la méthode de nommage des fichiers envoyés sur le serveur. Nous allons nous intéresser à deux méthodes prédéfinies. 

  • vich_uploader.namer_uniqid Renommera votre fichier selon un id unique. example.pdf deviendra 7db4ed789.pdf
  • vich_uploader.namer_origname Renommera votre fichier selon un id unique en conservant son nom d'origine. example.pdf deviendra  7db4ed789_example.pdf

Dans le cas où vous voudriez utiliser votre propre convention de renommage, il existe un paramètre qui utilise une méthode de votre entité.

 namer:
     service: vich_uploader.namer_property
     options: { property: 'personalNamer'}

Dans le cas présent, votre entité devra être composée d'une méthode personalNamer ou getPersonalNamer.

Pour finir, nous allons configurer notre entité pour établir un lien entre le fichier envoyé, c'est là tout l'intérêt du bundle. Pour cela vous pourrez utiliser YML ou XML, mais c'est les annotations qui seront utilisées pour illustrer ce processus. 

Marquez votre entité du tag Uplodable.

/**
 * Devis
 *
 * @ORM\Table(name="devis")
 * @ORM\Entity(repositoryClass="XXX\XXXBundle\Repository\DevisRepository")
 * @Vich\Uploadable
 */

Nous devons ajouter deux champs à notre entité, devisName où sera enregistré le nom du fichier envoyé et devisFile qui contiendra l'objet UploadedFile. Ce dernier ne sera en aucun cas persisté, mais il doit être annoté. 
Si vous ne l'avez pas déjà, il faudra également définir un champ updatedAt.

/**
 * @Vich\UploadableField(mapping="devis", fileNameProperty="devisName")
 * 
 * @var File
 */
private $devisFile;

/**
 * @ORM\Column(type="string", length=255)
 *
 * @var string
 */
private $devisName;

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

Sans oublier les accesseurs.

/**
 * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $devis
 *
 * @return Devis
*/
public function setDevisFile(File $devis = null)
{
    $this->devisFile = $devis;

    if ($devis) 
        $this->updatedAt = new \DateTimeImmutable();
    
    return $this;
}

/**
 * @return File|null
 */
public function getDevisFile()
{
    return $this->devisFile;
}

/**
 * @param string $devisName
 *
 * @return Devis
 */
public function setDevisName($devisName)
{
    $this->devisName = $devisName;

    return $this;
}

/**
 * @return string|null
 */
public function getDevisName()
{
    return $this->devisName;
}

Après avoir modifié notre entité, on peut vider le cache.

php bin/console cache:clear

La configuration est terminée.

3 - Utilisation

Pour ajouter un champ d'upload au formulaire : 

 ->add('devisFile', 'file')

Pour rendre le fichier dans un template :

<a href="{{ vich_uploader_asset(devis, 'devisFile') }}" />Voir mon devis</a>

4 - Conclusion

À travers ce court tutoriel, vous avez découvert une façon de gérer l'envoi et la persistance de fichier grâce à un bundle. Il existe beaucoup de manières de faire et je vous invite à les découvrir, les comparer et faire votre choix. Vous vous êtes sûrement rendu compte que cet article n'est qu'un résumé de la documentation de vichuploader. Vous pouvez la consulter afin de découvrir des paramètres de configuration supplémentaire et en apprendre plus sur ce bundle.