Introduction
To upload multiple files to the server, I use:
Note
Note:
- this configuration works without failures when using separate file downloads (selects a file, downloads it, and then repeats from the very beginning). My problem is multiple file downloads using the same building blocks.
- I was unable to implement the
jQuery File Upload example Basic Plus UI user interface. (In addition, I did not find a suitable example on the Internet). - At the moment, multiple file downloads work fine, although the interface is "very spartan" - it consists only of
upload progress bar (common to all files) and upload button (to download all added files). Thus, there is practically no UI!
Target
I would like to create some file uploads that will be close to the jQuery File Upload example of Basic Plus UI , but:
- without previewing the file and image,
- without individual file uploads,
- without customizing the progress bar.
PROBLEM
There is no way (at least for me at the moment) to determine which file is getting the error!
Example 1
For example: I get the following JSON response from the server
data.jqXHR.responseText = {"files":[{"error":"error.maxsize"},{"error":"error.maxsize"}]}
But at that time there were 3 uploaded files - and so - there is no information what error corresponds to that file!
Example 2
If I modify the boot listener like this:
public function onUpload(PreUploadEvent $event) { $file = $event->getFile(); $response = $event->getResponse(); $response['files'] = [ 'name'=> $file->getBaseName(), 'type'=> $file->getType(), 'size'=> $file->getSize(), ]; return json_encode($response); }
Then i get a broken answer
data.jqXHR.responseText = {"files":{"name":"php406E.tmp","type":"file","size":863329,"0":{"error":"error.maxsize"}}}
For the same download of 3 files there should be 2 errors, but there is only one error!
Example 3
I tried using the suggested sample code ,
for (k=0; k<data.files.length; k++) { alert(data.files[k].name + "\n" + data.files[k].error); }
but unfortunately this did not work ... data.files[k].error got undefined at every step of the loop.
CODE
My template with corresponding javascript code
{% extends 'base.html.twig' %} {% block stylesheets %} {{ parent() }} <link rel="stylesheet" type="text/css" href="{{ asset('css/blueimp/jquery.fileupload.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ asset('css/bootstrap/bootstrap.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ asset('css/bootstrap/bootstrap-theme.css') }}" /> {% endblock %} {% block title %}Upload nr.3 multiple files{% endblock %} {% block content %} <div id="box-upload"> <div id="box-file-upload"> <form method="post" enctype="multipart/form-data"> <span class="btn btn-success fileinput-button"> <i class="glyphicon glyphicon-plus"></i> <span> Choose files...</span> <input id="file-upload" type="file" name="files[]" data-url="{{ oneup_uploader_endpoint('gallery') }}" multiple="multiple" /> </span> <button id="file-upload-start" type="button" class="btn btn-primary start"> <i class="glyphicon glyphicon-upload"></i> <span>Start upload</span> </button> </form> </div> <div id="box-progress"> <div id="box-progress-bar" style="width: 0%;"></div> </div> <div id="box-info"> <p id="upload-status">Upload status...</p> </div> </div> {% endblock %} {% block javascripts %} {{ parent() }} <script type="text/javascript" src="{{ asset('js/tmpl/tmpl.min.js') }}"></script> <script type="text/javascript" src="{{ asset('js/blueimp/jquery.ui.widget.js') }}"></script> <script type="text/javascript" src="{{ asset('js/blueimp/jquery.iframe-transport.js') }}"></script> <script type="text/javascript" src="{{ asset('js/blueimp/jquery.fileupload.js') }}"></script> <script type="text/javascript"> $(function() { 'use strict'; var GLOBAL = {}; GLOBAL.upload_url = "{{ oneup_uploader_endpoint('gallery') }}"; GLOBAL.item_count_all = 1; GLOBAL.item_count_ok = 0; GLOBAL.file_list = []; GLOBAL.file_list_ids_ok = []; function enableFileUploadControl() { $('input#file-upload').attr('disabled', false); } function disableFileUploadControl() { $('input#file-upload').attr('disabled', true); } $('#file-upload').on('fileuploadprocessfail', function (e, data) { //alert(data.files[data.index].error); //alert(data.files[index].error); alert(data.files[data.index].name + "\n" + data.files[data.index].error); /* var file = data.files[data.index]; alert(file.error); console.log(file.error); */ }); $('#file-upload').on('click', function () { clearUploadedFileList(); $('#box-progress-bar').css('width', '1%'); }); $('#file-upload').fileupload( { formData: {extra:1}, add: function (e, data) { var current_item_class, allowedTypes = 'jpg,JPG,jpeg,JPEG,png,PNG,gif,GIF', fileName, fileSize, fileType, js_allowed_upload_file_size; fileName = data.files[0].name; fileSize = data.files[0].size; fileType = data.files[0].name.split('.').pop(); js_allowed_upload_file_size = 1048576; //console.log('fileSize = '+ fileSize); if (allowedTypes.indexOf(fileType) < 0) { $('#box-progress-bar').css('width', '0'); current_item_class = 'upload-item-'+ GLOBAL.item_count_all; $('<div class="upload-item '+ current_item_class +'"/>').appendTo($('#box-info')); $('<p/>').text(fileName).appendTo('.'+ current_item_class); $('<p class="wrong-file-type"/>').text('Invalid file type').appendTo('.'+ current_item_class); GLOBAL.item_count_all++; } /* else if (fileSize > js_allowed_upload_file_size) { current_item_class = 'upload-item-'+ GLOBAL.item_count_all; $('<div class="upload-item '+ current_item_class +'"/>').appendTo($('#box-info')); $('<p/>').text(fileName).appendTo('.'+ current_item_class); $('<p class="upload-error"/>').text('Max size exceeded').appendTo('.'+ current_item_class); GLOBAL.item_count_all++; } */ else { current_item_class = 'upload-item-'+ GLOBAL.item_count_all; $('<div class="upload-item '+ current_item_class +'"/>').appendTo($('#box-info')); $('<p/>').text(fileName).appendTo('.'+ current_item_class); if ($('.button-upload').length == 0) { // disabling file input $('input#file-upload').attr('disabled', true); $('<p class="ready-to-upload"/>').text('Ready to upload').appendTo('.'+ current_item_class); } //console.log('global.item_count_all = '+ GLOBAL.item_count_all); GLOBAL.file_list.push(data.files[0]); GLOBAL.file_list_ids_ok.push(GLOBAL.item_count_all); GLOBAL.item_count_all++; GLOBAL.item_count_ok++; } }, progressall: function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); $('#box-progress-bar').css('width', progress + '%'); }, done: function (e, data) { console.log('inside MAIN DONE'); var i, k, errorType, message = []; //console.log('data = '+ data); console.log('data.jqXHR.responseText = '+ data.jqXHR.responseText); console.log(data); if (data.jqXHR.responseText.length > 2) { errorType = $.parseJSON(data.jqXHR.responseText); errorType = errorType['files'][0]['error']; if (errorType === "error.forbidden_mime_type") { message[0] = 'error'; message[1] = 'Forbidden file type'; } else if (errorType === "error.mime_type_mismatch") { message[0] = 'error'; message[1] = 'Invalid mime type'; } else if (errorType === "error.maxsize") { message[0] = 'error'; message[1] = 'Max size exceeded'; } else if (errorType === "error.whitelist") { message[0] = 'error'; message[1] = 'Invalid file'; } } else { message[0] = 'all is ok'; message[1] = 'No error found'; } for (k=0; k<data.files.length; k++) { alert(data.files[k].name + "\n" + data.files[k].error); i = GLOBAL.file_list_ids_ok[k]; console.log(i); if (message[0] === 'error') { $('<p class="upload-error"/>').text(message).appendTo('.upload-item-'+ i); } else if (message[0] === 'no error') { $('<p class="upload-success"/>').text(message).appendTo('.upload-item-'+ i); } } // after all is done updateUploadFileListUploadFinished(); enableFileUploadControl(); resetUploadFormCounters(); }, start: function(e, data) { //console.log("Upload started"); console.log('inside MAIN START'); disableFileUploadControl(); updateUploadFileListUploading(); } } ); $('#file-upload-start').on('click', function() { $('#file-upload').fileupload('send', { files: GLOBAL.file_list, url: GLOBAL.upload_url, dataType: 'json', start: function(e, data) {}, done: function (e, data) {} } ); }); function clearUploadedFileList() { $('.upload-item').remove(); } function updateUploadFileListUploading() { var i, ok_item_class; for (i=0; i<GLOBAL.file_list_ids_ok.length; i++) { ok_item_class = 'upload-item-'+ GLOBAL.file_list_ids_ok[i]; $('<p class="upload-success"/>').text('Uploading...').appendTo('.'+ ok_item_class); } } function updateUploadFileListUploadFinished() { var i, ok_item_class; for (i=0; i<GLOBAL.file_list_ids_ok.length; i++) { ok_item_class = 'upload-item-'+ GLOBAL.file_list_ids_ok[i]; $('<p class="upload-success"/>').text('Upload finished').appendTo('.'+ ok_item_class); } } function resetUploadFormCounters() { GLOBAL.item_count_all = 1; GLOBAL.item_count_ok = 0; GLOBAL.file_list = []; GLOBAL.file_list_ids_ok = []; GLOBAL.message = []; } }); </script> {% endblock %}
FINALLY
- What am I missing?
- Am I missing a parameter in the configuration?
- Perhaps this is a bug in the javascript
jQuery File Upload by Blueimp ?
Conclusion
Please inform.
Thank you for your time and knowledge.
UPDATES
Update 1
I have the following settings in php.ini
- post_max_size = 3G
- upload_max_filesize = 3G
- max_file_uploads = 20
Update 2
So, I modified my Upload listener as follows:
public function onUpload(PreUploadEvent $event) { $file = $event->getFile(); $response = $event->getResponse(); $message = [ 'error' => 'none' ]; $response->addToOffset($message, array('files')); }
And now example 2 returns:
data.jqXHR.responseText = {"files":[{"error":"none"},{"error":"error.maxsize"},{"error":"error.maxsize"}]}
I updated the JavaScript part and now iterates through responseText and updates the elements with the corresponding errors.
If you see / know the best way, please comment.