WordPress.org

Make WordPress Core

Changeset 22967


Ignore:
Timestamp:
12/02/2012 04:06:31 PM (5 years ago)
Author:
nacin
Message:

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.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/admin-ajax.php

    r22872 r22967  
    5757    'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment',
    5858    'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
    59     'send-attachment-to-editor',
     59    'send-attachment-to-editor', 'save-attachment-order',
    6060);
    6161
  • trunk/wp-admin/includes/ajax-actions.php

    r22954 r22967  
    19281928}
    19291929
     1930function wp_ajax_save_attachment_order() {
     1931    if ( ! isset( $_REQUEST['post_id'] ) )
     1932        wp_send_json_error();
     1933
     1934    if ( ! $post_id = absint( $_REQUEST['post_id'] ) )
     1935        wp_send_json_error();
     1936
     1937    if ( empty( $_REQUEST['attachments'] ) )
     1938        wp_send_json_error();
     1939
     1940    check_ajax_referer( 'update-post_' . $post_id, 'nonce' );
     1941
     1942    $attachments = $_REQUEST['attachments'];
     1943
     1944    if ( ! current_user_can( 'edit_post', $post_id ) )
     1945        wp_send_json_error();
     1946
     1947    $post = get_post( $post_id, ARRAY_A );
     1948
     1949    foreach ( $attachments as $attachment_id => $menu_order ) {
     1950        if ( ! current_user_can( 'edit_post', $attachment_id ) )
     1951            continue;
     1952        if ( ! $attachment = get_post( $attachment_id ) )
     1953            continue;
     1954        if ( 'attachment' != $attachment->post_type )
     1955            continue;
     1956
     1957        wp_update_post( array( 'ID' => $attachment_id, 'menu_order' => $menu_order ) );
     1958    }
     1959
     1960    wp_send_json_success();
     1961}
     1962
    19301963/**
    19311964 * Generates the HTML to send an attachment to the editor.
  • trunk/wp-includes/js/media-models.js

    r22956 r22967  
    524524            if ( this.props.get('query') )
    525525                this.mirror( Query.get( this.props.toJSON() ) );
     526        },
     527
     528        // If this collection is sorted by `menuOrder`, recalculates and saves
     529        // the menu order to the database.
     530        saveMenuOrder: function() {
     531            if ( 'menuOrder' !== this.props.get('orderby') )
     532                return;
     533
     534            // Removes any uploading attachments, updates each attachment's
     535            // menu order, and returns an object with an { id: menuOrder }
     536            // mapping to pass to the request.
     537            var attachments = this.chain().filter( function( attachment ) {
     538                return ! _.isUndefined( attachment.id );
     539            }).map( function( attachment, index ) {
     540                // Indices start at 1.
     541                index = index + 1;
     542                attachment.set( 'menuOrder', index );
     543                return [ attachment.id, index ];
     544            }).object().value();
     545
     546            if ( _.isEmpty( attachments ) )
     547                return;
     548
     549            return media.post( 'save-attachment-order', {
     550                nonce:       media.model.settings.updatePostNonce,
     551                post_id:     media.model.settings.postId,
     552                attachments: attachments
     553            });
    526554        }
    527555    }, {
  • trunk/wp-includes/js/media-views.js

    r22965 r22967  
    1515    // Copy the `postId` setting over to the model settings.
    1616    media.model.settings.postId = media.view.settings.postId;
     17    media.model.settings.updatePostNonce = media.view.settings.nonce.updatePost;
    1718
    1819    // Check if the browser supports CSS 3.0 transitions
     
    268269            searchable: true,
    269270            filterable: false,
    270             uploads:    true
     271            uploads:    true,
     272            sortable:   true
    271273        },
    272274
     
    26912693
    26922694            this.initSortable();
    2693             this.collection.props.on( 'change:orderby', this.refreshSortable, this );
    26942695
    26952696            _.bindAll( this, 'css' );
     
    27352736
    27362737        initSortable: function() {
    2737             var collection = this.collection,
     2738            var view = this,
     2739                collection = this.collection,
    27382740                from;
    27392741
     
    27612763                // Do so silently, as the view is already accurate.
    27622764                update: function( event, ui ) {
    2763                     var model = collection.at( from );
    2764 
     2765                    var model = collection.at( from ),
     2766                        comparator = collection.comparator;
     2767
     2768                    // Temporarily disable the comparator to prevent `add`
     2769                    // from re-sorting.
     2770                    delete collection.comparator;
     2771
     2772                    // Silently shift the model to its new index.
    27652773                    collection.remove( model, {
    27662774                        silent: true
     
    27692777                        silent: true
    27702778                    });
     2779
     2780                    // Restore the comparator.
     2781                    collection.comparator = comparator;
     2782
     2783                    // If the collection is sorted by menu order,
     2784                    // update the menu order.
     2785                    view.saveMenuOrder();
     2786
     2787                    // Make sure any menu-order-related callbacks are bound.
     2788                    view.refreshSortable();
    27712789                }
    27722790            });
     
    27772795                this.$el.sortable( 'option', 'disabled', !! collection.comparator );
    27782796            }, this );
     2797
     2798            this.collection.props.on( 'change:orderby', this.refreshSortable, this );
     2799            this.refreshSortable();
    27792800        },
    27802801
     
    27842805
    27852806            // If the `collection` has a `comparator`, disable sorting.
    2786             this.$el.sortable( 'option', 'disabled', !! this.collection.comparator );
     2807            var collection = this.collection,
     2808                orderby = collection.props.get('orderby'),
     2809                enabled = 'menuOrder' === orderby || ! collection.comparator,
     2810                hasMenuOrder;
     2811
     2812            this.$el.sortable( 'option', 'disabled', ! enabled );
     2813
     2814            // Check if any attachments have a specified menu order.
     2815            hasMenuOrder = this.collection.any( function( attachment ) {
     2816                return attachment.get('menuOrder');
     2817            });
     2818
     2819            // Always unbind the `saveMenuOrder` callback to prevent multiple
     2820            // callbacks stacking up.
     2821            this.collection.off( 'change:uploading', this.saveMenuOrder, this );
     2822
     2823            if ( hasMenuOrder )
     2824                this.collection.on( 'change:uploading', this.saveMenuOrder, this );
     2825
     2826        },
     2827
     2828        saveMenuOrder: function() {
     2829            this.collection.saveMenuOrder();
    27872830        },
    27882831
     
    30503093            }
    30513094
    3052             if ( this.options.sortable ) {
     3095            if ( this.options.sortable && ! this.options.filters ) {
    30533096                this.toolbar.set( 'dragInfo', new media.View({
    30543097                    el: $( '<div class="instructions">' + l10n.dragInfo + '</div>' )[0],
  • trunk/wp-includes/media.php

    r22948 r22967  
    14341434        $post = get_post( $args['post'] );
    14351435        $settings['postId'] = $post->ID;
     1436        $settings['nonce']['updatePost'] = wp_create_nonce( 'update-post_' . $post->ID );
    14361437    }
    14371438
Note: See TracChangeset for help on using the changeset viewer.