Skip to content

Force re upload of last chunk

blueimp edited this page Mar 3, 2013 · 1 revision

Addition to Chunked file uploads by user Webunity

Force re-upload of last chunk

In case you would like to enforce the chunked upload to re-upload the last chunk, you could achieve this by applying the following logic.

You should replace your calls to "new UploadHandler(...)" with "new ChunkedUploadHelper(...)", which will trim the file if it exists. The rest of the code and functionality is untouched. Note: this code is based and tested upon jQuery File Upload Plugin 5.21

/**
 * Helper method for trimming chunked uploads.
 */
class ChunkedUploadHelper extends UploadHandler {
    /**
     * Custom "get" method to call our custom function.
     */
    public function get($print_response = true) {
        if ($print_response && isset($_GET['download'])) {
            return $this->download();
        }
        $file_name = $this->get_file_name_param();
        if ($file_name) {
            $response = array(
                substr($this->options['param_name'], 0, -1) => $this->get_file_object_trimmed($file_name)
            );
        } else {
            $response = array(
                $this->options['param_name'] => $this->get_file_objects()
            );
        }
        return $this->generate_response($response, $print_response);
    }

    /**
     * Gets a trimmed file object if the maxChunkSize has been given.
     */
    protected function get_file_object_trimmed($file_name) {
        $file_object = $this->get_file_object($file_name);
        if ($file_object != null) {
            // In case an upload was started and we have a max chunk size, trim it to the last full size.
            $max_chunk_size = $_GET['maxChunkSize'] || 0;
            if ($file_object->size > 0) && ($max_chunk_size > 0) {
                $truncated_bytes = floor($file_object->size / $max_chunk_size) * $max_chunk_size;
                if ($truncated_bytes < $file_object->size) {
                    $file_path = $this->get_upload_path($file_name, $this->get_version_param());
                    if (ftruncate(fopen($file_path, 'r+'), $truncated_bytes)) {
                        // Update file size to reflect truncated state
                        $file_object->size = filesize($file_path);
                    } else {
                        // Something went wrong while truncating, redo entire file
                        @unlink($file_path);
                        $file_object = null;
                    }
                }
            }
        }
        return $file_object;
    }
}

Then all you need to do is to pass the maxChunkSize value to the backend script, and the UploadHandler will take care of the rest.

$('#fileupload').fileupload({
    /* ... settings as above with add function replaced with ... */
    add: function (e, data) {
        // jQuery Widget Factory uses "namespace-widgetname" since version 1.10.0:
        var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
        var that = this;
        $.getJSON('server/php/', {file: data.files[0].name, maxChunkSize: fu.options.maxChunkSize}, function (result) {
            var file = result.file;
            data.uploadedBytes = file && file.size;
            $.blueimp.fileupload.prototype
                .options.add.call(that, e, data);
        });
    }
});
Clone this wiki locally