REST API: Set maximum 'per_page' for embedded REST API requests.

This enhancement refines the REST API server to automatically establish the maximum 'per_page' value for embedded objects, adhering to the endpoint's schema when not explicitly defined in the request. This adjustment elevates the limit from the default of 10 items to 100 items, significantly improving the likelihood of receiving the complete dataset of embedded objects.

Props manyourisms, lpawlik, spacedmonkey, kadamwhite, TimothyBlynJacobs. 
Fixes #43439.

git-svn-id: https://develop.svn.wordpress.org/trunk@57623 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jonny Harris 2024-02-13 13:46:45 +00:00
parent 1d4eff1303
commit 2480e16d99
3 changed files with 58 additions and 0 deletions

View File

@ -743,6 +743,13 @@ class WP_REST_Server {
continue;
}
if ( empty( $request['per_page'] ) ) {
$matched = $this->match_request_to_handler( $request );
if ( ! is_wp_error( $matched ) && isset( $matched[1]['args']['per_page']['maximum'] ) ) {
$request['per_page'] = (int) $matched[1]['args']['per_page']['maximum'];
}
}
// Embedded resources get passed context=embed.
if ( empty( $request['context'] ) ) {
$request['context'] = 'embed';

View File

@ -18,6 +18,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
protected static $supported_formats;
protected static $post_ids = array();
protected static $terms = array();
protected static $total_posts = 30;
protected static $per_page = 50;
@ -28,6 +29,8 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
self::$post_id = $factory->post->create();
self::$terms = $factory->term->create_many( 15, array( 'taxonomy' => 'category' ) );
wp_set_object_terms( self::$post_id, self::$terms, 'category' );
self::$superadmin_id = $factory->user->create(
array(
@ -223,6 +226,21 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
$this->assertSame( array( 'context', 'id', 'password' ), $keys );
}
public function test_registered_get_items_embed() {
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
$request->set_param( 'include', array( self::$post_id ) );
$response = rest_get_server()->dispatch( $request );
$response = rest_get_server()->response_to_data( $response, true );
$this->assertArrayHasKey( '_embedded', $response[0], 'The _embedded key must exist' );
$this->assertArrayHasKey( 'wp:term', $response[0]['_embedded'], 'The wp:term key must exist' );
$this->assertCount( 15, $response[0]['_embedded']['wp:term'][0], 'Should should be 15 terms and not the default 10' );
$i = 0;
foreach ( $response[0]['_embedded']['wp:term'][0] as $term ) {
$this->assertSame( self::$terms[ $i ], $term['id'], 'Check term id existing in response' );
++$i;
}
}
/**
* @ticket 43701
*/

View File

@ -931,6 +931,39 @@ class Tests_REST_Server extends WP_Test_REST_TestCase {
$this->assertSame( 'data', $result['untouched'] );
}
/**
* Ensure embedding is with links in the data.
*
* @ticket 43439
*/
public function test_link_embedding_with_links() {
$data = array(
'_links' => array(
'wp:term' => array(
array(
'taxonomy' => 'category',
'embeddable' => true,
'href' => get_rest_url( 0, '/wp/v2/categories' ),
),
array(
'taxonomy' => 'post_tag',
'embeddable' => true,
'href' => get_rest_url( 0, '/wp/v2/tags' ),
),
),
),
);
$mock = new MockAction();
add_filter( 'rest_post_dispatch', array( $mock, 'filter' ), 10, 3 );
rest_get_server()->embed_links( $data, true );
$args = $mock->get_args();
foreach ( $args as $arg ) {
$this->assertSame( 100, $arg[2]['per_page'], 'Posts per page should be 100' );
}
}
/**
* Ensure embed_links handles WP_Error objects returned by dispatch
*