Skip to content

Commit

Permalink
Permit unbounded per_page=-1 requests for Categories and Tags
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbachhuber committed May 11, 2018
1 parent 368dc63 commit c204bb6
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 3 deletions.
2 changes: 1 addition & 1 deletion core-data/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { getEntity } from './entities';
*/
export async function* getCategories() {
yield setRequested( 'terms', 'categories' );
const categories = await apiRequest( { path: '/wp/v2/categories' } );
const categories = await apiRequest( { path: '/wp/v2/categories?per_page=-1' } );
yield receiveTerms( 'categories', categories );
}

Expand Down
2 changes: 1 addition & 1 deletion editor/components/post-taxonomies/flat-term-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { withSelect, withDispatch } from '@wordpress/data';
* Module constants
*/
const DEFAULT_QUERY = {
per_page: 100,
per_page: -1,
orderby: 'count',
order: 'desc',
_fields: 'id,name',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { withSelect, withDispatch } from '@wordpress/data';
* Module Constants
*/
const DEFAULT_QUERY = {
per_page: 100,
per_page: -1,
orderby: 'count',
order: 'desc',
_fields: 'id,name,parent',
Expand Down
58 changes: 58 additions & 0 deletions lib/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,17 @@ function gutenberg_register_post_prepare_functions( $post_type ) {
}
add_filter( 'registered_post_type', 'gutenberg_register_post_prepare_functions' );

/**
* Whenever a taxonomy is registered, ensure we're hooked into its WP REST API response.
*
* @param string $taxonomy The newly registered taxonomy.
*/
function gutenberg_register_taxonomy_prepare_functions( $taxonomy ) {
add_filter( "rest_{$taxonomy}_collection_params", 'gutenberg_filter_term_collection_parameters', 10, 2 );
add_filter( "rest_{$taxonomy}_query", 'gutenberg_filter_term_query_arguments', 10, 2 );
}
add_filter( 'registered_taxonomy', 'gutenberg_register_taxonomy_prepare_functions' );

/**
* Includes the value for the 'viewable' attribute of a post type resource.
*
Expand Down Expand Up @@ -465,6 +476,8 @@ function gutenberg_ensure_wp_json_has_theme_supports( $response ) {
function gutenberg_handle_early_callback_checks( $response, $handler, $request ) {
$routes = array(
'/wp/v2/blocks',
'/wp/v2/categories',
'/wp/v2/tags',
'/wp/v2/pages',
'/wp/v2/users',
);
Expand Down Expand Up @@ -538,6 +551,51 @@ function gutenberg_filter_post_query_arguments( $prepared_args, $request ) {
return $prepared_args;
}

/**
* Include additional query parameters on the terms query endpoint.
*
* @see https://core.trac.wordpress.org/ticket/43998
*
* @param array $query_params JSON Schema-formatted collection parameters.
* @param object $taxonomy Taxonomy being accessed.
* @return array
*/
function gutenberg_filter_term_collection_parameters( $query_params, $taxonomy ) {
$taxonomies = array( 'category', 'post_tag' );
if ( in_array( $taxonomy->name, $taxonomies, true )
&& isset( $query_params['per_page'] ) ) {
// Change from '1' to '-1', which means unlimited.
$query_params['per_page']['minimum'] = -1;
// Default sanitize callback is 'absint', which won't work in our case.
$query_params['per_page']['sanitize_callback'] = 'rest_sanitize_request_arg';
}
return $query_params;
}

/**
* Filter term collection query parameters to include specific behavior.
*
* @see https://core.trac.wordpress.org/ticket/43998
*
* @param array $prepared_args Array of arguments for WP_Term_Query.
* @param WP_REST_Request $request The current request.
* @return array
*/
function gutenberg_filter_term_query_arguments( $prepared_args, $request ) {
// Can't check the actual taxonomy here because it's not
// passed through in $prepared_args (or the filter generally).
if ( 0 === strpos( $request->get_route(), '/wp/v2/' ) ) {
if ( -1 === $prepared_args['number'] ) {
// This should be unset( $prepared_args['number'] )
// but WP_REST_Terms Controller needs to be updated to support
// unbounded queries.
// Will be addressed in https://core.trac.wordpress.org/ticket/43998.
$prepared_args['number'] = 100000;
}
}
return $prepared_args;
}

/**
* Include additional query parameters on the user query endpoint.
*
Expand Down
20 changes: 20 additions & 0 deletions phpunit/class-gutenberg-rest-api-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,26 @@ public function test_get_items_unbounded_per_page_unauthorized() {
$this->assertEquals( 'rest_forbidden_per_page', $data['code'] );
}

public function test_get_categories_unbounded_per_page() {
wp_set_current_user( $this->author );
$this->factory->category->create();
$request = new WP_REST_Request( 'GET', '/wp/v2/categories' );
$request->set_param( 'per_page', '-1' );
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );
}

public function test_get_categories_unbounded_per_page_unauthorized() {
wp_set_current_user( $this->subscriber );
$this->factory->category->create();
$request = new WP_REST_Request( 'GET', '/wp/v2/categories' );
$request->set_param( 'per_page', '-1' );
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 403, $response->get_status() );
$data = $response->get_data();
$this->assertEquals( 'rest_forbidden_per_page', $data['code'] );
}

public function test_get_pages_unbounded_per_page() {
wp_set_current_user( $this->author );
$this->factory->post->create( array( 'post_type' => 'page' ) );
Expand Down

0 comments on commit c204bb6

Please sign in to comment.