Use JS Attachment models in wp.Uploader. fixes #21868.

Moves the uploading Attachments queue from the media workspace view to the uploader itself. This ensures that all attachments are added to the central attachmnet store.

Updates wp.Uploader to pass Attachment models to callbacks instead of Plupload file objects. Attachments in the process of uploading have a reference to the file object (which can be fetched by calling `attachment.get('file');`).

Also updates the customizer to be compatible with the API changes.


git-svn-id: http://core.svn.wordpress.org/trunk@21814 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Daryl Koopersmith 2012-09-11 16:55:58 +00:00
parent 87c947a987
commit 7fb2c8b4f7
5 changed files with 88 additions and 102 deletions

View File

@ -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() {

View File

@ -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 = $( '<a href="#" class="thumbnail"></a>' )
.data( 'customizeImageValue', attachment.url )
.append( '<img src="' + attachment.url+ '" />' )
.data( 'customizeImageValue', attachment.get('url') )
.append( '<img src="' + attachment.get('url')+ '" />' )
.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' );

View File

@ -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

View File

@ -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 );

View File

@ -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.