From db8bc6a371e2f958bfdad0a361da770097c5d41e Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 6 Feb 2025 10:19:21 +0400 Subject: [PATCH 1/3] 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 won't prepend sticky posts at the top; instead, it will display them in the natural order of the query. --- src/wp-includes/blocks.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index c09321edfa5bd..2ecf6fc4752cb 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -2489,9 +2489,15 @@ function build_query_vars_from_query_block( $block, $page ) { */ $query['post__in'] = ! empty( $sticky ) ? $sticky : array( 0 ); $query['ignore_sticky_posts'] = 1; - } else { + } + + if ( 'exclude' === $block->context['query']['sticky'] ) { $query['post__not_in'] = array_merge( $query['post__not_in'], $sticky ); } + + if ( 'ignore' === $block->context['query']['sticky'] ) { + $query['ignore_sticky_posts'] = 1; + } } if ( ! empty( $block->context['query']['exclude'] ) ) { $excluded_post_ids = array_map( 'intval', $block->context['query']['exclude'] ); From 92ddf6684b61a20d35ca5d2ecdd790e4331798bc Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 18 Feb 2025 12:59:43 +1100 Subject: [PATCH 2/3] Tests for 62908. --- tests/phpunit/tests/blocks/wpBlock.php | 143 +++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/tests/phpunit/tests/blocks/wpBlock.php b/tests/phpunit/tests/blocks/wpBlock.php index bfde02b4dc44c..f28bbd6c83733 100644 --- a/tests/phpunit/tests/blocks/wpBlock.php +++ b/tests/phpunit/tests/blocks/wpBlock.php @@ -747,6 +747,149 @@ public function test_build_query_vars_from_query_block_with_top_level_parent() { ); } + /** + * 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 */ From efb4ace6ff78c06881cec04881a97ce52dde22f7 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 19 Feb 2025 11:00:04 +0800 Subject: [PATCH 3/3] CS feedback --- src/wp-includes/blocks.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 2ecf6fc4752cb..fd5c2d769b571 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -2489,13 +2489,9 @@ function build_query_vars_from_query_block( $block, $page ) { */ $query['post__in'] = ! empty( $sticky ) ? $sticky : array( 0 ); $query['ignore_sticky_posts'] = 1; - } - - if ( 'exclude' === $block->context['query']['sticky'] ) { + } elseif ( 'exclude' === $block->context['query']['sticky'] ) { $query['post__not_in'] = array_merge( $query['post__not_in'], $sticky ); - } - - if ( 'ignore' === $block->context['query']['sticky'] ) { + } elseif ( 'ignore' === $block->context['query']['sticky'] ) { $query['ignore_sticky_posts'] = 1; } }