File uploads: Percentage completed progress bar

懵懂的女人 提交于 2019-12-03 17:30:56

问题


I'm trying to add a 'percentage completed so far' progress bar to avatar uploads in BuddyPress. The aim is to stop users navigating away from the page before the upload is completed.

The upload process is handled in BuddyPress by bp_core_avatar_handle_upload() in file bp-core/bp-core-avatars.php. The function starts off by checking that the file has been uploaded properly using bp_core_check_avatar_upload(). It then checks that the file size is within limits, and that it has an accepted file extension (jpg, gif, png). If everything checks out, the user is allowed to crop the image (uses Jcrop) and then the image is moved to its real location.

The actual upload is handled by the WordPress function wp_handle_upload.

How can I create a 'percentage completed' progress bar and display it when the file is uploading?


回答1:


I'm not familiar with BuddyPress, but all upload handlers (including the HTML5 XHR one that androbin outlined) will have a file progress hook point that you can bind to.

I've used uploadify, uploadifive and swfupload, and they can all interact with the same progress function handler in order to acheive the same progress bar result.

// 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, being an HTML5 based uploader, simply binds to the XHR 'progress' event, so all these properties will be available to any HTML5 uploader.

As for the actual progress bar code..

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 + "%");
}



回答2:


You should use an XHR object. I don't now if it helps you, but I have a simple XHR uploader written.

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;
});

In this case I uploaded the file with uploadimage.php and if it printed: "ERROR_FILESIZE" then it alerted the error.




回答3:


I think that before you worry about the client-side of things you should be aware of the server-side requirements to actually be able to accomplish this.

For PHP you need to have the session.upload_progress enabled unless the wp_handle_upload() function uses something different, so I'm here just guessing, but chances are they do use the regular PHP session stuff hence it needs to be enabled.

If you look at the comments for the given link many users say that progress state does not work under certain environments such as PHP on FastCGI which is what you'll get in shared hosting environments most of the time.

Now many people here are telling you to use the XHR uploader but the problem is that they are giving you an example of a custom upload.php script or something like that to send the data, but you are using a wordpress plugin which you don't control (kinda)

So considering that the wp_handle_upload() does not actually works in an AJAX way then you would have to hook an event when the file upload form submit button is clicked and set a timer in JS which calls some URL where you pass the form data like an ID, and then query the session with that ID to check the progress of the file:

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

With that data you can calculate how much has been transfered. You could set the JS timer to be called like each second but if the files they are uploading are not very large (say, larger than 1mb) and they have a good connection then there won't be much progress to be notified.

Check this link for a step by step example on how to work with this session upload data.




回答4:


You need to inject the progress bar.

I think the only way is to over-ride the function bp_core_avatar_handle_upload using the filter hook apply_filters( 'bp_core_pre_avatar_handle_upload' etc. )

You'll end up duplicating most of the function but you should be able to add your progress bar code.

If you get this working, you should submit it as an enhancement ticket; it's a good idea.



来源:https://stackoverflow.com/questions/21646626/file-uploads-percentage-completed-progress-bar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!