mirror of
https://github.com/phpbb/phpbb.git
synced 2025-02-27 13:32:33 +01:00
The hidden attachment_data list needs to be updated if a file got removed. This was not done until now and caused a general error after submitting a post if a file was removed after uploading it. PHPBB3-11916
305 lines
8.6 KiB
JavaScript
305 lines
8.6 KiB
JavaScript
plupload.addI18n(phpbb.plupload.i18n);
|
|
plupload.attachment_data = [];
|
|
|
|
/**
|
|
* Returns the index of the plupload.attachment_data array where the given
|
|
* attach id appears
|
|
*
|
|
* @param int id The attachment id of the file
|
|
*
|
|
* @return bool Returns false if the id cannot be found
|
|
* @return int Returns the index in the main array where the attachment id
|
|
* was found
|
|
*/
|
|
function phpbb_plupload_find_attachment_idx(id) {
|
|
var data = plupload.attachment_data;
|
|
for (var i = 0; i < data.length; i++) {
|
|
if (data[i].attach_id == id) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Converts an array of objects into an object that PHP would expect as POST
|
|
* data
|
|
*
|
|
* @return object An object in the form 'attachment_data[i][key]': value as
|
|
* expected by the server
|
|
*/
|
|
function phpbb_plupload_attachment_data_serialize() {
|
|
var obj = {};
|
|
for (var i = 0; i < plupload.attachment_data.length; i++) {
|
|
var datum = plupload.attachment_data[i];
|
|
for (var key in datum) {
|
|
if (!datum.hasOwnProperty(key)) {
|
|
continue;
|
|
}
|
|
|
|
obj['attachment_data[' + i + '][' + key + ']'] = datum[key];
|
|
}
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
|
|
/**
|
|
* Unsets all elements in an object whose keys begin with 'attachment_data['
|
|
*
|
|
* @param object The object to be cleared
|
|
*
|
|
* @return undefined
|
|
*/
|
|
function phpbb_plupload_clear_params(obj) {
|
|
for (var key in obj) {
|
|
if (!obj.hasOwnProperty(key) || key.indexOf('attachment_data[') !== 0) {
|
|
continue;
|
|
}
|
|
|
|
delete obj[key];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update hidden attachment inputs in posting form
|
|
* Pre-existing hidden inputs will be removed by comparing the old attachment
|
|
* data (old_data) to the new attachment data (data) that has been sent back
|
|
* by plupload.
|
|
*
|
|
* @param object form Posting form
|
|
* @param object data Current attachment_data
|
|
* @param object old_date Previous attachment_data (before submission)
|
|
*
|
|
* @return void
|
|
*/
|
|
phpbb.update_hidden_attachment_inputs = function(form, data, old_data) {
|
|
// Update already existing hidden inputs
|
|
for (var i = 0; i < form.length; i++) {
|
|
if (data.hasOwnProperty(form[i].name)) {
|
|
form[i].value = data[form[i].name];
|
|
delete data[form[i].name];
|
|
} else if (typeof old_data !== 'undefined' && old_data.hasOwnProperty(form[i].name)) {
|
|
var inputRegex = /\b^[a-z_]+[+[0-9]+]/;
|
|
var inputName = inputRegex.exec(form[i].name);
|
|
if (typeof inputName !== 'undefined' && inputName[0] !== '') {
|
|
$("input[type='hidden'][name^='" + inputName[0] + "']").remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Append new inputs
|
|
for (var key in data) {
|
|
if (!data.hasOwnProperty(key)) {
|
|
continue;
|
|
}
|
|
|
|
var input = $('<input />')
|
|
.attr('type', 'hidden')
|
|
.attr('name', key)
|
|
.attr('value', data[key]);
|
|
$(form).append(input);
|
|
}
|
|
}
|
|
|
|
jQuery(function($) {
|
|
$(phpbb.plupload.config.element_hook).pluploadQueue(phpbb.plupload.config);
|
|
var uploader = $(phpbb.plupload.config.element_hook).pluploadQueue();
|
|
|
|
// Check the page for already-existing attachment data and add it to the
|
|
// array
|
|
var form = $(phpbb.plupload.config.form_hook)[0];
|
|
for (var i = 0; i < form.length; i++) {
|
|
if (form[i].name.indexOf('attachment_data[') !== 0) {
|
|
continue;
|
|
}
|
|
|
|
var matches = form[i].name.match(/\[(\d+)\]\[([^\]]+)\]/);
|
|
var index = matches[1];
|
|
var property = matches[2];
|
|
|
|
if (!plupload.attachment_data[index]) {
|
|
plupload.attachment_data[index] = {};
|
|
}
|
|
|
|
plupload.attachment_data[index][property] = form[i].value;
|
|
uploader.settings.multipart_params[form[i].name] = form[i].value;
|
|
}
|
|
|
|
/**
|
|
* Fires before a given file is about to be uploaded. This allows us to
|
|
* send the real filename along with the chunk. This is necessary because
|
|
* for some reason the filename is set to 'blob' whenever a file is chunked
|
|
*
|
|
* @param object up The plupload.Uploader object
|
|
* @param object file The plupload.File object that is about to be
|
|
* uploaded
|
|
*
|
|
* @return undefined
|
|
*/
|
|
uploader.bind('BeforeUpload', function(up, file) {
|
|
up.settings.multipart_params = $.extend(
|
|
up.settings.multipart_params,
|
|
{'real_filename': file.name}
|
|
);
|
|
});
|
|
|
|
/**
|
|
* Fired when a single chunk of any given file is uploaded. This parses the
|
|
* response from the server and checks for an error. If an error occurs it
|
|
* is reported to the user and the upload of this particular file is halted
|
|
*
|
|
* @param object up The plupload.Uploader object
|
|
* @param object file The plupload.File object whose chunk has just
|
|
* been uploaded
|
|
* @param object response The response object from the server
|
|
*
|
|
* @return undefined
|
|
*/
|
|
uploader.bind('ChunkUploaded', function(up, file, response) {
|
|
if (response.chunk >= response.chunks - 1) {
|
|
return;
|
|
}
|
|
|
|
var json = {};
|
|
try {
|
|
json = $.parseJSON(response.response);
|
|
} catch (e) {
|
|
file.status = plupload.FAILED;
|
|
up.trigger('FileUploaded', file, {
|
|
response: JSON.stringify({
|
|
error: {
|
|
message: 'Error parsing server response.'
|
|
}
|
|
})
|
|
});
|
|
}
|
|
|
|
if (json.error) {
|
|
file.status = plupload.FAILED;
|
|
up.trigger('FileUploaded', file, {
|
|
response: JSON.stringify({
|
|
error: {
|
|
message: json.error.message
|
|
}
|
|
})
|
|
});
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Fires when an entire file has been uploaded. It checks for errors
|
|
* returned by the server otherwise parses the list of attachment data and
|
|
* appends it to the next file upload so that the server can maintain state
|
|
* with regards to the attachments in a given post
|
|
*
|
|
* @param object up The plupload.Uploader object
|
|
* @param object file The plupload.File object that has just been
|
|
* uploaded
|
|
* @param string response The response string from the server
|
|
*
|
|
* @return undefined
|
|
*/
|
|
uploader.bind('FileUploaded', function(up, file, response) {
|
|
var json = {};
|
|
try {
|
|
json = $.parseJSON(response.response);
|
|
} catch (e) {
|
|
file.status = plupload.FAILED;
|
|
file.error = 'Error parsing server response.'
|
|
}
|
|
|
|
if (json.error) {
|
|
file.status = plupload.FAILED;
|
|
file.error = json.error.message;
|
|
} else if (file.status === plupload.DONE) {
|
|
plupload.attachment_data = json;
|
|
file.attachment_data = json[0];
|
|
up.settings.multipart_params = $.extend(
|
|
up.settings.multipart_params,
|
|
phpbb_plupload_attachment_data_serialize()
|
|
);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Fires when the entire queue of files have been uploaded. It resets the
|
|
* 'add files' button to allow more files to be uploaded and also attaches
|
|
* several events to each row of the currently-uploaded files to facilitate
|
|
* deleting any one of the files.
|
|
*
|
|
* Deleting a file removes it from the queue and fires an ajax event to the
|
|
* server to tell it to remove the temporary attachment. The server
|
|
* responds with the updated attachment data list so that any future
|
|
* uploads can maintain state with the server
|
|
*
|
|
* @param object up The plupload.Uploader object
|
|
* @param array files An array of plupload.File objects that have just
|
|
* been uploaded as part of a queue
|
|
*
|
|
* @return undefined
|
|
*/
|
|
uploader.bind('UploadComplete', function(up, files) {
|
|
$('.plupload_upload_status').css('display', 'none');
|
|
$('.plupload_buttons').css('display', 'block');
|
|
|
|
// Insert a bunch of hidden input elements containing the attachment
|
|
// data so that the save/preview/submit buttons work as expected.
|
|
var form = $(phpbb.plupload.config.form_hook)[0];
|
|
var data = phpbb_plupload_attachment_data_serialize();
|
|
|
|
phpbb.update_hidden_attachment_inputs(form, data);
|
|
|
|
files.forEach(function(file) {
|
|
if (file.status !== plupload.DONE) {
|
|
var click = function(evt) {
|
|
alert(file.error);
|
|
}
|
|
|
|
$('#' + file.id).attr('title', file.error);
|
|
$('#' + file.id).click(click);
|
|
|
|
return;
|
|
}
|
|
|
|
var click = function(evt) {
|
|
$(evt.target).find('a').addClass('working');
|
|
|
|
// The index is always found because file.attachment_data is
|
|
// just an element of plupload.attachment_data
|
|
var idx = phpbb_plupload_find_attachment_idx(file.attachment_data.attach_id);
|
|
var fields = {};
|
|
fields['delete_file[' + idx + ']'] = 1;
|
|
|
|
var always = function() {
|
|
$(evt.target).find('a').removeClass('working');
|
|
};
|
|
|
|
var done = function(response) {
|
|
up.removeFile(file);
|
|
plupload.attachment_data = response;
|
|
phpbb.update_hidden_attachment_inputs(form, phpbb_plupload_attachment_data_serialize(), data);
|
|
phpbb_plupload_clear_params(up.settings.multipart_params);
|
|
up.settings.multipart_params = $.extend(
|
|
up.settings.multipart_params,
|
|
phpbb_plupload_attachment_data_serialize()
|
|
);
|
|
};
|
|
|
|
$.ajax(phpbb.plupload.config.url, {
|
|
type: 'POST',
|
|
data: $.extend(fields, phpbb_plupload_attachment_data_serialize()),
|
|
headers: {'X-PHPBB-USING-PLUPLOAD': '1'}
|
|
})
|
|
.always(always)
|
|
.done(done);
|
|
};
|
|
|
|
$('#' + file.id)
|
|
.addClass('can_delete')
|
|
.click(click);
|
|
});
|
|
});
|
|
});
|