web-dev-qa-db-fra.com

Fichiers téléchargés: barre de progression complétée en pourcentage

J'essaie d'ajouter une barre de progression indiquant le pourcentage terminé jusqu'à présent pour les téléchargements d'avatar dans BuddyPress . L'objectif est d'empêcher les utilisateurs de quitter la page avant que le téléchargement ne soit terminé.

Le processus de téléchargement est géré dans BuddyPress par bp_core_avatar_handle_upload() dans le fichier bp-core/bp-core-avatars.php. La fonction démarre en vérifiant que le fichier a été chargé correctement à l'aide de bp_core_check_avatar_upload(). Il vérifie ensuite que la taille du fichier est dans les limites et qu'il dispose d'une extension de fichier acceptée (jpg, gif, png). Si tout est vérifié, l'utilisateur est autorisé à rogner l'image (utilise Jcrop ), puis l'image est déplacée à son emplacement réel.

Le téléchargement effectif est géré par la fonction WordPress wp_handle_upload .

Comment créer une barre de progression 'pourcentage complété' et l'afficher lorsque le fichier est en cours de téléchargement?

12
henrywright

Je ne connais pas bien BuddyPress, mais tous les gestionnaires de téléchargement (y compris celui de HTML5 XHR décrit par androbin) auront un point d’accroché de progression du fichier auquel vous pouvez vous connecter. 

J'ai utilisé uploadify , uploadifive et swfupload , et ils peuvent tous interagir avec le même gestionnaire de fonctions de progression afin d'obtenir le même résultat dans la barre de progression.

// SWFUpload
$elem.bind('uploadProgress', function(event, file, bytesLoaded) { fnProgress(file, bytesLoaded); })

// Uploadify
$elem.uploadify({ onUploadProgress: function (file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) { fnProgress(file, bytesUploaded); });

// Uploadfive
$elem.uploadifive({ onProgress: function(file, e) { fn.onProgress(file, e.loaded); });

Uploadifive, en tant que programme de téléchargement basé sur HTML5, se lie simplement à l'événement 'progrès' de XHR, de sorte que toutes ces propriétés seront disponibles pour tout programme de téléchargement HTML5. 

En ce qui concerne le code à barres de progression réelle ..

HTML:

<div class='progressWrapper' style='float: left; width: 100%'>
    <div class='progress' style='float: left; width: 0%; color: red'></div>
    <div class='progressText' style='float: left;></div>
</div>

JS:

var fnProgress = function(file, bytes) {
    var percentage = (bytesLoaded / file.size) * 100;

    // Update DOM
    $('.progress').css({ 'width': percentage + '%' });
    $('.progressText').html(Math.round(percentage + "%");
}
11
Stumblor

Vous devriez utiliser un objet XHR. Je ne sais pas si cela peut vous aider, mais j’ai écrit un simple uploader XHR.

HTML:

    <form id="uploader" enctype="multipart/form-data" action="uploadimage.php" method="post">
        <input type="file" id="file" name="file[]" multiple="multiple" accept="image/jpeg" /><br/>
        <input type="submit" value="Upload" />
        <div class="list" style="background-color:#000;color:#FFF;padding:5px;display:none;border-radius:5px;">
        </div>
    </form>

JS:

$("#uploader").submit(function(){
    $('#uploader .list').fadeIn(100).css("width","0px");
    var data = new FormData();
    // if you want to append any other data: data.append("ID","");
    $.each($('#file')[0].files, function(i, file) {
        data.append('file-'+i, file);
    });
    $.ajax({
        url: 'uploadimage.php',
        data: data,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        xhr: function() {  // custom xhr
            myXhr = $.ajaxSettings.xhr();
            if(myXhr.upload){ // check if upload property exists
                myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // for handling the progress of the upload
            }
            return myXhr;
        },
        success: function(data2){
            $('#uploader .list').css({
                "width":"200px",
                "text-align":"center",
                "margin":"10px 0 10px 0"
            }).html("DONE!").delay(2000).fadeOut(500);
            if (data2 == "ERROR_FILESIZE"){
                return alert("Choose another file");
            }
                            else{ /*change location*/ }
        });
    return false;
});

Dans ce cas, j'ai téléchargé le fichier avec uploadimage.php et, s'il était imprimé: "ERROR_FILESIZE", il a alerté l'erreur.

7
androbin

Je pense qu'avant de vous préoccuper du côté client, vous devez être conscient des exigences du côté serveur pour pouvoir y parvenir.

Pour PHP, vous devez activer la fonction session.upload_progress, à moins que la fonction wp_handle_upload () n'utilise quelque chose de différent. Je suis donc en train de deviner, mais il y a de bonnes chances qu'ils le fassent utilisez la session PHP habituelle, elle doit donc être activée.

Si vous examinez les commentaires pour le lien donné, de nombreux utilisateurs indiquent que l'état de progression ne fonctionne pas dans certains environnements, tels que PHP sur FastCGI, ce que vous obtiendrez la plupart du temps dans des environnements d'hébergement partagé.

Maintenant, beaucoup de gens ici vous disent d’utiliser le programme de téléchargement XHR, mais le problème est qu’ils vous donnent un exemple de script upload.php personnalisé ou quelque chose du genre pour envoyer les données, mais vous utilisez un plugin wordpress auquel vous n’avez pas accès. t contrôle (un peu)

Si vous considérez que la fonction wp_handle_upload () ne fonctionne pas réellement de manière AJAX, vous devrez alors accrocher un événement lorsque le bouton de soumission du formulaire de téléchargement de fichier est cliqué et définir un temporisateur dans JS qui appelle une URL à laquelle vous transmettez le message. formez des données comme un identifiant, puis interrogez la session avec cet identifiant pour vérifier la progression du fichier:

 $_SESSION["upload_id"]["content_length"]
 $_SESSION["upload_id"]["bytes_processed"]

Avec ces données, vous pouvez calculer le montant transféré. Vous pouvez configurer le minuteur JS pour qu'il soit appelé comme chaque seconde, mais si les fichiers qu'ils téléchargent ne sont pas très volumineux (par exemple, supérieurs à 1 Mo) et qu'ils ont une bonne connexion, il n'y aura pas beaucoup de progrès à notifier.

Vérifiez ce lien pour un exemple pas à pas sur la façon de travailler avec les données de téléchargement de cette session.

2
Gustavo Rubio

Vous devez injecter la barre de progression. 

Je pense que le seul moyen est de remplacer la fonction bp_core_avatar_handle_upload en utilisant le filtre hook apply_filters ('bp_core_pre_avatar_handle_upload' etc.) 

Vous finirez par dupliquer la plupart des fonctions, mais vous devriez pouvoir ajouter votre code à barres de progression. 

Si cela fonctionne, vous devez le soumettre en tant que ticket d’amélioration; c'est une bonne idée. 

0
shanebp