From 08e2f6ce681e3ba19edf8d09e46d6614d71d6534 Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 12 Dec 2025 12:28:22 +1100 Subject: [PATCH 1/4] Add deterministic fallback for adjacent post queries only when the query hasn't been modified. This update introduces a deterministic fallback for the SQL `WHERE` and `ORDER BY` clauses in the `get_adjacent_post` function when posts have identical dates. The fallback is applied only if the respective clauses have not been modified by filters, ensuring consistent behavior. Unit tests have been added to verify the correct application of this fallback under various conditions, including scenarios where filters are applied or not. See Trac ticket https://core.trac.wordpress.org/ticket/64390. --- src/wp-includes/link-template.php | 20 +- tests/phpunit/tests/link/getAdjacentPost.php | 227 +++++++++++++++++++ 2 files changed, 242 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index d1af2996bc7fb..d8e4a732752bd 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1814,6 +1814,7 @@ function get_next_post( $in_same_term = false, $excluded_terms = '', $taxonomy = * Can either be next or previous post. * * @since 2.5.0 + * @since 6.9.1 Adds deterministic fallback for sort clause if not modified by a filter. * * @global wpdb $wpdb WordPress database abstraction object. * @@ -1965,8 +1966,8 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo $join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms, $taxonomy, $post ); // Prepare the where clause for the adjacent post query. - $where_prepared = $wpdb->prepare( "WHERE (p.post_date $comparison_operator %s OR (p.post_date = %s AND p.ID $comparison_operator %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $comparison_operator is a string literal, either '<' or '>'. - + $where_prepared_with_deterministic_fallback = $wpdb->prepare( "WHERE (p.post_date $comparison_operator %s OR (p.post_date = %s AND p.ID $comparison_operator %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $comparison_operator is a string literal, either '<' or '>'. + $where_prepared = $wpdb->prepare( "WHERE p.post_date $comparison_operator %s AND p.post_type = %s $where", $current_post_date, $post->post_type ); /** * Filters the WHERE clause in the SQL for an adjacent post query. * @@ -1980,7 +1981,6 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * * @since 2.5.0 * @since 4.4.0 Added the `$taxonomy` and `$post` parameters. - * @since 6.9.0 Adds ID-based fallback for posts with identical dates in adjacent post queries. * * @param string $where The `WHERE` clause in the SQL. * @param bool $in_same_term Whether post should be in the same taxonomy term. @@ -1989,6 +1989,11 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @param WP_Post $post WP_Post object. */ $where = apply_filters( "get_{$adjacent}_post_where", $where_prepared, $in_same_term, $excluded_terms, $taxonomy, $post ); + + // Only force deterministic fallback if the where clause has not been modified by a filter. + if ( $where === $where_prepared ) { + $where = $where_prepared_with_deterministic_fallback; + } /** * Filters the ORDER BY clause in the SQL for an adjacent post query. @@ -2004,13 +2009,18 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @since 2.5.0 * @since 4.4.0 Added the `$post` parameter. * @since 4.9.0 Added the `$order` parameter. - * @since 6.9.0 Adds ID sort to ensure deterministic ordering for posts with identical dates. * * @param string $order_by The `ORDER BY` clause in the SQL. * @param WP_Post $post WP_Post object. * @param string $order Sort order. 'DESC' for previous post, 'ASC' for next. */ - $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order, p.ID $order LIMIT 1", $post, $order ); + $sort_prepared = "ORDER BY p.post_date $order LIMIT 1"; + $sort = apply_filters( "get_{$adjacent}_post_sort", $sort_prepared, $post, $order ); + + // Only force deterministic sort if the sort clause has not been modified by a filter. + if ( $sort === $sort_prepared ) { + $sort = "ORDER BY p.post_date $order, p.ID $order LIMIT 1"; + } $query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort"; $key = md5( $query ); diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 4d68493bfe8de..b72184a763404 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -622,6 +622,233 @@ public function test_get_adjacent_post_with_identical_dates() { $this->assertEquals( $post_ids[3], $next->ID ); } + /** + * Test that deterministic ID fallback is applied when WHERE filter doesn't modify the clause. + * + * @ticket 64390 + */ + public function test_get_adjacent_post_identical_dates_applies_deterministic_where_when_filter_unmodified() { + $identical_date = '2024-01-01 12:00:00'; + + // Create posts with identical dates but different IDs. + $post_ids = array(); + for ( $i = 1; $i <= 5; $i++ ) { + $post_ids[] = self::factory()->post->create( + array( + 'post_title' => "Post $i", + 'post_date' => $identical_date, + ) + ); + } + + // Add a filter that doesn't modify the WHERE clause (returns unchanged). + add_filter( + 'get_next_post_where', + static function( $where ) { + // Return unchanged - deterministic fallback should be applied. + return $where; + } + ); + + // Test navigation from the middle post (ID: 3rd post). + $current_post_id = $post_ids[2]; // 3rd post + $this->go_to( get_permalink( $current_post_id ) ); + + // Next post should be the 4th post (higher ID, same date) - deterministic. + $next = get_adjacent_post( false, '', false ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertEquals( $post_ids[3], $next->ID ); + + remove_all_filters( 'get_next_post_where' ); + } + + /** + * Test that deterministic ID fallback is NOT applied when WHERE filter modifies the clause. + * + * @ticket 64390 + */ + public function test_get_adjacent_post_identical_dates_respects_modified_where_filter() { + $identical_date = '2024-01-01 12:00:00'; + + // Create posts with identical dates but different IDs. + $post_ids = array(); + for ( $i = 1; $i <= 5; $i++ ) { + $post_ids[] = self::factory()->post->create( + array( + 'post_title' => "Post $i", + 'post_date' => $identical_date, + ) + ); + } + + // Capture what the filter receives and what it returns. + $filter_received = ''; + $filter_returned = ''; + add_filter( + 'get_next_post_where', + static function( $where ) use ( &$filter_received, &$filter_returned ) { + $filter_received = $where; + // Modify the WHERE clause - deterministic fallback should NOT be applied. + // Add a harmless condition that won't affect results but proves the filter was applied. + $filter_returned = $where . ' AND 1=1'; + return $filter_returned; + } + ); + + // Test navigation from the middle post (ID: 3rd post). + $current_post_id = $post_ids[2]; // 3rd post + $this->go_to( get_permalink( $current_post_id ) ); + + // Call get_adjacent_post to trigger the filter. + get_adjacent_post( false, '', false ); + + // Verify the filter received the non-deterministic WHERE clause (without ID fallback). + $this->assertNotEmpty( $filter_received, 'Filter should have been called.' ); + $this->assertStringNotContainsString( 'AND p.ID', $filter_received, 'Filter should receive WHERE clause without deterministic ID fallback.' ); + // Verify the filter's modification is preserved (proves deterministic logic wasn't applied on top). + $this->assertStringContainsString( 'AND 1=1', $filter_returned, 'Filter modification should be preserved.' ); + + remove_all_filters( 'get_next_post_where' ); + } + + /** + * Test that deterministic ID sort is applied when SORT filter doesn't modify the clause. + * + * @ticket 64390 + */ + public function test_get_adjacent_post_identical_dates_applies_deterministic_sort_when_filter_unmodified() { + $identical_date = '2024-01-01 12:00:00'; + + // Create posts with identical dates but different IDs. + $post_ids = array(); + for ( $i = 1; $i <= 5; $i++ ) { + $post_ids[] = self::factory()->post->create( + array( + 'post_title' => "Post $i", + 'post_date' => $identical_date, + ) + ); + } + + // Add a filter that doesn't modify the SORT clause (returns unchanged). + add_filter( + 'get_next_post_sort', + static function( $sort ) { + // Return unchanged - deterministic ID sort should be applied. + return $sort; + } + ); + + // Test navigation from the middle post (ID: 3rd post). + $current_post_id = $post_ids[2]; // 3rd post + $this->go_to( get_permalink( $current_post_id ) ); + + // Next post should be the 4th post (higher ID, same date) - deterministic. + $next = get_adjacent_post( false, '', false ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertEquals( $post_ids[3], $next->ID ); + + remove_all_filters( 'get_next_post_sort' ); + } + + /** + * Test that deterministic ID sort is NOT applied when SORT filter modifies the clause. + * + * @ticket 64390 + */ + public function test_get_adjacent_post_identical_dates_respects_modified_sort_filter() { + $identical_date = '2024-01-01 12:00:00'; + + // Create posts with identical dates but different IDs. + $post_ids = array(); + for ( $i = 1; $i <= 5; $i++ ) { + $post_ids[] = self::factory()->post->create( + array( + 'post_title' => "Post $i", + 'post_date' => $identical_date, + ) + ); + } + + // Capture what the filter receives and what it returns. + $filter_received = ''; + $filter_returned = ''; + add_filter( + 'get_next_post_sort', + static function( $sort, $post, $order ) use ( &$filter_received, &$filter_returned ) { + $filter_received = $sort; + // Modify to remove ID - deterministic ID sort should NOT be applied. + $filter_returned = "ORDER BY p.post_date $order LIMIT 1"; + return $filter_returned; + }, + 10, + 3 + ); + + // Test navigation from the middle post (ID: 3rd post). + $current_post_id = $post_ids[2]; // 3rd post + $this->go_to( get_permalink( $current_post_id ) ); + + // Call get_adjacent_post to trigger the filter. + get_adjacent_post( false, '', false ); + + // Verify the filter received the non-deterministic SORT clause (without ID). + $this->assertNotEmpty( $filter_received, 'Filter should have been called.' ); + $this->assertStringNotContainsString( 'p.ID', $filter_received, 'Filter should receive SORT clause without deterministic ID sort.' ); + // Verify the filter's modification is preserved (proves deterministic logic wasn't applied on top). + $this->assertStringNotContainsString( 'p.ID', $filter_returned, 'Filter modification should not include ID when filter removes it.' ); + $this->assertStringContainsString( 'ORDER BY p.post_date', $filter_returned, 'Filter modification should be preserved.' ); + + remove_all_filters( 'get_next_post_sort' ); + } + + /** + * Test that both WHERE and SORT filters work together correctly. + * + * @ticket 64390 + */ + public function test_get_adjacent_post_identical_dates_with_both_filters_unmodified() { + $identical_date = '2024-01-01 12:00:00'; + + // Create posts with identical dates but different IDs. + $post_ids = array(); + for ( $i = 1; $i <= 5; $i++ ) { + $post_ids[] = self::factory()->post->create( + array( + 'post_title' => "Post $i", + 'post_date' => $identical_date, + ) + ); + } + + // Add filters that don't modify the clauses. + add_filter( + 'get_previous_post_where', + static function( $where ) { + return $where; + } + ); + + add_filter( + 'get_previous_post_sort', + static function( $sort ) { + return $sort; + } + ); + + // Test navigation from the middle post (ID: 3rd post). + $current_post_id = $post_ids[2]; // 3rd post + $this->go_to( get_permalink( $current_post_id ) ); + + // Previous post should be the 2nd post (lower ID, same date) - deterministic. + $previous = get_adjacent_post( false, '', true ); + $this->assertInstanceOf( 'WP_Post', $previous ); + $this->assertEquals( $post_ids[1], $previous->ID ); + + remove_all_filters( 'get_previous_post_where' ); + remove_all_filters( 'get_previous_post_sort' ); + } + /** * Test get_adjacent_post with mixed dates and identical dates. * From fa9a9f1f94d1a48871a2114cbf1d2c6b1055d6b1 Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 12 Dec 2025 12:57:04 +1100 Subject: [PATCH 2/4] formatting --- src/wp-includes/link-template.php | 4 ++-- tests/phpunit/tests/link/getAdjacentPost.php | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index d8e4a732752bd..8c2324890c537 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1989,7 +1989,7 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @param WP_Post $post WP_Post object. */ $where = apply_filters( "get_{$adjacent}_post_where", $where_prepared, $in_same_term, $excluded_terms, $taxonomy, $post ); - + // Only force deterministic fallback if the where clause has not been modified by a filter. if ( $where === $where_prepared ) { $where = $where_prepared_with_deterministic_fallback; @@ -2015,7 +2015,7 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @param string $order Sort order. 'DESC' for previous post, 'ASC' for next. */ $sort_prepared = "ORDER BY p.post_date $order LIMIT 1"; - $sort = apply_filters( "get_{$adjacent}_post_sort", $sort_prepared, $post, $order ); + $sort = apply_filters( "get_{$adjacent}_post_sort", $sort_prepared, $post, $order ); // Only force deterministic sort if the sort clause has not been modified by a filter. if ( $sort === $sort_prepared ) { diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index b72184a763404..1399a044c0574 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -644,7 +644,7 @@ public function test_get_adjacent_post_identical_dates_applies_deterministic_whe // Add a filter that doesn't modify the WHERE clause (returns unchanged). add_filter( 'get_next_post_where', - static function( $where ) { + static function ( $where ) { // Return unchanged - deterministic fallback should be applied. return $where; } @@ -686,7 +686,7 @@ public function test_get_adjacent_post_identical_dates_respects_modified_where_f $filter_returned = ''; add_filter( 'get_next_post_where', - static function( $where ) use ( &$filter_received, &$filter_returned ) { + static function ( $where ) use ( &$filter_received, &$filter_returned ) { $filter_received = $where; // Modify the WHERE clause - deterministic fallback should NOT be applied. // Add a harmless condition that won't affect results but proves the filter was applied. @@ -733,7 +733,7 @@ public function test_get_adjacent_post_identical_dates_applies_deterministic_sor // Add a filter that doesn't modify the SORT clause (returns unchanged). add_filter( 'get_next_post_sort', - static function( $sort ) { + static function ( $sort ) { // Return unchanged - deterministic ID sort should be applied. return $sort; } @@ -775,7 +775,7 @@ public function test_get_adjacent_post_identical_dates_respects_modified_sort_fi $filter_returned = ''; add_filter( 'get_next_post_sort', - static function( $sort, $post, $order ) use ( &$filter_received, &$filter_returned ) { + static function ( $sort, $post, $order ) use ( &$filter_received, &$filter_returned ) { $filter_received = $sort; // Modify to remove ID - deterministic ID sort should NOT be applied. $filter_returned = "ORDER BY p.post_date $order LIMIT 1"; @@ -824,14 +824,14 @@ public function test_get_adjacent_post_identical_dates_with_both_filters_unmodif // Add filters that don't modify the clauses. add_filter( 'get_previous_post_where', - static function( $where ) { + static function ( $where ) { return $where; } ); add_filter( 'get_previous_post_sort', - static function( $sort ) { + static function ( $sort ) { return $sort; } ); From 2cc9d270b6d3e2c16ce5b75b9b566d8422f34103 Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 12 Dec 2025 12:59:29 +1100 Subject: [PATCH 3/4] formatting comment --- tests/phpunit/tests/link/getAdjacentPost.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 1399a044c0574..81e1100b1355e 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -688,8 +688,11 @@ public function test_get_adjacent_post_identical_dates_respects_modified_where_f 'get_next_post_where', static function ( $where ) use ( &$filter_received, &$filter_returned ) { $filter_received = $where; - // Modify the WHERE clause - deterministic fallback should NOT be applied. - // Add a harmless condition that won't affect results but proves the filter was applied. + /* + * Modify the WHERE clause - deterministic fallback should NOT be applied. + * Add a harmless condition that won't affect results but proves the filter was applied. + * This is to ensure that the deterministic fallback is not applied on top of the filter's modification. + */ $filter_returned = $where . ' AND 1=1'; return $filter_returned; } From f001ac26b7617f0771c5056d5bc8bb6bd7570fc4 Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 19 Dec 2025 15:20:27 +1100 Subject: [PATCH 4/4] Update var name and PHP docs Unit tests have been updated according to feedback (using assertSame for simple comparisons), and removing filter removes. --- src/wp-includes/link-template.php | 19 ++++++++++++------- tests/phpunit/tests/link/getAdjacentPost.php | 17 +++-------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 8c2324890c537..3128a3eae2c16 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1814,7 +1814,8 @@ function get_next_post( $in_same_term = false, $excluded_terms = '', $taxonomy = * Can either be next or previous post. * * @since 2.5.0 - * @since 6.9.1 Adds deterministic fallback for sort clause if not modified by a filter. + * @since 6.9.0 Introduce deterministic fallback based in IDs to account for date collisions. + * @since 6.9.1 Remove deterministic fallback for sites modifying the WHERE clause via a filter. See #64390. * * @global wpdb $wpdb WordPress database abstraction object. * @@ -1966,8 +1967,9 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo $join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms, $taxonomy, $post ); // Prepare the where clause for the adjacent post query. - $where_prepared_with_deterministic_fallback = $wpdb->prepare( "WHERE (p.post_date $comparison_operator %s OR (p.post_date = %s AND p.ID $comparison_operator %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $comparison_operator is a string literal, either '<' or '>'. - $where_prepared = $wpdb->prepare( "WHERE p.post_date $comparison_operator %s AND p.post_type = %s $where", $current_post_date, $post->post_type ); + $where_prepared = $wpdb->prepare( "WHERE p.post_date $comparison_operator %s AND p.post_type = %s $where", $current_post_date, $post->post_type ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $comparison_operator is a string literal, either '<' or '>'. + $deterministic_where_prepared = $wpdb->prepare( "WHERE (p.post_date $comparison_operator %s OR (p.post_date = %s AND p.ID $comparison_operator %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $comparison_operator is a string literal, either '<' or '>'. + /** * Filters the WHERE clause in the SQL for an adjacent post query. * @@ -1982,7 +1984,7 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @since 2.5.0 * @since 4.4.0 Added the `$taxonomy` and `$post` parameters. * - * @param string $where The `WHERE` clause in the SQL. + * @param string $where_prepared The `WHERE` clause in the SQL. * @param bool $in_same_term Whether post should be in the same taxonomy term. * @param int[]|string $excluded_terms Array of excluded term IDs. Empty string if none were provided. * @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true. @@ -1992,9 +1994,11 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo // Only force deterministic fallback if the where clause has not been modified by a filter. if ( $where === $where_prepared ) { - $where = $where_prepared_with_deterministic_fallback; + $where = $deterministic_where_prepared; } + $sort_prepared = "ORDER BY p.post_date $order LIMIT 1"; + /** * Filters the ORDER BY clause in the SQL for an adjacent post query. * @@ -2009,13 +2013,14 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @since 2.5.0 * @since 4.4.0 Added the `$post` parameter. * @since 4.9.0 Added the `$order` parameter. + * @since 6.9.0 Adds ID sort to ensure deterministic ordering for posts with identical dates. + * @since 6.9.1 Remove deterministic fallback for sites modifying the SORT clause via a filter. See #64390. * * @param string $order_by The `ORDER BY` clause in the SQL. * @param WP_Post $post WP_Post object. * @param string $order Sort order. 'DESC' for previous post, 'ASC' for next. */ - $sort_prepared = "ORDER BY p.post_date $order LIMIT 1"; - $sort = apply_filters( "get_{$adjacent}_post_sort", $sort_prepared, $post, $order ); + $sort = apply_filters( "get_{$adjacent}_post_sort", $sort_prepared, $post, $order ); // Only force deterministic sort if the sort clause has not been modified by a filter. if ( $sort === $sort_prepared ) { diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 81e1100b1355e..30de08c982b39 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -657,9 +657,7 @@ static function ( $where ) { // Next post should be the 4th post (higher ID, same date) - deterministic. $next = get_adjacent_post( false, '', false ); $this->assertInstanceOf( 'WP_Post', $next ); - $this->assertEquals( $post_ids[3], $next->ID ); - - remove_all_filters( 'get_next_post_where' ); + $this->assertSame( $post_ids[3], $next->ID, 'Next post should be the 4th post (higher ID, same date).' ); } /** @@ -710,8 +708,6 @@ static function ( $where ) use ( &$filter_received, &$filter_returned ) { $this->assertStringNotContainsString( 'AND p.ID', $filter_received, 'Filter should receive WHERE clause without deterministic ID fallback.' ); // Verify the filter's modification is preserved (proves deterministic logic wasn't applied on top). $this->assertStringContainsString( 'AND 1=1', $filter_returned, 'Filter modification should be preserved.' ); - - remove_all_filters( 'get_next_post_where' ); } /** @@ -749,9 +745,7 @@ static function ( $sort ) { // Next post should be the 4th post (higher ID, same date) - deterministic. $next = get_adjacent_post( false, '', false ); $this->assertInstanceOf( 'WP_Post', $next ); - $this->assertEquals( $post_ids[3], $next->ID ); - - remove_all_filters( 'get_next_post_sort' ); + $this->assertSame( $post_ids[3], $next->ID, 'Next post should be the 4th post (higher ID, same date).' ); } /** @@ -801,8 +795,6 @@ static function ( $sort, $post, $order ) use ( &$filter_received, &$filter_retur // Verify the filter's modification is preserved (proves deterministic logic wasn't applied on top). $this->assertStringNotContainsString( 'p.ID', $filter_returned, 'Filter modification should not include ID when filter removes it.' ); $this->assertStringContainsString( 'ORDER BY p.post_date', $filter_returned, 'Filter modification should be preserved.' ); - - remove_all_filters( 'get_next_post_sort' ); } /** @@ -846,10 +838,7 @@ static function ( $sort ) { // Previous post should be the 2nd post (lower ID, same date) - deterministic. $previous = get_adjacent_post( false, '', true ); $this->assertInstanceOf( 'WP_Post', $previous ); - $this->assertEquals( $post_ids[1], $previous->ID ); - - remove_all_filters( 'get_previous_post_where' ); - remove_all_filters( 'get_previous_post_sort' ); + $this->assertSame( $post_ids[1], $previous->ID, 'Previous post should be the 2nd post (lower ID, same date).' ); } /**