REST API: Add support for the ignore_sticky_posts argument.

Introduce `ignore_sticky` as a boolean argument for the posts endpoint for requests without the sticky posts being stuck. The new argument defaults to `false` with the value of the argument passed to `WP_Query`'s `ignore_sticky_posts` parameter.

Props audrasjb, danielbachhuber, joemcgill, johnbillion, jorbin, mamaduka, rmccue.
Fixes #35907.



git-svn-id: https://develop.svn.wordpress.org/trunk@59801 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Peter Wilson 2025-02-10 22:21:51 +00:00
parent 9160fbd2f6
commit f71d5f06b2
3 changed files with 87 additions and 0 deletions

View File

@ -247,6 +247,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
'author_exclude' => 'author__not_in',
'exclude' => 'post__not_in',
'include' => 'post__in',
'ignore_sticky' => 'ignore_sticky_posts',
'menu_order' => 'menu_order',
'offset' => 'offset',
'order' => 'order',
@ -337,6 +338,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
}
}
/*
* Honor the original REST API `post__in` behavior. Don't prepend sticky posts
* when `post__in` has been specified.
*/
if ( ! empty( $args['post__in'] ) ) {
unset( $args['ignore_sticky_posts'] );
}
if (
isset( $registered['search_semantics'], $request['search_semantics'] )
&& 'exact' === $request['search_semantics']
@ -3045,6 +3054,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
'description' => __( 'Limit result set to items that are sticky.' ),
'type' => 'boolean',
);
$query_params['ignore_sticky'] = array(
'description' => __( 'Whether to ignore sticky posts or not.' ),
'type' => 'boolean',
'default' => false,
);
}
if ( post_type_supports( $this->post_type, 'post-formats' ) ) {

View File

@ -197,6 +197,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
'context',
'exclude',
'format',
'ignore_sticky',
'include',
'modified_after',
'modified_before',
@ -5715,6 +5716,71 @@ Shankle pork chop prosciutto ribeye ham hock pastrami. T-bone shank brisket baco
$this->assertErrorResponse( 'rest_post_invalid_page_number', $response, 400 );
}
/**
* Test the REST API support for `ignore_sticky_posts`.
*
* @ticket 35907
*
* @covers WP_REST_Posts_Controller::get_items
*/
public function test_get_posts_ignore_sticky_default_prepends_sticky_posts() {
$id1 = self::$post_id;
// Create more recent post to avoid automatically placing other at the top.
$id2 = self::factory()->post->create( array( 'post_status' => 'publish' ) );
update_option( 'sticky_posts', array( $id1 ) );
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$this->assertSame( $data[0]['id'], $id1, 'Response has sticky post at the top.' );
$this->assertSame( $data[1]['id'], $id2, 'It is followed by most recent post.' );
}
/**
* Test the REST API support for `ignore_sticky_posts`.
*
* @ticket 35907
*
* @covers WP_REST_Posts_Controller::get_items
*/
public function test_get_posts_ignore_sticky_ignores_post_stickiness() {
$id1 = self::$post_id;
$id2 = self::factory()->post->create( array( 'post_status' => 'publish' ) );
update_option( 'sticky_posts', array( $id1 ) );
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
$request->set_param( 'ignore_sticky', true );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$this->assertSame( $data[0]['id'], $id2, 'Response has no sticky post at the top.' );
}
/**
* Test the REST API support for `ignore_sticky_posts`.
*
* @ticket 35907
*
* @covers WP_REST_Posts_Controller::get_items
*/
public function test_get_posts_ignore_sticky_honors_include() {
$id1 = self::$post_id;
$id2 = self::factory()->post->create( array( 'post_status' => 'publish' ) );
update_option( 'sticky_posts', array( $id1 ) );
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
$request->set_param( 'include', array( $id2 ) );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$this->assertCount( 1, $data, 'Only one post is expected to be returned.' );
$this->assertSame( $data[0]['id'], $id2, 'Returns the included post.' );
}
/**
* Internal function used to disable an insert query which
* will trigger a wpdb error for testing purposes.

View File

@ -627,6 +627,12 @@ mockedApiResponse.Schema = {
"type": "boolean",
"required": false
},
"ignore_sticky": {
"description": "Whether to ignore sticky posts or not.",
"type": "boolean",
"default": false,
"required": false
},
"format": {
"description": "Limit result set to items assigned one or more given formats.",
"type": "array",