From 69378cc472b00ad861d58541389918208a9287fc Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 25 Feb 2025 05:10:31 +0000 Subject: [PATCH] Editor: Add option to ignore sticky posts in Query block. Introduce a new `ignore` value for the `sticky` query argument. When this value is used, the query will not prepend sticky posts at the top but display them in the natural order. Props mamaduka, peterwilsoncc, audrasjb, mikinc860, poena, dhruvishah2203, joemcgill. Fixes #62908. git-svn-id: https://develop.svn.wordpress.org/trunk@59866 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/blocks.php | 4 +- tests/phpunit/tests/blocks/wpBlock.php | 143 +++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 58e03d0155..4a9cf545e6 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -2564,8 +2564,10 @@ function build_query_vars_from_query_block( $block, $page ) { */ $query['post__in'] = ! empty( $sticky ) ? $sticky : array( 0 ); $query['ignore_sticky_posts'] = 1; - } else { + } elseif ( 'exclude' === $block->context['query']['sticky'] ) { $query['post__not_in'] = array_merge( $query['post__not_in'], $sticky ); + } elseif ( 'ignore' === $block->context['query']['sticky'] ) { + $query['ignore_sticky_posts'] = 1; } } if ( ! empty( $block->context['query']['exclude'] ) ) { diff --git a/tests/phpunit/tests/blocks/wpBlock.php b/tests/phpunit/tests/blocks/wpBlock.php index bfde02b4dc..f28bbd6c83 100644 --- a/tests/phpunit/tests/blocks/wpBlock.php +++ b/tests/phpunit/tests/blocks/wpBlock.php @@ -747,6 +747,149 @@ class Tests_Blocks_wpBlock extends WP_UnitTestCase { ); } + /** + * Ensure requesting only sticky posts returns only sticky posts. + * + * @ticket 62908 + */ + public function test_build_query_vars_from_block_query_only_sticky_posts() { + $this->factory()->post->create_many( 5 ); + $sticky_post_id = $this->factory()->post->create( + array( + 'post_type' => 'post', + 'post_status' => 'publish', + 'post_title' => 'Sticky Post', + ) + ); + stick_post( $sticky_post_id ); + + $this->registry->register( + 'core/example', + array( 'uses_context' => array( 'query' ) ) + ); + + $parsed_blocks = parse_blocks( 'ab' ); + $parsed_block = $parsed_blocks[0]; + $context = array( + 'query' => array( + 'sticky' => 'only', + ), + ); + $block = new WP_Block( $parsed_block, $context, $this->registry ); + $query_args = build_query_vars_from_query_block( $block, 1 ); + + $this->assertSame( + array( + 'post_type' => 'post', + 'order' => 'DESC', + 'orderby' => 'date', + 'post__not_in' => array(), + 'tax_query' => array(), + 'post__in' => array( $sticky_post_id ), + 'ignore_sticky_posts' => 1, + ), + $query_args + ); + + $query = new WP_Query( $query_args ); + $this->assertSame( array( $sticky_post_id ), wp_list_pluck( $query->posts, 'ID' ) ); + } + + /** + * Ensure excluding sticky posts returns only non-sticky posts. + * + * @ticket 62908 + */ + public function test_build_query_vars_from_block_query_exclude_sticky_posts() { + $not_sticky_post_ids = $this->factory()->post->create_many( 5 ); + $sticky_post_id = $this->factory()->post->create( + array( + 'post_type' => 'post', + 'post_status' => 'publish', + 'post_title' => 'Sticky Post', + ) + ); + stick_post( $sticky_post_id ); + + $this->registry->register( + 'core/example', + array( 'uses_context' => array( 'query' ) ) + ); + + $parsed_blocks = parse_blocks( 'ab' ); + $parsed_block = $parsed_blocks[0]; + $context = array( + 'query' => array( + 'sticky' => 'exclude', + ), + ); + $block = new WP_Block( $parsed_block, $context, $this->registry ); + $query_args = build_query_vars_from_query_block( $block, 1 ); + + $this->assertSame( + array( + 'post_type' => 'post', + 'order' => 'DESC', + 'orderby' => 'date', + 'post__not_in' => array(), + 'tax_query' => array(), + 'post__not_in' => array( $sticky_post_id ), + ), + $query_args + ); + + $query = new WP_Query( $query_args ); + $this->assertNotContains( $sticky_post_id, wp_list_pluck( $query->posts, 'ID' ) ); + $this->assertSameSets( $not_sticky_post_ids, wp_list_pluck( $query->posts, 'ID' ) ); + } + + /** + * Ensure ignoring sticky posts includes both sticky and non-sticky posts. + * + * @ticket 62908 + */ + public function test_build_query_vars_from_block_query_ignore_sticky_posts() { + $not_sticky_post_ids = $this->factory()->post->create_many( 5 ); + $sticky_post_id = $this->factory()->post->create( + array( + 'post_type' => 'post', + 'post_status' => 'publish', + 'post_title' => 'Sticky Post', + ) + ); + stick_post( $sticky_post_id ); + + $this->registry->register( + 'core/example', + array( 'uses_context' => array( 'query' ) ) + ); + + $parsed_blocks = parse_blocks( 'ab' ); + $parsed_block = $parsed_blocks[0]; + $context = array( + 'query' => array( + 'sticky' => 'ignore', + ), + ); + $block = new WP_Block( $parsed_block, $context, $this->registry ); + $query_args = build_query_vars_from_query_block( $block, 1 ); + + $this->assertSame( + array( + 'post_type' => 'post', + 'order' => 'DESC', + 'orderby' => 'date', + 'post__not_in' => array(), + 'tax_query' => array(), + 'ignore_sticky_posts' => 1, + ), + $query_args + ); + + $query = new WP_Query( $query_args ); + $this->assertSameSets( array_merge( $not_sticky_post_ids, array( $sticky_post_id ) ), wp_list_pluck( $query->posts, 'ID' ) ); + } + /** * @ticket 56467 */