Upload de fichier +upload drag & drop Jquery

Ce développement permet d’uploader facilement des fichiers en utilisant une class PHP maison.

Une option non obligatoire permet de coupler ce système d’upload avec un système de drag & drop Jquery.

Pré-requis

  • Avoir dans le dossier /src/Outil/ la class Url.php permettant la création de slug
  • Avoir à disposition la version 3.6.0 ou + de la bibliothèque Jquery

Class PHP

Dans le dossier /src/Outil/ créer un fichier Upload.php et y placer le code ci-dessous.

<?php
/**
 * Created by PhpStorm.
 * User: Graffagnino David
 * Société : DGWWW - https://dgwww.fr
 * Date: 21/06/2022
 * Time: 08:38
 */

namespace App\Outil;

/**
 * https://www.w3schools.com/php/php_file_upload.asp
 * https://developer.mozilla.org/fr/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
 */
class Upload
{
    /**
     * @var bool
     */
    private $_etat = true;

    /**
     * @var string
     */
    private $_message_erreur = "";

    /**
     * @var string
     */
    private $_extention = "";

    /**
     * @var string
     */
    private $_fichier_uploader = "";

    /**
     * Upload d'un fichier
     * @param $fichier
     * @param $params
     */
    public function __construct($fichier, $params){
        /*
         * Verrification
         */
        $this->_verrification($fichier, $params);

        /*
         * Upload
         */
        if($this->_etat == true) {
            $this->_fichier_uploader = trim($params["nom_fichier"]) . "." . $this->_extention;

            move_uploaded_file($fichier["tmp_name"], trim($params["chemin_upload"]) . "/" . $this->_fichier_uploader);
        }
    }

    /**
     * Retourne l'état de l'upload
     * @return bool
     */
    public function etat(){
        return $this->_etat;
    }

    /**
     * Retourne le message d'erreur de l'upload
     * @return string
     */
    public function message_erreur(){
        return $this->_message_erreur;
    }

    /**
     * Retourne le nom du fichier uploadé
     * @return string
     */
    public function fichier_uploader(){
        return $this->_fichier_uploader;
    }

    /**
     * Verrification des parramètres nécessaire à l'upload
     * @param $fichier
     * @param $params
     * @return void
     */
    private function _verrification($fichier, $params){

        //  Fichier
        if($fichier == null){

            $this->_etat = false;
            $this->_message_erreur = "La variable <b>fichier</b> est manquante";

        }else {

            //  Nom
            if (isset($params["nom_fichier"]) == false || trim($params["nom_fichier"]) == "") {
                $this->_etat = false;
                $this->_message_erreur = "Le paramètre <b>nom_fichier</b> est manquant";
            }

            //  Chemin
            if (isset($params["chemin_upload"]) == false || trim($params["chemin_upload"]) == "") {
                $this->_etat = false;
                $this->_message_erreur .= "<br />Le paramètre <b>chemin_upload</b> est manquant";
            }

            //  Type upload authorisé
            if (isset($params["type_upload"]) == false) {
                $this->_etat = false;
                $this->_message_erreur .= "<br />Le paramètre <b>type_upload</b> est manquant";
            } else {
                $extention_valide = false;

                $nom_fichier_temporaire = basename($fichier["name"]);
                $this->_extention = strtolower(pathinfo($nom_fichier_temporaire,PATHINFO_EXTENSION));
                foreach ($params["type_upload"] as $ty){
                    if($this->_extention == str_replace(".", "", $ty)){
                        $extention_valide = true;
                        break;
                    }
                }

                if($extention_valide == false){
                    $this->_etat = false;
                    $this->_message_erreur .= "<br />L'extention du fichier n'est pas valide";
                }
            }

            //  Taille upload maximum authorisé (exprimé en mo)
            //  100000 = 100kb
            if (isset($params["taille_upload"]) == false) {
                $this->_etat = false;
                $this->_message_erreur .= "<br />Le paramètre <b>taille_upload</b> est manquant";
            } else {
                $taille = $params["taille_upload"] * 1000 * 1000;

                if($fichier["size"] > $taille){
                    $this->_etat = false;
                    $this->_message_erreur .= "<br />La taille du fichier est supérieur à la limite autorisé";
                }
            }

        }

    }
}

La fonction etat() renvoise true ou false si l’ensemble des vérifications sont validées ou non

La fonction message_erreur() renvois les messages d’erreur rencontrés lors de la tentative de validation

La fonction fichier_uploader() renvois le nom fichier ainsi que son extention

Configuration et déclenchement de l’upload dans le controller

$dossier = $this->getParameter("visuels_produits");
        
$params = [
     "nom_fichier" => "test-upload-" . date("Ymd-hms"),
     "chemin_upload" => $dossier,
     "type_upload" => [
          "jpg",
          "png",
          "jpeg",
          "gif"
     ],
     "taille_upload" => 0.5
];

$upload = new Upload($_FILES["fichier"], $params);

if($upload->etat() == true)
     echo "Le fichier " . $upload->fichier_uploader() . " a correctement été uploadé";
else
     echo "Erreur durant l'upload";
        

nom_fichier : Nom que prendra le fichier à la fin de l’upload

