diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php
index b6dcca4bb5..5dbe74e23b 100644
--- a/wp-admin/includes/ajax-actions.php
+++ b/wp-admin/includes/ajax-actions.php
@@ -1611,12 +1611,12 @@ function wp_ajax_upload_attachment() {
check_ajax_referer( 'media-form' );
if ( ! current_user_can( 'upload_files' ) )
- wp_die( -1 );
+ wp_send_json_error();
if ( isset( $_REQUEST['post_id'] ) ) {
$post_id = $_REQUEST['post_id'];
if ( ! current_user_can( 'edit_post', $post_id ) )
- wp_die( -1 );
+ wp_send_json_error();
} else {
$post_id = null;
}
@@ -1626,14 +1626,10 @@ function wp_ajax_upload_attachment() {
$attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data );
if ( is_wp_error( $attachment_id ) ) {
- echo json_encode( array(
- 'type' => 'error',
- 'data' => array(
- 'message' => $attachment_id->get_error_message(),
- 'filename' => $_FILES['async-upload']['name'],
- ),
+ wp_send_json_error( array(
+ 'message' => $attachment_id->get_error_message(),
+ 'filename' => $_FILES['async-upload']['name'],
) );
- wp_die();
}
if ( isset( $post_data['context'] ) && isset( $post_data['theme'] ) ) {
@@ -1644,19 +1640,10 @@ function wp_ajax_upload_attachment() {
update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', $post_data['theme'] );
}
- $post = get_post( $attachment_id );
+ if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) )
+ wp_send_json_error();
- echo json_encode( array(
- 'type' => 'success',
- 'data' => array(
- 'id' => $attachment_id,
- 'title' => esc_attr( $post->post_title ),
- 'filename' => esc_html( basename( $post->guid ) ),
- 'url' => wp_get_attachment_url( $attachment_id ),
- 'meta' => wp_get_attachment_metadata( $attachment_id ),
- ),
- ) );
- wp_die();
+ wp_send_json_success( $attachment );
}
function wp_ajax_image_editor() {
diff --git a/wp-admin/js/customize-controls.js b/wp-admin/js/customize-controls.js
index 900ab13c01..12e0f16a7e 100644
--- a/wp-admin/js/customize-controls.js
+++ b/wp-admin/js/customize-controls.js
@@ -168,7 +168,7 @@
this.removerVisibility( this.setting.get() );
},
success: function( attachment ) {
- this.setting.set( attachment.url );
+ this.setting.set( attachment.get('url') );
},
removerVisibility: function( to ) {
this.remover.toggle( to != this.params.removed );
@@ -272,9 +272,10 @@
if ( this.tabs.uploaded && this.tabs.uploaded.target.length ) {
this.tabs.uploaded.both.removeClass('hidden');
+ // @todo: Do NOT store this on the attachment model. That is bad.
attachment.element = $( '' )
- .data( 'customizeImageValue', attachment.url )
- .append( '' )
+ .data( 'customizeImageValue', attachment.get('url') )
+ .append( '' )
.appendTo( this.tabs.uploaded.target );
}
},
@@ -945,16 +946,16 @@
api.ImageControl.prototype.success.call( control, attachment );
data = {
- attachment_id: attachment.id,
- url: attachment.url,
- thumbnail_url: attachment.url,
- height: attachment.meta.height,
- width: attachment.meta.width
+ attachment_id: attachment.get('id'),
+ url: attachment.get('url'),
+ thumbnail_url: attachment.get('url'),
+ height: attachment.get('height'),
+ width: attachment.get('width')
};
attachment.element.data( 'customizeHeaderImageData', data );
control.settings.data.set( data );
- }
+ };
});
api.trigger( 'ready' );
diff --git a/wp-includes/js/media-views.js b/wp-includes/js/media-views.js
index 032b5d85f2..49a33f750e 100644
--- a/wp-includes/js/media-views.js
+++ b/wp-includes/js/media-views.js
@@ -279,26 +279,14 @@
this.$content.append( this.attachmentsView.$el );
// Track uploading attachments.
- this.pending = new Attachments( [], { query: false });
- this.pending.on( 'add remove reset change:percent', function() {
- this.$el.toggleClass( 'uploading', !! this.pending.length );
-
- if ( ! this.$bar || ! this.pending.length )
- return;
-
- this.$bar.width( ( this.pending.reduce( function( memo, attachment ) {
- if ( attachment.get('uploading') )
- return memo + ( attachment.get('percent') || 0 );
- else
- return memo + 100;
- }, 0 ) / this.pending.length ) + '%' );
- }, this );
+ wp.Uploader.queue.on( 'add remove reset change:percent', this.renderUploadProgress, this );
},
render: function() {
this.attachmentsView.render();
+ this.renderUploadProgress();
this.$el.html( this.template( this.options ) ).append( this.$content );
- this.$bar = this.$('.media-progress-bar div');
+ this.$bar = this.$('.upload-attachments .media-progress-bar div');
return this;
},
@@ -312,46 +300,26 @@
this.uploader = new wp.Uploader( _.extend({
container: this.$el,
dropzone: this.$el,
- browser: this.$('.upload-attachments a'),
-
- added: function( file ) {
- file.attachment = Attachment.create( _.extend({
- file: file,
- uploading: true,
- date: new Date()
- }, _.pick( file, 'loaded', 'size', 'percent' ) ) );
-
- workspace.pending.add( file.attachment );
- },
-
- progress: function( file ) {
- file.attachment.set( _.pick( file, 'loaded', 'percent' ) );
- },
-
- success: function( resp, file ) {
- var complete;
-
- _.each(['file','loaded','size','uploading','percent'], function( key ) {
- file.attachment.unset( key );
- });
-
- file.attachment.set( 'id', resp.id );
- Attachment.get( resp.id, file.attachment ).fetch();
-
- complete = workspace.pending.all( function( attachment ) {
- return ! attachment.get('uploading');
- });
-
- if ( complete )
- workspace.pending.reset();
- },
-
- error: function( message, error, file ) {
- file.attachment.destroy();
- }
+ browser: this.$('.upload-attachments a')
}, this.options.uploader ) );
},
+ renderUploadProgress: function() {
+ var queue = wp.Uploader.queue;
+
+ this.$el.toggleClass( 'uploading', !! queue.length );
+
+ if ( ! this.$bar || ! queue.length )
+ return;
+
+ this.$bar.width( ( queue.reduce( function( memo, attachment ) {
+ if ( attachment.get('uploading') )
+ return memo + ( attachment.get('percent') || 0 );
+ else
+ return memo + 100;
+ }, 0 ) / queue.length ) + '%' );
+ },
+
// Initializes the toolbar view. Currently uses defaults set for
// inserting media into a post. This should be pulled out into the
// appropriate workflow when the time comes, but is currently here
diff --git a/wp-includes/js/plupload/wp-plupload.js b/wp-includes/js/plupload/wp-plupload.js
index e9ec49292a..31f21f6260 100644
--- a/wp-includes/js/plupload/wp-plupload.js
+++ b/wp-includes/js/plupload/wp-plupload.js
@@ -28,7 +28,7 @@ if ( typeof wp === 'undefined' )
browser: 'browse_button',
dropzone: 'drop_element'
},
- key;
+ key, error;
this.supports = {
upload: Uploader.browser.supported
@@ -84,6 +84,12 @@ if ( typeof wp === 'undefined' )
this.param( this.params || {} );
delete this.params;
+ error = function( message, data, file ) {
+ if ( file.attachment )
+ file.attachment.destroy();
+ self.error( message, data, file );
+ };
+
this.uploader.init();
this.supports.dragdrop = this.uploader.features.dragdrop && ! Uploader.browser.mobile;
@@ -134,26 +140,57 @@ if ( typeof wp === 'undefined' )
$('#' + this.uploader.id + '_html5_container').hide();
}
+ this.uploader.bind( 'FilesAdded', function( up, files ) {
+ _.each( files, function( file ) {
+ file.attachment = wp.media.model.Attachment.create( _.extend({
+ file: file,
+ uploading: true,
+ date: new Date()
+ }, _.pick( file, 'loaded', 'size', 'percent' ) ) );
+
+ Uploader.queue.add( file.attachment );
+
+ self.added( file.attachment );
+ });
+
+ up.refresh();
+ up.start();
+ });
+
this.uploader.bind( 'UploadProgress', function( up, file ) {
- self.progress( file );
+ file.attachment.set( _.pick( file, 'loaded', 'percent' ) );
+ self.progress( file.attachment );
});
this.uploader.bind( 'FileUploaded', function( up, file, response ) {
+ var complete;
+
try {
response = JSON.parse( response.response );
} catch ( e ) {
- return self.error( pluploadL10n.default_error, e );
+ return error( pluploadL10n.default_error, e, file );
}
- if ( ! response || ! response.type || ! response.data )
- return self.error( pluploadL10n.default_error );
+ if ( ! _.isObject( response ) || _.isUndefined( response.success ) )
+ return error( pluploadL10n.default_error, null, file );
+ else if ( ! response.success )
+ return error( response.data.message, response.data, file );
- if ( 'error' === response.type )
- return self.error( response.data.message, response.data, file );
+ _.each(['file','loaded','size','uploading','percent'], function( key ) {
+ file.attachment.unset( key );
+ });
- if ( 'success' === response.type )
- return self.success( response.data, file );
+ file.attachment.set( response.data );
+ wp.media.model.Attachment.get( response.data.id, file.attachment );
+ complete = Uploader.queue.all( function( attachment ) {
+ return ! attachment.get('uploading');
+ });
+
+ if ( complete )
+ Uploader.queue.reset();
+
+ self.success( file.attachment );
});
this.uploader.bind( 'Error', function( up, error ) {
@@ -168,19 +205,10 @@ if ( typeof wp === 'undefined' )
}
}
- self.error( message, error, error.file );
+ error( message, error, error.file );
up.refresh();
});
- this.uploader.bind( 'FilesAdded', function( up, files ) {
- $.each( files, function() {
- self.added( this );
- });
-
- up.refresh();
- up.start();
- });
-
this.init();
};
@@ -237,5 +265,7 @@ if ( typeof wp === 'undefined' )
}
});
+ Uploader.queue = new wp.media.model.Attachments( [], { query: false });
+
exports.Uploader = Uploader;
})( wp, jQuery );
diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php
index 5fdc7e5335..6a03efeb29 100644
--- a/wp-includes/script-loader.php
+++ b/wp-includes/script-loader.php
@@ -232,7 +232,7 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'plupload-handlers', "/wp-includes/js/plupload/handlers$suffix.js", array('plupload-all', 'jquery') );
did_action( 'init' ) && $scripts->localize( 'plupload-handlers', 'pluploadL10n', $uploader_l10n );
- $scripts->add( 'wp-plupload', "/wp-includes/js/plupload/wp-plupload$suffix.js", array('plupload-all', 'jquery', 'json2') );
+ $scripts->add( 'wp-plupload', "/wp-includes/js/plupload/wp-plupload$suffix.js", array('plupload-all', 'jquery', 'json2', 'media-models'), false, 1 );
did_action( 'init' ) && $scripts->localize( 'wp-plupload', 'pluploadL10n', $uploader_l10n );
// keep 'swfupload' for back-compat.