Allow the 'Uploaded to this post' view to be sorted, saving the resulting order as menu_order.
This functionality is designed to be backwards compatible with manual querying for attachments by menu_order. props koopersmith. see #22607. git-svn-id: http://core.svn.wordpress.org/trunk@22967 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
3cfc81b328
commit
27bf82201b
|
@ -56,7 +56,7 @@ $core_actions_post = array(
|
|||
'save-widget', 'set-post-thumbnail', 'date_format', 'time_format', 'wp-fullscreen-save-post',
|
||||
'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment',
|
||||
'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
|
||||
'send-attachment-to-editor',
|
||||
'send-attachment-to-editor', 'save-attachment-order',
|
||||
);
|
||||
|
||||
// Register core Ajax calls.
|
||||
|
|
|
@ -1927,6 +1927,39 @@ function wp_ajax_save_attachment_compat() {
|
|||
wp_send_json_success( $attachment );
|
||||
}
|
||||
|
||||
function wp_ajax_save_attachment_order() {
|
||||
if ( ! isset( $_REQUEST['post_id'] ) )
|
||||
wp_send_json_error();
|
||||
|
||||
if ( ! $post_id = absint( $_REQUEST['post_id'] ) )
|
||||
wp_send_json_error();
|
||||
|
||||
if ( empty( $_REQUEST['attachments'] ) )
|
||||
wp_send_json_error();
|
||||
|
||||
check_ajax_referer( 'update-post_' . $post_id, 'nonce' );
|
||||
|
||||
$attachments = $_REQUEST['attachments'];
|
||||
|
||||
if ( ! current_user_can( 'edit_post', $post_id ) )
|
||||
wp_send_json_error();
|
||||
|
||||
$post = get_post( $post_id, ARRAY_A );
|
||||
|
||||
foreach ( $attachments as $attachment_id => $menu_order ) {
|
||||
if ( ! current_user_can( 'edit_post', $attachment_id ) )
|
||||
continue;
|
||||
if ( ! $attachment = get_post( $attachment_id ) )
|
||||
continue;
|
||||
if ( 'attachment' != $attachment->post_type )
|
||||
continue;
|
||||
|
||||
wp_update_post( array( 'ID' => $attachment_id, 'menu_order' => $menu_order ) );
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the HTML to send an attachment to the editor.
|
||||
* Backwards compatible with the media_send_to_editor filter and the chain
|
||||
|
|
|
@ -523,6 +523,34 @@ window.wp = window.wp || {};
|
|||
_requery: function() {
|
||||
if ( this.props.get('query') )
|
||||
this.mirror( Query.get( this.props.toJSON() ) );
|
||||
},
|
||||
|
||||
// If this collection is sorted by `menuOrder`, recalculates and saves
|
||||
// the menu order to the database.
|
||||
saveMenuOrder: function() {
|
||||
if ( 'menuOrder' !== this.props.get('orderby') )
|
||||
return;
|
||||
|
||||
// Removes any uploading attachments, updates each attachment's
|
||||
// menu order, and returns an object with an { id: menuOrder }
|
||||
// mapping to pass to the request.
|
||||
var attachments = this.chain().filter( function( attachment ) {
|
||||
return ! _.isUndefined( attachment.id );
|
||||
}).map( function( attachment, index ) {
|
||||
// Indices start at 1.
|
||||
index = index + 1;
|
||||
attachment.set( 'menuOrder', index );
|
||||
return [ attachment.id, index ];
|
||||
}).object().value();
|
||||
|
||||
if ( _.isEmpty( attachments ) )
|
||||
return;
|
||||
|
||||
return media.post( 'save-attachment-order', {
|
||||
nonce: media.model.settings.updatePostNonce,
|
||||
post_id: media.model.settings.postId,
|
||||
attachments: attachments
|
||||
});
|
||||
}
|
||||
}, {
|
||||
comparator: function( a, b, options ) {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
// Copy the `postId` setting over to the model settings.
|
||||
media.model.settings.postId = media.view.settings.postId;
|
||||
media.model.settings.updatePostNonce = media.view.settings.nonce.updatePost;
|
||||
|
||||
// Check if the browser supports CSS 3.0 transitions
|
||||
$.support.transition = (function(){
|
||||
|
@ -267,7 +268,8 @@
|
|||
content: 'browse',
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
uploads: true
|
||||
uploads: true,
|
||||
sortable: true
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
|
@ -2690,7 +2692,6 @@
|
|||
this.scroll = _.chain( this.scroll ).bind( this ).throttle( this.options.refreshSensitivity ).value();
|
||||
|
||||
this.initSortable();
|
||||
this.collection.props.on( 'change:orderby', this.refreshSortable, this );
|
||||
|
||||
_.bindAll( this, 'css' );
|
||||
this.model.on( 'change:edge change:gutter', this.css, this );
|
||||
|
@ -2734,7 +2735,8 @@
|
|||
},
|
||||
|
||||
initSortable: function() {
|
||||
var collection = this.collection,
|
||||
var view = this,
|
||||
collection = this.collection,
|
||||
from;
|
||||
|
||||
if ( ! this.options.sortable || ! $.fn.sortable )
|
||||
|
@ -2760,14 +2762,30 @@
|
|||
// Update the model's index in the collection.
|
||||
// Do so silently, as the view is already accurate.
|
||||
update: function( event, ui ) {
|
||||
var model = collection.at( from );
|
||||
var model = collection.at( from ),
|
||||
comparator = collection.comparator;
|
||||
|
||||
// Temporarily disable the comparator to prevent `add`
|
||||
// from re-sorting.
|
||||
delete collection.comparator;
|
||||
|
||||
// Silently shift the model to its new index.
|
||||
collection.remove( model, {
|
||||
silent: true
|
||||
}).add( model, {
|
||||
at: ui.item.index(),
|
||||
silent: true
|
||||
});
|
||||
|
||||
// Restore the comparator.
|
||||
collection.comparator = comparator;
|
||||
|
||||
// If the collection is sorted by menu order,
|
||||
// update the menu order.
|
||||
view.saveMenuOrder();
|
||||
|
||||
// Make sure any menu-order-related callbacks are bound.
|
||||
view.refreshSortable();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2776,6 +2794,9 @@
|
|||
collection.props.on( 'change:orderby', function() {
|
||||
this.$el.sortable( 'option', 'disabled', !! collection.comparator );
|
||||
}, this );
|
||||
|
||||
this.collection.props.on( 'change:orderby', this.refreshSortable, this );
|
||||
this.refreshSortable();
|
||||
},
|
||||
|
||||
refreshSortable: function() {
|
||||
|
@ -2783,7 +2804,29 @@
|
|||
return;
|
||||
|
||||
// If the `collection` has a `comparator`, disable sorting.
|
||||
this.$el.sortable( 'option', 'disabled', !! this.collection.comparator );
|
||||
var collection = this.collection,
|
||||
orderby = collection.props.get('orderby'),
|
||||
enabled = 'menuOrder' === orderby || ! collection.comparator,
|
||||
hasMenuOrder;
|
||||
|
||||
this.$el.sortable( 'option', 'disabled', ! enabled );
|
||||
|
||||
// Check if any attachments have a specified menu order.
|
||||
hasMenuOrder = this.collection.any( function( attachment ) {
|
||||
return attachment.get('menuOrder');
|
||||
});
|
||||
|
||||
// Always unbind the `saveMenuOrder` callback to prevent multiple
|
||||
// callbacks stacking up.
|
||||
this.collection.off( 'change:uploading', this.saveMenuOrder, this );
|
||||
|
||||
if ( hasMenuOrder )
|
||||
this.collection.on( 'change:uploading', this.saveMenuOrder, this );
|
||||
|
||||
},
|
||||
|
||||
saveMenuOrder: function() {
|
||||
this.collection.saveMenuOrder();
|
||||
},
|
||||
|
||||
createAttachmentView: function( attachment ) {
|
||||
|
@ -3049,7 +3092,7 @@
|
|||
}).render() );
|
||||
}
|
||||
|
||||
if ( this.options.sortable ) {
|
||||
if ( this.options.sortable && ! this.options.filters ) {
|
||||
this.toolbar.set( 'dragInfo', new media.View({
|
||||
el: $( '<div class="instructions">' + l10n.dragInfo + '</div>' )[0],
|
||||
priority: -40
|
||||
|
|
|
@ -1433,6 +1433,7 @@ function wp_enqueue_media( $args = array() ) {
|
|||
if ( isset( $args['post'] ) ) {
|
||||
$post = get_post( $args['post'] );
|
||||
$settings['postId'] = $post->ID;
|
||||
$settings['nonce']['updatePost'] = wp_create_nonce( 'update-post_' . $post->ID );
|
||||
}
|
||||
|
||||
$hier = $post && is_post_type_hierarchical( $post->post_type );
|
||||
|
|
Loading…
Reference in New Issue