Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
plupload.js
001 /* global phpbb, plupload, attachInline */
002
003 plupload.addI18n(phpbb.plupload.i18n);
004 phpbb.plupload.ids = [];
005
006 (function($) { // Avoid conflicts with other libraries
007
008 'use strict';
009
010 /**
011 * Set up the uploader.
012 */
013 phpbb.plupload.initialize = function() {
014 // Initialize the Plupload uploader.
015 phpbb.plupload.uploader.init();
016
017 // Set attachment data.
018 phpbb.plupload.setData(phpbb.plupload.data);
019 phpbb.plupload.updateMultipartParams(phpbb.plupload.getSerializedData());
020
021 // Only execute if Plupload initialized successfully.
022 phpbb.plupload.uploader.bind('Init', function() {
023 phpbb.plupload.form = $(phpbb.plupload.config.form_hook)[0];
024 let $attachRowTemplate = $('#attach-row-tpl');
025 $attachRowTemplate.removeClass('attach-row-tpl');
026 phpbb.plupload.rowTpl = $attachRowTemplate[0].outerHTML;
027
028 // Hide the basic upload panel and remove the attach row template.
029 $('#attach-row-tpl, #attach-panel-basic').remove();
030 // Show multi-file upload options.
031 $('#attach-panel-multi').show();
032 });
033
034 phpbb.plupload.uploader.bind('PostInit', function() {
035 // Point out the drag-and-drop zone if it's supported.
036 if (phpbb.plupload.uploader.features.dragdrop) {
037 $('#drag-n-drop-message').show();
038 }
039
040 // Ensure "Add files" button position is correctly calculated.
041 if ($('#attach-panel-multi').is(':visible')) {
042 phpbb.plupload.uploader.refresh();
043 }
044 $('[data-subpanel="attach-panel"]').one('click', function() {
045 phpbb.plupload.uploader.refresh();
046 });
047 });
048 };
049
050 /**
051 * Unsets all elements in the object uploader.settings.multipart_params whose keys
052 * begin with 'attachment_data['
053 */
054 phpbb.plupload.clearParams = function() {
055 var obj = phpbb.plupload.uploader.settings.multipart_params;
056 for (var key in obj) {
057 if (!obj.hasOwnProperty(key) || key.indexOf('attachment_data[') !== 0) {
058 continue;
059 }
060
061 delete phpbb.plupload.uploader.settings.multipart_params[key];
062 }
063 };
064
065 /**
066 * Update uploader.settings.multipart_params object with new data.
067 *
068 * @param {object} obj
069 */
070 phpbb.plupload.updateMultipartParams = function(obj) {
071 var settings = phpbb.plupload.uploader.settings;
072 settings.multipart_params = $.extend(settings.multipart_params, obj);
073 };
074
075 /**
076 * Convert the array of attachment objects into an object that PHP would expect as POST data.
077 *
078 * @returns {object} An object in the form 'attachment_data[i][key]': value as
079 * expected by the server
080 */
081 phpbb.plupload.getSerializedData = function() {
082 var obj = {};
083 for (var i = 0; i < phpbb.plupload.data.length; i++) {
084 var datum = phpbb.plupload.data[i];
085 for (var key in datum) {
086 if (!datum.hasOwnProperty(key)) {
087 continue;
088 }
089
090 obj['attachment_data[' + i + '][' + key + ']'] = datum[key];
091 }
092 }
093
094 // Insert form data
095 var $pluploadForm = $(phpbb.plupload.config.form_hook).first();
096 obj.creation_time = $pluploadForm.find('input[type=hidden][name="creation_time"]').val();
097 obj.form_token = $pluploadForm.find('input[type=hidden][name="form_token"]').val();
098
099 return obj;
100 };
101
102 /**
103 * Get the index from the phpbb.plupload.data array where the given
104 * attachment id appears.
105 *
106 * @param {int} attachId The attachment id of the file.
107 * @returns {bool|int} Index of the file if exists, otherwise false.
108 */
109 phpbb.plupload.getIndex = function(attachId) {
110 var index = $.inArray(Number(attachId), phpbb.plupload.ids);
111 return (index !== -1) ? index : false;
112 };
113
114 /**
115 * Set the data in phpbb.plupload.data and phpbb.plupload.ids arrays.
116 *
117 * @param {Array} data Array containing the new data to use. In the form of
118 * array(index => object(property: value). Requires attach_id to be one of the object properties.
119 */
120 phpbb.plupload.setData = function(data) {
121 // Make sure that the array keys are reset.
122 phpbb.plupload.ids = phpbb.plupload.data = [];
123 phpbb.plupload.data = data;
124
125 for (var i = 0; i < data.length; i++) {
126 phpbb.plupload.ids.push(Number(data[i].attach_id));
127 }
128 };
129
130 /**
131 * Update the attachment data in the HTML and the phpbb & phpbb.plupload objects.
132 *
133 * @param {Array} data Array containing the new data to use.
134 * @param {string} action The action that required the update. Used to update the inline attachment bbcodes.
135 * @param {int} index The index from phpbb.plupload_ids that was affected by the action.
136 * @param {Array} downloadUrl Optional array of download urls to update.
137 */
138 phpbb.plupload.update = function(data, action, index, downloadUrl) {
139
140 phpbb.plupload.updateBbcode(action, index);
141 phpbb.plupload.setData(data);
142 phpbb.plupload.updateRows(downloadUrl);
143 phpbb.plupload.clearParams();
144 phpbb.plupload.updateMultipartParams(phpbb.plupload.getSerializedData());
145 };
146
147 /**
148 * Update the relevant elements and hidden data for all attachments.
149 *
150 * @param {Array} downloadUrl Optional array of download urls to update.
151 */
152 phpbb.plupload.updateRows = function(downloadUrl) {
153 for (var i = 0; i < phpbb.plupload.ids.length; i++) {
154 phpbb.plupload.updateRow(i, downloadUrl);
155 }
156 };
157
158 /**
159 * Insert a row for a new attachment. This expects an HTML snippet in the HTML
160 * using the id "attach-row-tpl" to be present. This snippet is cloned and the
161 * data for the file inserted into it. The row is then appended or prepended to
162 * #file-list based on the attach_order setting.
163 *
164 * @param {object} file Plupload file object for the new attachment.
165 */
166 phpbb.plupload.insertRow = function(file) {
167 var row = $(phpbb.plupload.rowTpl);
168
169 row.attr('id', file.id);
170 row.find('.file-name').html(plupload.xmlEncode(file.name));
171 row.find('.file-size').html(plupload.formatSize(file.size));
172
173 if (phpbb.plupload.order === 'desc') {
174 $('#file-list').prepend(row);
175 } else {
176 $('#file-list').append(row);
177 }
178 };
179
180 /**
181 * Update the relevant elements and hidden data for an attachment.
182 *
183 * @param {int} index The index from phpbb.plupload.ids of the attachment to edit.
184 * @param {Array} downloadUrl Optional array of download urls to update.
185 */
186 phpbb.plupload.updateRow = function(index, downloadUrl) {
187 var attach = phpbb.plupload.data[index],
188 row = $('[data-attach-id="' + attach.attach_id + '"]');
189
190 // Add the link to the file
191 if (typeof downloadUrl !== 'undefined' && typeof downloadUrl[index] !== 'undefined') {
192 var url = downloadUrl[index].replace('&', '&'),
193 link = $('<a></a>');
194
195 link.attr('href', url).html(attach.real_filename);
196 row.find('.file-name').html(link);
197 }
198
199 row.find('textarea').attr('name', 'comment_list[' + index + ']');
200 phpbb.plupload.updateHiddenData(row, attach, index);
201 };
202
203 /**
204 * Update hidden input data for an attachment.
205 *
206 * @param {object} row jQuery object for the attachment row.
207 * @param {object} attach Attachment data object from phpbb.plupload.data
208 * @param {int} index Attachment index from phpbb.plupload.ids
209 */
210 phpbb.plupload.updateHiddenData = function(row, attach, index) {
211 row.find('input[type="hidden"]').remove();
212
213 for (var key in attach) {
214 if (!attach.hasOwnProperty(key)) {
215 return;
216 }
217
218 var input = $('<input />')
219 .attr('type', 'hidden')
220 .attr('name', 'attachment_data[' + index + '][' + key + ']')
221 .attr('value', attach[key]);
222 $(row).append(input);
223 }
224 };
225
226 /**
227 * Deleting a file removes it from the queue and fires an AJAX event to the
228 * server to tell it to remove the temporary attachment. The server
229 * responds with the updated attachment data list so that any future
230 * uploads can maintain state with the server
231 *
232 * @param {object} row jQuery object for the attachment row.
233 * @param {int} attachId Attachment id of the file to be removed.
234 */
235 phpbb.plupload.deleteFile = function(row, attachId) {
236 // If there's no attach id, then the file hasn't been uploaded. Simply delete the row.
237 if (typeof attachId === 'undefined') {
238 var file = phpbb.plupload.uploader.getFile(row.attr('id'));
239 phpbb.plupload.uploader.removeFile(file);
240
241 row.slideUp(100, function() {
242 row.remove();
243 phpbb.plupload.hideEmptyList();
244 });
245 }
246
247 var index = phpbb.plupload.getIndex(attachId);
248 row.find('.file-status').toggleClass('file-uploaded file-working');
249
250 if (index === false) {
251 return;
252 }
253 var fields = {};
254 fields['delete_file[' + index + ']'] = 1;
255
256 var always = function() {
257 row.find('.file-status').removeClass('file-working');
258 };
259
260 var done = function(response) {
261 if (typeof response !== 'object') {
262 return;
263 }
264
265 // trigger_error() was called which likely means a permission error was encountered.
266 if (typeof response.title !== 'undefined') {
267 phpbb.plupload.uploader.trigger('Error', { message: response.message });
268 // We will have to assume that the deletion failed. So leave the file status as uploaded.
269 row.find('.file-status').toggleClass('file-uploaded');
270
271 return;
272 }
273
274 // Handle errors while deleting file
275 if (typeof response.error !== 'undefined') {
276 phpbb.alert(phpbb.plupload.lang.ERROR, response.error.message);
277
278 // We will have to assume that the deletion failed. So leave the file status as uploaded.
279 row.find('.file-status').toggleClass('file-uploaded');
280
281 return;
282 }
283
284 phpbb.plupload.update(response, 'removal', index);
285 // Check if the user can upload files now if he had reached the max files limit.
286 phpbb.plupload.handleMaxFilesReached();
287
288 if (row.attr('id')) {
289 var file = phpbb.plupload.uploader.getFile(row.attr('id'));
290 phpbb.plupload.uploader.removeFile(file);
291 }
292 row.slideUp(100, function() {
293 row.remove();
294 // Hide the file list if it's empty now.
295 phpbb.plupload.hideEmptyList();
296 });
297 phpbb.plupload.uploader.trigger('FilesRemoved');
298 };
299
300 $.ajax(phpbb.plupload.config.url, {
301 type: 'POST',
302 data: $.extend(fields, phpbb.plupload.getSerializedData()),
303 headers: phpbb.plupload.config.headers
304 })
305 .always(always)
306 .done(done);
307 };
308
309 /**
310 * Check the attachment list and hide its container if it's empty.
311 */
312 phpbb.plupload.hideEmptyList = function() {
313 if (!$('#file-list').children().length) {
314 $('#file-list-container').slideUp(100);
315 }
316 };
317
318 /**
319 * Update the indices used in inline attachment bbcodes. This ensures that the
320 * bbcodes correspond to the correct file after a file is added or removed.
321 * This should be called before the phpbb.plupload,data and phpbb.plupload.ids
322 * arrays are updated, otherwise it will not work correctly.
323 *
324 * @param {string} action The action that occurred -- either "addition" or "removal"
325 * @param {int} index The index of the attachment from phpbb.plupload.ids that was affected.
326 */
327 phpbb.plupload.updateBbcode = function(action, index) {
328 var textarea = $('#message', phpbb.plupload.form),
329 text = textarea.val(),
330 removal = (action === 'removal');
331
332 // Return if the bbcode isn't used at all.
333 if (text.indexOf('[attachment=') === -1) {
334 return;
335 }
336
337 function runUpdate(i) {
338 var regex = new RegExp('\\[attachment=' + i + '\\](.*?)\\[\\/attachment\\]', 'g');
339 text = text.replace(regex, function updateBbcode(_, fileName) {
340 // Remove the bbcode if the file was removed.
341 if (removal && index === i) {
342 return '';
343 }
344 var newIndex = i + ((removal) ? -1 : 1);
345 return '[attachment=' + newIndex + ']' + fileName + '[/attachment]';
346 });
347 }
348
349 // Loop forwards when removing and backwards when adding ensures we don't
350 // corrupt the bbcode index.
351 var i;
352 if (removal) {
353 for (i = index; i < phpbb.plupload.ids.length; i++) {
354 runUpdate(i);
355 }
356 } else {
357 for (i = phpbb.plupload.ids.length - 1; i >= index; i--) {
358 runUpdate(i);
359 }
360 }
361
362 textarea.val(text);
363 };
364
365 /**
366 * Get Plupload file objects based on their upload status.
367 *
368 * @param {int} status Plupload status - plupload.DONE, plupload.FAILED,
369 * plupload.QUEUED, plupload.STARTED, plupload.STOPPED
370 *
371 * @returns {Array} The Plupload file objects matching the status.
372 */
373 phpbb.plupload.getFilesByStatus = function(status) {
374 var files = [];
375
376 $.each(phpbb.plupload.uploader.files, function(i, file) {
377 if (file.status === status) {
378 files.push(file);
379 }
380 });
381 return files;
382 };
383
384 /**
385 * Check whether the user has reached the maximun number of files that he's allowed
386 * to upload. If so, disables the uploader and marks the queued files as failed. Otherwise
387 * makes sure that the uploader is enabled.
388 *
389 * @returns {bool} True if the limit has been reached. False if otherwise.
390 */
391 phpbb.plupload.handleMaxFilesReached = function() {
392 // If there is no limit, the user is an admin or moderator.
393 if (!phpbb.plupload.maxFiles) {
394 return false;
395 }
396
397 if (phpbb.plupload.maxFiles <= phpbb.plupload.ids.length) {
398 // Fail the rest of the queue.
399 phpbb.plupload.markQueuedFailed(phpbb.plupload.lang.TOO_MANY_ATTACHMENTS);
400 // Disable the uploader.
401 phpbb.plupload.disableUploader();
402 phpbb.plupload.uploader.trigger('Error', { message: phpbb.plupload.lang.TOO_MANY_ATTACHMENTS });
403
404 return true;
405 } else if (phpbb.plupload.maxFiles > phpbb.plupload.ids.length) {
406 // Enable the uploader if the user is under the limit
407 phpbb.plupload.enableUploader();
408 }
409 return false;
410 };
411
412 /**
413 * Disable the uploader
414 */
415 phpbb.plupload.disableUploader = function() {
416 $('#add_files').addClass('disabled');
417 phpbb.plupload.uploader.disableBrowse();
418 };
419
420 /**
421 * Enable the uploader
422 */
423 phpbb.plupload.enableUploader = function() {
424 $('#add_files').removeClass('disabled');
425 phpbb.plupload.uploader.disableBrowse(false);
426 };
427
428 /**
429 * Mark all queued files as failed.
430 *
431 * @param {string} error Error message to present to the user.
432 */
433 phpbb.plupload.markQueuedFailed = function(error) {
434 var files = phpbb.plupload.getFilesByStatus(plupload.QUEUED);
435
436 $.each(files, function(i, file) {
437 $('#' + file.id).find('.file-progress').hide();
438 phpbb.plupload.fileError(file, error);
439 });
440 };
441
442 /**
443 * Marks a file as failed and sets the error message for it.
444 *
445 * @param {object} file Plupload file object that failed.
446 * @param {string} error Error message to present to the user.
447 */
448 phpbb.plupload.fileError = function(file, error) {
449 file.status = plupload.FAILED;
450 file.error = error;
451 $('#' + file.id).find('.file-status')
452 .addClass('file-error')
453 .attr({
454 'data-error-title': phpbb.plupload.lang.ERROR,
455 'data-error-message': error
456 });
457 };
458
459
460 /**
461 * Set up the Plupload object and get some basic data.
462 */
463 phpbb.plupload.uploader = new plupload.Uploader(phpbb.plupload.config);
464 phpbb.plupload.initialize();
465
466 /**
467 * Add a file filter to check for max file sizes per mime type.
468 */
469 plupload.addFileFilter('mime_types_max_file_size', function(types, file, callback) {
470 if (file.size !== 'undefined') {
471 $(types).each(function(i, type) {
472 let extensions = [],
473 extsArray = type.extensions.split(',');
474
475 $(extsArray).each(function(i, extension) {
476 /^\s*\*\s*$/.test(extension) ? extensions.push("\\.*") : extensions.push("\\." + extension.replace(new RegExp("[" + "/^$.*+?|()[]{}\\".replace(/./g, "\\$&") + "]", "g"), "\\$&"));
477 });
478
479 let regex = new RegExp("(" + extensions.join("|") + ")$", "i");
480
481 if (regex.test(file.name)) {
482 if (type.max_file_size !== 'undefined' && type.max_file_size) {
483 if (file.size > type.max_file_size) {
484 phpbb.plupload.uploader.trigger('Error', {
485 code: plupload.FILE_SIZE_ERROR,
486 message: plupload.translate('File size error.'),
487 file: file
488 });
489
490 callback(false);
491 } else {
492 callback(true);
493 }
494 } else {
495 callback(true);
496 }
497
498 return false;
499 }
500 });
501 }
502 });
503
504 var $fileList = $('#file-list');
505
506 /**
507 * Insert inline attachment bbcode.
508 */
509 $fileList.on('click', '.file-inline-bbcode', function(e) {
510 var attachId = $(this).parents('.attach-row').attr('data-attach-id'),
511 index = phpbb.plupload.getIndex(attachId);
512
513 attachInline(index, phpbb.plupload.data[index].real_filename);
514 e.preventDefault();
515 });
516
517 /**
518 * Delete a file.
519 */
520 $fileList.on('click', '.file-delete', function(e) {
521 var row = $(this).parents('.attach-row'),
522 attachId = row.attr('data-attach-id');
523
524 phpbb.plupload.deleteFile(row, attachId);
525 e.preventDefault();
526 });
527
528 /**
529 * Display the error message for a particular file when the error icon is clicked.
530 */
531 $fileList.on('click', '.file-error', function(e) {
532 phpbb.alert($(this).attr('data-error-title'), $(this).attr('data-error-message'));
533 e.preventDefault();
534 });
535
536 /**
537 * Fires when an error occurs.
538 */
539 phpbb.plupload.uploader.bind('Error', function(up, error) {
540 error.file.name = plupload.xmlEncode(error.file.name);
541
542 // The error message that Plupload provides for these is vague, so we'll be more specific.
543 if (error.code === plupload.FILE_EXTENSION_ERROR) {
544 error.message = plupload.translate('Invalid file extension:') + ' ' + error.file.name;
545 } else if (error.code === plupload.FILE_SIZE_ERROR) {
546 error.message = plupload.translate('File too large:') + ' ' + error.file.name;
547 }
548 phpbb.alert(phpbb.plupload.lang.ERROR, error.message);
549 });
550
551 /**
552 * Fires before a given file is about to be uploaded. This allows us to
553 * send the real filename along with the chunk. This is necessary because
554 * for some reason the filename is set to 'blob' whenever a file is chunked
555 *
556 * @param {object} up The plupload.Uploader object
557 * @param {object} file The plupload.File object that is about to be uploaded
558 */
559 phpbb.plupload.uploader.bind('BeforeUpload', function(up, file) {
560 if (phpbb.plupload.handleMaxFilesReached()) {
561 return;
562 }
563
564 phpbb.plupload.updateMultipartParams({ real_filename: file.name });
565 });
566
567 /**
568 * Fired when a single chunk of any given file is uploaded. This parses the
569 * response from the server and checks for an error. If an error occurs it
570 * is reported to the user and the upload of this particular file is halted
571 *
572 * @param {object} up The plupload.Uploader object
573 * @param {object} file The plupload.File object whose chunk has just
574 * been uploaded
575 * @param {object} response The response object from the server
576 */
577 phpbb.plupload.uploader.bind('ChunkUploaded', function(up, file, response) {
578 if (response.chunk >= response.chunks - 1) {
579 return;
580 }
581
582 var json = {};
583 try {
584 json = $.parseJSON(response.response);
585 } catch (e) {
586 file.status = plupload.FAILED;
587 up.trigger('FileUploaded', file, {
588 response: JSON.stringify({
589 error: {
590 message: 'Error parsing server response.'
591 }
592 })
593 });
594 }
595
596 // If trigger_error() was called, then a permission error likely occurred.
597 if (typeof json.title !== 'undefined') {
598 json.error = { message: json.message };
599 }
600
601 if (json.error) {
602 file.status = plupload.FAILED;
603 up.trigger('FileUploaded', file, {
604 response: JSON.stringify({
605 error: {
606 message: json.error.message
607 }
608 })
609 });
610 }
611 });
612
613 /**
614 * Fires when files are added to the queue.
615 */
616 phpbb.plupload.uploader.bind('FilesAdded', function(up, files) {
617 // Prevent unnecessary requests to the server if the user already uploaded
618 // the maximum number of files allowed.
619 if (phpbb.plupload.handleMaxFilesReached()) {
620 return;
621 }
622
623 // Switch the active tab if the style supports it
624 if (typeof activateSubPanel === 'function') {
625 activateSubPanel('attach-panel'); // jshint ignore: line
626 }
627
628 // Show the file list if there aren't any files currently.
629 var $fileListContainer = $('#file-list-container');
630 if (!$fileListContainer.is(':visible')) {
631 $fileListContainer.show(100);
632 }
633
634 $.each(files, function(i, file) {
635 phpbb.plupload.insertRow(file);
636 });
637
638 up.bind('UploadProgress', function(up, file) {
639 $('.file-progress-bar', '#' + file.id).css('width', file.percent + '%');
640 $('#file-total-progress-bar').css('width', up.total.percent + '%');
641 });
642
643 // Do not allow more files to be added to the running queue.
644 phpbb.plupload.disableUploader();
645
646 // Start uploading the files once the user has selected them.
647 up.start();
648 });
649
650
651 /**
652 * Fires when an entire file has been uploaded. It checks for errors
653 * returned by the server otherwise parses the list of attachment data and
654 * appends it to the next file upload so that the server can maintain state
655 * with regards to the attachments in a given post
656 *
657 * @param {object} up The plupload.Uploader object
658 * @param {object} file The plupload.File object that has just been
659 * uploaded
660 * @param {string} response The response string from the server
661 */
662 phpbb.plupload.uploader.bind('FileUploaded', function(up, file, response) {
663 var json = {},
664 row = $('#' + file.id),
665 error;
666
667 // Hide the progress indicator.
668 row.find('.file-progress').hide();
669
670 try {
671 json = JSON.parse(response.response);
672 } catch (e) {
673 error = 'Error parsing server response.';
674 }
675
676 // If trigger_error() was called, then a permission error likely occurred.
677 if (typeof json.title !== 'undefined') {
678 error = json.message;
679 up.trigger('Error', { message: error });
680
681 // The rest of the queue will fail.
682 phpbb.plupload.markQueuedFailed(error);
683 } else if (json.error) {
684 error = json.error.message;
685 }
686
687 if (typeof error !== 'undefined') {
688 phpbb.plupload.fileError(file, error);
689 } else if (file.status === plupload.DONE) {
690 file.attachment_data = json.data[0];
691
692 row.attr('data-attach-id', file.attachment_data.attach_id);
693 row.find('.file-inline-bbcode').show();
694 row.find('.file-status').addClass('file-uploaded');
695 phpbb.plupload.update(json.data, 'addition', 0, [json.download_url]);
696 }
697 });
698
699 /**
700 * Fires when the entire queue of files have been uploaded.
701 */
702 phpbb.plupload.uploader.bind('UploadComplete', function() {
703 // Hide the progress bar
704 setTimeout(function() {
705 $('#file-total-progress-bar').fadeOut(500, function() {
706 $(this).css('width', 0).show();
707 });
708 }, 2000);
709
710 // Re-enable the uploader
711 phpbb.plupload.enableUploader();
712 });
713
714 })(jQuery); // Avoid conflicts with other libraries
715