| @@ -6,9 +6,9 @@ | ||
| 6 | 6 | * Main Uploader object. |
| 7 | 7 | */ |
| 8 | 8 | var Uploader = function( $dragdrop ) { |
| 9 | 9 | var self = this, |
| 10 | - params = $dragdrop.data('params'), | |
| 10 | + params = $dragdrop.data('params'), | |
| 11 | 11 | uploader = new plupload.Uploader( params ); |
| 12 | 12 | |
| 13 | 13 | this.$dragdrop = $dragdrop; |
| 14 | 14 | this.$dropzone = $(uploader.settings.drop_element); |
| @@ -34,9 +34,9 @@ | ||
| 34 | 34 | self.FileFiltered( uploader, files ); |
| 35 | 35 | }); |
| 36 | 36 | |
| 37 | 37 | uploader.bind( 'FilesAdded', function( uploader, files ) { |
| 38 | - self.FilesAdded( uploader, files ); | |
| 38 | + self.FilesAdded( uploader, files ); | |
| 39 | 39 | }); |
| 40 | 40 | |
| 41 | 41 | uploader.bind( 'Error', function( uploader, e ){ |
| 42 | 42 | console.log( e ); |
| @@ -42,9 +42,9 @@ | ||
| 42 | 42 | console.log( e ); |
| 43 | 43 | }); |
| 44 | 44 | |
| 45 | 45 | uploader.bind( 'FileUploaded', function( uploader, file, r ){ |
| 46 | - self.FileUploaded( uploader, file, r ); | |
| 46 | + self.FileUploaded( uploader, file, r ); | |
| 47 | 47 | }); |
| 48 | 48 | }; |
| 49 | 49 | |
| 50 | 50 | /** |
| @@ -56,9 +56,9 @@ | ||
| 56 | 56 | if ( ! this.$dropzone ) { |
| 57 | 57 | return; |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | - if ( uploader.features.dragdrop && ! this.$dragdrop.parent().hasClass('mobile') ) { | |
| 60 | + if ( uploader.features.dragdrop && ! this.$dragdrop.parent().hasClass('mobile') ) { | |
| 61 | 61 | this.$dragdrop.parent().addClass( 'supports-drag-drop' ); |
| 62 | 62 | |
| 63 | 63 | // We may need to enhance this to account for the issue noted |
| 64 | 64 | // in https://core.trac.wordpress.org/ticket/21705 |
| @@ -68,9 +68,9 @@ | ||
| 68 | 68 | |
| 69 | 69 | this.$dropzone.bind( 'dragleave', function(){ |
| 70 | 70 | self.$dropzone.removeClass('drag-over'); |
| 71 | 71 | }); |
| 72 | - } | |
| 72 | + } | |
| 73 | 73 | |
| 74 | 74 | // Set up image remove handler |
| 75 | 75 | this.$dragdrop.on( 'click', '.remove-image', function( e ) { |
| 76 | 76 | e.preventDefault(); |
| @@ -76,9 +76,9 @@ | ||
| 76 | 76 | e.preventDefault(); |
| 77 | 77 | return self.remove_image( $(this), uploader ); |
| 78 | 78 | }); |
| 79 | 79 | }; |
| 80 | - | |
| 80 | + | |
| 81 | 81 | /** |
| 82 | 82 | * FileFiltered event |
| 83 | 83 | */ |
| 84 | 84 | Uploader.prototype.FileFiltered = function( uploader, file ) { |
| @@ -88,9 +88,9 @@ | ||
| 88 | 88 | if ( full ) { |
| 89 | 89 | if ( ! this.max_uploads_alert_shown ) { |
| 90 | 90 | alert( this.get_max_uploads_message() ); |
| 91 | 91 | } |
| 92 | - | |
| 92 | + | |
| 93 | 93 | this.max_uploads_alert_shown = true; |
| 94 | 94 | return uploader.removeFile( file ); |
| 95 | 95 | } |
| 96 | 96 | |
| @@ -96,9 +96,9 @@ | ||
| 96 | 96 | |
| 97 | 97 | // If the file is too big, remove it and show a message. |
| 98 | 98 | if ( file.size >= this.max_file_size ) { |
| 99 | 99 | if ( ! this.max_upload_size_alert_shown ) { |
| 100 | - alert( file, CHARITABLE_UPLOAD_VARS.max_file_size.replace('%1$s', file.name).replace('%2$s', this.bytes_to_mb( this.max_file_size ) ) ); | |
| 100 | + alert( CHARITABLE_UPLOAD_VARS.max_file_size.replace('%1$s', file.name).replace('%2$s', this.bytes_to_mb( this.max_file_size ) ) ); | |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | this.max_upload_size_alert_shown = true; |
| 104 | 104 | return uploader.removeFile( file ); |
| @@ -112,9 +112,9 @@ | ||
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | this.add_image_loader( file ); |
| 115 | 115 | } |
| 116 | - | |
| 116 | + | |
| 117 | 117 | /** |
| 118 | 118 | * FilesAdded event |
| 119 | 119 | */ |
| 120 | 120 | Uploader.prototype.FilesAdded = function( uploader, files ) { |
| @@ -131,17 +131,24 @@ | ||
| 131 | 131 | /** |
| 132 | 132 | * FileUploaded event |
| 133 | 133 | */ |
| 134 | 134 | Uploader.prototype.FileUploaded = function( uploader, file, r ) { |
| 135 | - var input, data; | |
| 135 | + var input, data, message; | |
| 136 | 136 | |
| 137 | 137 | r = $.parseJSON( r.response ); |
| 138 | 138 | |
| 139 | 139 | if ( ! r.success ) { |
| 140 | 140 | |
| 141 | - this.add_image_error( file, CHARITABLE_UPLOAD_VARS.upload_problem.replace('%s', file.name) ); | |
| 141 | + // Show the server's own reason when it sends one - a refusal ("please log in") | |
| 142 | + // or a rejected file type is not something retrying can fix, so the generic | |
| 143 | + // "please try again" is only the fallback. Only data.message is trusted here: | |
| 144 | + // data.error carries WordPress core's raw upload errors, which name php.ini | |
| 145 | + // directives and server paths and must not be shown to public visitors. | |
| 146 | + message = r.data && typeof r.data.message === 'string' ? r.data.message : ''; | |
| 147 | + | |
| 148 | + this.add_image_error( file, message || CHARITABLE_UPLOAD_VARS.upload_problem.replace('%s', file.name) ); | |
| 142 | 149 | return; |
| 143 | - | |
| 150 | + | |
| 144 | 151 | } |
| 145 | 152 | |
| 146 | 153 | // Remove the image from the loader & possibly hide the loader. |
| 147 | 154 | this.hide_image_loader( file ); |
| @@ -170,9 +177,9 @@ | ||
| 170 | 177 | * @return void |
| 171 | 178 | */ |
| 172 | 179 | Uploader.prototype.add_image_loader = function( file ) { |
| 173 | 180 | this.$loader.fadeIn( 300 ) |
| 174 | - this.$loader.children('.images').append( '<li data-file-id="' + file.id + '" class="">' + file.name + '</li>' ); | |
| 181 | + this.$loader.children('.images').append( '<li data-file-id="' + file.id + '" class="">' + file.name + '</li>' ); | |
| 175 | 182 | }; |
| 176 | 183 | |
| 177 | 184 | /** |
| 178 | 185 | * Hide the image loader. |
| @@ -185,14 +192,14 @@ | ||
| 185 | 192 | this.$loader.find( '[data-file-id=' + file.id + ']' ).remove(); |
| 186 | 193 | |
| 187 | 194 | if ( ! this.$loader.find('.images li').length ) { |
| 188 | 195 | this.$loader.hide(); |
| 189 | - } | |
| 196 | + } | |
| 190 | 197 | }; |
| 191 | 198 | |
| 192 | 199 | /** |
| 193 | 200 | * Remove an image. |
| 194 | - * | |
| 201 | + * | |
| 195 | 202 | * @return void |
| 196 | 203 | */ |
| 197 | 204 | Uploader.prototype.remove_image = function($anchor, uploader) { |
| 198 | 205 | var $image = $anchor.parent(); |
| @@ -234,9 +241,9 @@ | ||
| 234 | 241 | * Dequeues the file and displays an error. |
| 235 | 242 | * |
| 236 | 243 | * @param object $loader |
| 237 | 244 | * @param object $dropzone |
| 238 | - * @param object file | |
| 245 | + * @param object file | |
| 239 | 246 | * @param string msg |
| 240 | 247 | * @return void |
| 241 | 248 | */ |
| 242 | 249 | Uploader.prototype.add_image_error = function( file, msg ) { |
| @@ -241,12 +248,20 @@ | ||
| 241 | 248 | */ |
| 242 | 249 | Uploader.prototype.add_image_error = function( file, msg ) { |
| 243 | 250 | var self = this; |
| 244 | 251 | |
| 252 | + // FileFiltered counted this file against max_file_uploads before it was sent. A | |
| 253 | + // failed upload never becomes a preview, so nothing else gives the slot back, and | |
| 254 | + // without this the next attempt is rejected client-side with the "you have already | |
| 255 | + // uploaded the maximum number of files" alert and the user is stuck until reload. | |
| 256 | + if ( self.uploaded > 0 ) { | |
| 257 | + self.uploaded -= 1; | |
| 258 | + } | |
| 259 | + | |
| 245 | 260 | self.$dropzone.fadeIn( 300 ); |
| 246 | 261 | |
| 247 | 262 | self.$loader.find( '[data-file-id=' + file.id + ']' ).addClass( 'error' ).text( msg ).delay( 5000 ).fadeOut( 300, function(){ |
| 248 | - self.hide_image_loader( file ); | |
| 263 | + self.hide_image_loader( file ); | |
| 249 | 264 | }); |
| 250 | 265 | } |
| 251 | 266 | |
| 252 | 267 | exports.Uploader = Uploader; |
| @@ -257,7 +272,7 @@ | ||
| 257 | 272 | $(document).ready( function() { |
| 258 | 273 | $('.charitable-drag-drop').each( function() { |
| 259 | 274 | new Uploader( $(this) ); |
| 260 | 275 | }); |
| 261 | - }); | |
| 276 | + }); | |
| 262 | 277 | |
| 263 | 278 | })( jQuery, CHARITABLE ); |