diff --git a/src/js/_enqueues/wp/util.js b/src/js/_enqueues/wp/util.js index b5ba1801d7..8384371173 100644 --- a/src/js/_enqueues/wp/util.js +++ b/src/js/_enqueues/wp/util.js @@ -115,7 +115,7 @@ window.wp = window.wp || {}; } if ( _.isObject( response ) && ! _.isUndefined( response.success ) ) { - deferred[ response.success ? 'resolveWith' : 'rejectWith' ]( this, [response.data] ); + deferred[ response.success ? 'resolveWith' : 'rejectWith' ]( deferred.jqXHR, [response.data] ); } else { deferred.rejectWith( this, [response] ); } diff --git a/src/js/media/models/attachments.js b/src/js/media/models/attachments.js index a0ba72869b..e06d719939 100644 --- a/src/js/media/models/attachments.js +++ b/src/js/media/models/attachments.js @@ -375,21 +375,15 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * passing through the JSON response. We override this to add attributes to * the collection items. * - * @since 5.8.0 The response returns the attachments under `response.attachments` and - * `response.totalAttachments` holds the total number of attachments found. - * * @param {Object|Array} response The raw response Object/Array. * @param {Object} xhr * @return {Array} The array of model attributes to be added to the collection */ parse: function( response, xhr ) { - if ( ! _.isArray( response.attachments ) ) { - response = [ response.attachments ]; + if ( ! _.isArray( response ) ) { + response = [response]; } - - this.totalAttachments = parseInt( response.totalAttachments, 10 ); - - return _.map( response.attachments, function( attrs ) { + return _.map( response, function( attrs ) { var id, attachment, newAttributes; if ( attrs instanceof Backbone.Model ) { @@ -409,9 +403,24 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen return attachment; }); }, + + // Customize fetch so we can extract the total post count from the response headers. + fetch: function(options) { + var collection = this; + var fetched = Backbone.Collection.prototype.fetch.call(this, options) + .done( function() { + if ( this.hasOwnProperty( 'getResponseHeader' ) ) { + collection.totalAttachments = parseInt( this.getResponseHeader( 'X-WP-Total' ), 10 ); + } else { + collection.totalAttachments = 0; + } + } ); + return fetched; + }, + /** * If the collection is a query, create and mirror an Attachments Query collection. - * + * * @access private * @param {Boolean} refresh Deprecated, refresh parameter no longer used. */ diff --git a/src/js/media/models/query.js b/src/js/media/models/query.js index d744537c44..1d56fed624 100644 --- a/src/js/media/models/query.js +++ b/src/js/media/models/query.js @@ -113,9 +113,7 @@ Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{ options.remove = false; return this._more = this.fetch( options ).done( function( response ) { - var attachments = response.attachments; - - if ( _.isEmpty( attachments ) || -1 === this.args.posts_per_page || attachments.length < this.args.posts_per_page ) { + if ( _.isEmpty( response ) || -1 === query.args.posts_per_page || response.length < query.args.posts_per_page ) { query._hasMore = false; } }); diff --git a/src/js/media/views/attachments/browser.js b/src/js/media/views/attachments/browser.js index 6a75fb9a7d..f91da5910b 100644 --- a/src/js/media/views/attachments/browser.js +++ b/src/js/media/views/attachments/browser.js @@ -88,6 +88,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro } this.updateContent(); + this.updateLoadMoreView(); if ( ! this.options.sidebar || 'errors' === this.options.sidebar ) { this.$el.addClass( 'hide-sidebar' ); @@ -635,11 +636,10 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro }); view.loadMoreSpinner.show(); - - this.collection.more().done( function() { - // Within done(), `this` is the returned collection. + this.collection.once( 'attachments:received', function() { view.loadMoreSpinner.hide(); } ); + this.collection.more(); }, /** diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index feb35ca40c..32e777e569 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -2990,17 +2990,27 @@ function wp_ajax_query_attachments() { * @param array $query An array of query variables. */ $query = apply_filters( 'ajax_query_attachments_args', $query ); - $query = new WP_Query( $query ); + $attachments_query = new WP_Query( $query ); - $posts = array_map( 'wp_prepare_attachment_for_js', $query->posts ); + $posts = array_map( 'wp_prepare_attachment_for_js', $attachments_query->posts ); $posts = array_filter( $posts ); + $total_posts = $attachments_query->found_posts; - $result = array( - 'attachments' => $posts, - 'totalAttachments' => $query->found_posts, - ); + if ( $total_posts < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $query['paged'] ); - wp_send_json_success( $result ); + $count_query = new WP_Query(); + $count_query->query( $query_args ); + $total_posts = $count_query->found_posts; + } + + $max_pages = ceil( $total_posts / (int) $attachments_query->query['posts_per_page'] ); + + header( 'X-WP-Total: ' . (int) $total_posts ); + header( 'X-WP-TotalPages: ' . (int) $max_pages ); + + wp_send_json_success( $posts ); } /**