Загрузка файлов: Процент выполненных индикаторов выполнения

Я пытаюсь добавить "прогресс, достигнутый до конца", индикатор выполнения загрузки аватара в BuddyPress. Цель состоит в том, чтобы запретить пользователям перемещаться от страницы до завершения загрузки.

Процесс загрузки обрабатывается в BuddyPress на bp_core_avatar_handle_upload() в файле bp-core/bp-core-avatars.php. Функция запускается, проверяя, что файл загружен правильно, используя bp_core_check_avatar_upload(). Затем он проверяет, что размер файла находится в пределах, и что он имеет принятое расширение файла (jpg, gif, png). Если все проверяется, пользователю разрешено обрезать изображение (использует Jcrop), а затем изображение перемещается в его реальное местоположение.

Фактическая загрузка осуществляется с помощью функции WordPress wp_handle_upload.

Как я могу создать индикатор выполнения "процент завершен" и отобразить его при загрузке файла?

Ответ 1

Я не знаком с BuddyPress, но все обработчики загрузки (в том числе HTML5 XHR, которые обозначены андробином) будут иметь точку захвата файла, к которой вы можете привязать.

Я использовал uploadify, uploadifive и swfupload, и все они могут взаимодействовать с одним и тем же обработчиком функции выполнения, чтобы получить тот же результат выполнения.

// 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, являющийся загрузчиком на основе HTML5, просто привязывается к событию XHR "progress", поэтому все эти свойства будут доступны для любого загрузчика HTML5.

Что касается фактического штрихового кода выполнения.

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

Вы должны использовать объект XHR. Я не сейчас, если это вам поможет, но у меня есть простой загрузчик 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;
});

В этом случае я загрузил файл с помощью uploadimage.php, и если он напечатан: "ERROR_FILESIZE", он предупредил об ошибке.

Ответ 3

Я думаю, что прежде чем вы будете беспокоиться о клиентской стороне вещей, вы должны знать требования к серверной стороне, чтобы реально выполнить это.

Для PHP вам нужно включить session.upload_progress, если wp_handle_upload() использует что-то другое, поэтому я просто угадываю, но, скорее всего, они используют обычный материал PHP-сессии, поэтому его нужно активировать.

Если вы посмотрите на комментарии к данной ссылке, многие пользователи заявляют, что состояние прогресса не работает в определенных средах, таких как PHP на FastCGI, которые вы обычно будете получать в средах с общим хостингом.

Теперь многие люди говорят вам использовать загрузчик XHR, но проблема в том, что они дают вам пример пользовательского upload.php script или что-то подобное для отправки данных, но вы используете wordpress плагин, который вы не контролируете (kinda)

Итак, учитывая, что wp_handle_upload() фактически не работает по пути AJAX, вам нужно будет связать событие, когда нажата кнопка отправки формы загрузки файла, и установить таймер в JS, который вызывает некоторый URL-адрес, где вы передаете форму данные, такие как идентификатор, а затем запросить сеанс с этим идентификатором, чтобы проверить ход работы файла:

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

С помощью этих данных вы можете рассчитать, сколько было перенесено. Вы можете настроить так называемый таймер JS как каждую секунду, но если файлы, которые они загружают, не очень большие (скажем, больше, чем 1 Мб), и у них есть хорошая связь, тогда не будет большого прогресса, чтобы получать уведомления.

Отметьте эту ссылку для пошагового примера о том, как работать с данными загрузки этого сеанса.

Ответ 4

Вам нужно ввести индикатор выполнения.

Я думаю, что единственный способ - перегрузить функцию bp_core_avatar_handle_upload с помощью фильтра hook apply_filters ('bp_core_pre_avatar_handle_upload' и т.д.)

В результате вы будете дублировать большую часть функции, но вы должны будете добавить свой код прогресса.

Если вы получите эту работу, вы должны представить ее в качестве дополнительного билета; это хорошая идея.