chemin_upload : Chemin où sera uploadé le fichier

type_upload : Tableau des formats de fichier autorisés pour l’upload. Attention à ne pas mettre de point avant l’extention

taille_upload : Taille maximale autorisé pour l’upload. La taille est exprimée en MO

Attention : $_FILES[« fichier »] ici est lié au name du champ input type file du formulaire. Si jamais le système Drag & drop est implémenté, il fait référence à la valeur de la variable javaScript _upload_nom_variable_fichier du fichier upload.js

HTML

Code HTML du formulaire simple

<form action="[ACTION DU FORMULAIRE]" method="post" enctype="multipart/form-data">
     <input type="file" name="fichier" id="fichier" />
</form>

Drag & drop + Upload

Créer un fichier upload.js dans le dossier js du projet et y placer le code suivant

$(document).ready(function(){
    let _upload_class_zone_upload = '.dgwww_zone_upload'
    let _upload_class_input_file = '.dgwww_input_file_upload'
    let _upload_nom_variable_fichier = 'fichier'    //  Utiliser dans le traitement PHP
    let _upload_class_zone_preview = '.dgwww_zone_preview'

    /*
     *  Blocage de la redirection de la page
     */
    $("html").on("dragover", function(e) {
        e.preventDefault();
        e.stopPropagation();
    });

    $("html").on("drop", function(e) { e.preventDefault(); e.stopPropagation(); });

    /*
     *  Entrer et sortir de la zone de drag and drop
     */
    $(_upload_class_zone_upload).on('dragenter', function (e) {
        e.stopPropagation();
        e.preventDefault();
        $(_upload_class_zone_upload + " .message").text("Déposer le fichier");
    });

    $(_upload_class_zone_upload).on('dragover', function (e) {
        e.stopPropagation();
        e.preventDefault();
        $(_upload_class_zone_upload + " .message").text("Déposer le fichier");
    });

    /*
     *  Clique dans la zone de drag and drop
     */
    $(_upload_class_zone_upload).click(function(){
        $(_upload_class_input_file).click();
    });

    /*
     *  Déposer le fichier en upload
     */
    $(_upload_class_zone_upload).on('drop', function (e) {
        e.stopPropagation();
        e.preventDefault();

        $(_upload_class_zone_upload + " .message").text("Upload du fichier en cours ...");

        var file = e.originalEvent.dataTransfer.files;
        var fd = new FormData();

        fd.append(_upload_nom_variable_fichier, file[0]);

        _upload(fd);
    });

    /*
     *  Changement de valeur du champs upload
     */
    $(_upload_class_input_file).change(function() {

        var fd = new FormData();

        var files = $(_upload_class_input_file)[0].files[0];

        fd.append(_upload_nom_variable_fichier, files);

        _upload(fd);
    })

    /*
     *  Fonction d'upload
     */
    function _upload(input_file_data){
        let url = "produits/upload"
        
        // Ajout de valeur spécifique

        $.ajax({
            url: url,
            type: 'post',
            data: input_file_data,
            contentType: false,
            processData: false,
            success: function(response){
                if(response != 0){
                    $(_upload_class_zone_preview + " span").after("<img src='" + response + "' alt='' />")

                    $(_upload_class_zone_upload + " .message").text("Upload terminé");
                }else{
                    alert("Erreur dans l'upload du fichier");
                }
            },
        });
    }
})

_upload_nom_variable_fichier : est le nom repris dans le code PHP pour le traitement

Si besoin de passer d’autres valeurs que le FILE, il est possible d’ajout en dessous du commentaire // Ajout de valeur spécifique une ou plusieurs lignes sur le modèle suivant récupérables en POST

input_file_data.append("nom_variable", "Valeur")

HTML modifié

Version évolué du formulaire HTML prévoyant une zone de prévisualisation et une zone de Drag & Drop

<fieldset class="form-group">
     <legend class="col-form-label required">Visuels</legend>

     <div class="dgwww_zone_upload">
          <p class="message">Zone de dépot de fichier</p>
     </div>
      
     <input type="file" name="dgwww_zone_preview" id="dgwww_zone_preview" class="dgwww_input_file_upload" data-produit-id="{{ produit_id }}" data-site-id="{{ site_id }}" />

     <div class='dgwww_zone_preview'>
          <span></span>
     </div>
</fieldset>

CSS additional (SCSS)

$dgwww_zone_upload-height:100px;
$dgwww_zone_upload-padding:20px;
.dgwww_zone_upload{
  border: 1px solid grey;
  max-height: $dgwww_zone_upload-height;
  height: $dgwww_zone_upload-height;
  line-height: $dgwww_zone_upload-height;
  width: auto;
  padding: $dgwww_zone_upload-padding;
  text-align: center;
  cursor: pointer;

  p{
    line-height:calc(#{$dgwww_zone_upload-height} - (#{$dgwww_zone_upload-padding} * 2));
  }
}

.dgwww_input_file_upload{
  display: none;
}

.dgwww_zone_preview{
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;

  span{
    display: none;
  }

  img{
    height: auto;
    max-height: 100px;
    width: auto;
    max-width: 100px;
    margin-top: 15px;
  }
}

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *