From d9e099418464c2e433725a139f6c5330672b150e Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Fri, 4 Oct 2013 19:41:46 +0200 Subject: [PATCH] Changing multiple file uploads to properly support iOS 6+ --- wcfsetup/install/files/js/WCF.Attachment.js | 24 ++++++++-------- wcfsetup/install/files/js/WCF.js | 28 +++++++++---------- .../attachment/AttachmentAction.class.php | 13 +++++---- .../lib/system/upload/UploadFile.class.php | 20 +++++++++++++ .../lib/system/upload/UploadHandler.class.php | 20 +++++++++++++ 5 files changed, 74 insertions(+), 31 deletions(-) diff --git a/wcfsetup/install/files/js/WCF.Attachment.js b/wcfsetup/install/files/js/WCF.Attachment.js index b17355fb91..9b05e28629 100644 --- a/wcfsetup/install/files/js/WCF.Attachment.js +++ b/wcfsetup/install/files/js/WCF.Attachment.js @@ -164,7 +164,7 @@ WCF.Attachment.Upload = WCF.Upload.extend({ * @see WCF.Upload._success() */ _success: function(uploadID, data) { - for (var $i = 0; $i < this._uploadMatrix[uploadID].length; $i++) { + for (var $i in this._uploadMatrix[uploadID]) { // get li var $li = this._uploadMatrix[uploadID][$i]; @@ -173,10 +173,11 @@ WCF.Attachment.Upload = WCF.Upload.extend({ // get filename and check result var $filename = $li.data('filename'); - if (data.returnValues && data.returnValues['attachments'][$filename]) { + var $internalFileID = $li.data('internalFileID'); + if (data.returnValues && data.returnValues.attachments[$internalFileID]) { // show thumbnail - if (data.returnValues['attachments'][$filename]['tinyURL']) { - $li.children('.icon-spinner').replaceWith($('')); + if (data.returnValues.attachments[$internalFileID]['tinyURL']) { + $li.children('.icon-spinner').replaceWith($('')); } // show file icon else { @@ -185,23 +186,22 @@ WCF.Attachment.Upload = WCF.Upload.extend({ // update attachment link var $link = $(''); - $link.text($filename).attr('href', data.returnValues['attachments'][$filename]['url']); + $link.text($filename).attr('href', data.returnValues.attachments[$internalFileID]['url']); - if (data.returnValues['attachments'][$filename]['isImage'] != 0) { - console.debug(data.returnValues['attachments'][$filename]['isImage']); + if (data.returnValues.attachments[$internalFileID]['isImage'] != 0) { $link.addClass('jsImageViewer').attr('title', $filename); } $li.find('p').empty().append($link); // update file size - $li.find('small').append(data.returnValues['attachments'][$filename]['formattedFilesize']); + $li.find('small').append(data.returnValues.attachments[$internalFileID]['formattedFilesize']); // init buttons - var $deleteButton = $('
  • '); + var $deleteButton = $('
  • '); $li.find('ul').append($deleteButton); if (this._wysiwygContainerID) { - var $insertButton = $('
  • '); + var $insertButton = $('
  • '); $insertButton.children('.jsButtonInsertAttachment').click($.proxy(this._insert, this)); $li.find('ul').append($insertButton); } @@ -212,8 +212,8 @@ WCF.Attachment.Upload = WCF.Upload.extend({ var $errorMessage = ''; // error handling - if (data.returnValues && data.returnValues['errors'][$filename]) { - $errorMessage = data.returnValues['errors'][$filename]['errorType']; + if (data.returnValues && data.returnValues.errors[$internalFileID]) { + $errorMessage = data.returnValues.errors[$internalFileID]['errorType']; } else { // unknown error diff --git a/wcfsetup/install/files/js/WCF.js b/wcfsetup/install/files/js/WCF.js index 955ec19c91..ba4999f781 100755 --- a/wcfsetup/install/files/js/WCF.js +++ b/wcfsetup/install/files/js/WCF.js @@ -6678,6 +6678,12 @@ WCF.Upload = Class.extend({ */ _iframe: null, + /** + * internal file id + * @var integer + */ + _internalFileID: 0, + /** * additional options * @var jQuery @@ -6714,6 +6720,7 @@ WCF.Upload = Class.extend({ this._buttonSelector = buttonSelector; this._fileListSelector = fileListSelector; this._className = className; + this._internalFileID = 0; this._options = $.extend(true, { action: 'upload', multiple: false, @@ -6781,17 +6788,10 @@ WCF.Upload = Class.extend({ return; } - var $validFilenames = [ ]; - for (var $i = 0, $length = this._uploadMatrix[$uploadID].length; $i < $length; $i++) { - var $li = this._uploadMatrix[$uploadID][$i]; - if (!$li.hasClass('uploadFailed')) { - $validFilenames.push($li.data('filename')); - } - } - for (var $i = 0, $length = $files.length; $i < $length; $i++) { - if ($validFilenames.indexOf($files[$i].name) !== -1) { - $fd.append('__files[]', $files[$i]); + if (this._uploadMatrix[$uploadID][$i]) { + var $internalFileID = this._uploadMatrix[$uploadID][$i].data('internalFileID'); + $fd.append('__files[' + $internalFileID + ']', $files[$i]); } } @@ -6799,7 +6799,7 @@ WCF.Upload = Class.extend({ $fd.append('className', this._className); var $additionalParameters = this._getParameters(); for (var $name in $additionalParameters) { - $fd.append('parameters['+$name+']', $additionalParameters[$name]); + $fd.append('parameters[' + $name + ']', $additionalParameters[$name]); } var self = this; @@ -6843,8 +6843,8 @@ WCF.Upload = Class.extend({ var $li = this._initFile($file); if (!$li.hasClass('uploadFailed')) { - $li.data('filename', $file.name); - this._uploadMatrix[$uploadID].push($li); + $li.data('filename', $file.name).data('internalFileID', this._internalFileID++); + this._uploadMatrix[$uploadID][$i] = $li; } } @@ -6880,7 +6880,7 @@ WCF.Upload = Class.extend({ _progress: function(uploadID, event) { var $percentComplete = Math.round(event.loaded * 100 / event.total); - for (var $i = 0; $i < this._uploadMatrix[uploadID].length; $i++) { + for (var $i in this._uploadMatrix[uploadID]) { this._uploadMatrix[uploadID][$i].find('progress').attr('value', $percentComplete); } }, diff --git a/wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php b/wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php index fe81958140..2312d37e3f 100644 --- a/wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php +++ b/wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php @@ -173,7 +173,7 @@ class AttachmentAction extends AbstractDatabaseObjectAction { EventHandler::getInstance()->fireAction($this, 'checkThumbnail'); if ($this->eventData['hasThumbnail']) $thumbnails[] = $attachment; } - $attachments[] = $attachment; + $attachments[$file->getInternalFileID()] = $attachment; } else { // moving failed; delete attachment @@ -194,8 +194,11 @@ class AttachmentAction extends AbstractDatabaseObjectAction { $result = array('attachments' => array(), 'errors' => array()); if (!empty($attachments)) { // get attachment ids - $attachmentIDs = array(); - foreach ($attachments as $attachment) $attachmentIDs[] = $attachment->attachmentID; + $attachmentIDs = $attachmentToFileID = array(); + foreach ($attachments as $internalFileID => $attachment) { + $attachmentIDs[] = $attachment->attachmentID; + $attachmentToFileID[$attachment->attachmentID] = $internalFileID; + } // get attachments from database (check thumbnail status) $attachmentList = new AttachmentList(); @@ -203,7 +206,7 @@ class AttachmentAction extends AbstractDatabaseObjectAction { $attachmentList->readObjects(); foreach ($attachmentList as $attachment) { - $result['attachments'][$attachment->filename] = array( + $result['attachments'][$attachmentToFileID[$attachment->attachmentID]] = array( 'filename' => $attachment->filename, 'filesize' => $attachment->filesize, 'formattedFilesize' => FileUtil::formatFilesize($attachment->filesize), @@ -217,7 +220,7 @@ class AttachmentAction extends AbstractDatabaseObjectAction { } foreach ($failedUploads as $failedUpload) { - $result['errors'][$failedUpload->getFilename()] = array( + $result['errors'][$failedUpload->getInternalFileID()] = array( 'filename' => $failedUpload->getFilename(), 'filesize' => $failedUpload->getFilesize(), 'errorType' => $failedUpload->getValidationErrorType() diff --git a/wcfsetup/install/files/lib/system/upload/UploadFile.class.php b/wcfsetup/install/files/lib/system/upload/UploadFile.class.php index f6b405a925..4abed6f235 100644 --- a/wcfsetup/install/files/lib/system/upload/UploadFile.class.php +++ b/wcfsetup/install/files/lib/system/upload/UploadFile.class.php @@ -19,6 +19,12 @@ class UploadFile { */ protected $filename = ''; + /** + * internal file id + * @var integer + */ + protected $internalFileID = 0; + /** * location of the uploaded file * @var string @@ -59,6 +65,11 @@ class UploadFile { * @param string $mimeType */ public function __construct($filename, $location, $filesize, $errorCode = 0, $mimeType = '') { + if (preg_match('~^__wcf_([0-9]+)_(.*)~', $filename, $matches)) { + $this->internalFileID = $matches[1]; + $filename = $matches[2]; + } + $this->filename = $filename; $this->location = $location; $this->filesize = $filesize; @@ -75,6 +86,15 @@ class UploadFile { return $this->filename; } + /** + * Returns internal file id. + * + * @return integer + */ + public function getInternalFileID() { + return $this->internalFileID; + } + /** * Returns the extension of the original file name. * diff --git a/wcfsetup/install/files/lib/system/upload/UploadHandler.class.php b/wcfsetup/install/files/lib/system/upload/UploadHandler.class.php index 605a3e5c8d..6d1a4d038a 100644 --- a/wcfsetup/install/files/lib/system/upload/UploadHandler.class.php +++ b/wcfsetup/install/files/lib/system/upload/UploadHandler.class.php @@ -32,6 +32,26 @@ class UploadHandler { */ protected function __construct(array $rawFileData) { if (is_array($rawFileData['name'])) { + // iOS work-around + $newRawFileData = array( + 'name' => array(), + 'type' => array(), + 'tmp_name' => array(), + 'error' => array(), + 'size' => array() + ); + $i = 0; + foreach (array_keys($rawFileData['name']) as $internalFileID) { + $newRawFileData['name'][$i] = '__wcf_' . $internalFileID . '_' . $rawFileData['name'][$internalFileID]; // __wcf_X_filename.ext + $newRawFileData['type'][$i] = $rawFileData['type'][$internalFileID]; + $newRawFileData['tmp_name'][$i] = $rawFileData['tmp_name'][$internalFileID]; + $newRawFileData['error'][$i] = $rawFileData['error'][$internalFileID]; + $newRawFileData['size'][$i] = $rawFileData['size'][$internalFileID]; + + $i++; + } + $rawFileData = $newRawFileData; + // multiple uploads for ($i = 0, $l = count($rawFileData['name']); $i < $l; $i++) { $this->files[] = new UploadFile($rawFileData['name'][$i], $rawFileData['tmp_name'][$i], $rawFileData['size'][$i], $rawFileData['error'][$i], ($rawFileData['tmp_name'][$i] ? (FileUtil::getMimeType($rawFileData['tmp_name'][$i]) ?: $rawFileData['type'][$i]) : '')); -- 2.20.1