From f8ffa69d5f6d18ecf499ef5ae11e454e656cebe7 Mon Sep 17 00:00:00 2001 From: Ramon Date: Wed, 22 Oct 2025 18:14:38 +1100 Subject: [PATCH 1/6] Enhancement: Add ID-based fallback for adjacent post queries with identical dates. This update modifies the `get_adjacent_post` function to ensure deterministic ordering when multiple posts share the same date by incorporating the post ID in the SQL query. Additionally, new unit tests have been added to verify the functionality for posts with identical dates, ensuring correct navigation through adjacent posts. --- src/wp-includes/link-template.php | 6 +- tests/phpunit/tests/link/getAdjacentPost.php | 192 +++++++++++++++++++ tests/phpunit/tests/url.php | 65 +++++++ 3 files changed, 261 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 525a9efe53eb8..0827104716722 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1977,6 +1977,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. + * @since n.e.x.t 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. @@ -1984,7 +1985,7 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true. * @param WP_Post $post WP_Post object. */ - $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $current_post_date, $post->post_type ), $in_same_term, $excluded_terms, $taxonomy, $post ); + $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE (p.post_date $op %s OR (p.post_date = %s AND p.ID $op %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ), $in_same_term, $excluded_terms, $taxonomy, $post ); /** * Filters the ORDER BY clause in the SQL for an adjacent post query. @@ -2000,12 +2001,13 @@ 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 n.e.x.t 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 LIMIT 1", $post, $order ); + $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order, p.ID $order LIMIT 1", $post, $order ); $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 ce948c713ee1a..13f73e7286cdb 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -587,4 +587,196 @@ public function test_get_adjacent_post_cache() { $this->assertEquals( $post_four, get_adjacent_post( true, '', false ), 'Result of function call is wrong after after adding new term' ); $this->assertSame( get_num_queries() - $num_queries, 2, 'Number of queries run was not two after adding new term' ); } + + /** + * Test get_adjacent_post with posts having identical post_date. + * + * @ticket 8107 + */ + public function test_get_adjacent_post_with_identical_dates() { + $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, + ) + ); + } + + // 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) + $previous = get_adjacent_post( false, '', true ); + $this->assertInstanceOf( 'WP_Post', $previous ); + $this->assertEquals( $post_ids[1], $previous->ID ); + + // Next post should be the 4th post (higher ID, same date) + $next = get_adjacent_post( false, '', false ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertEquals( $post_ids[3], $next->ID ); + } + + /** + * Test get_adjacent_post with mixed dates and identical dates. + * + * @ticket 8107 + */ + public function test_get_adjacent_post_mixed_dates_with_identical_groups() { + // Create posts with different dates + $post_early = self::factory()->post->create( + array( + 'post_title' => 'Early Post', + 'post_date' => '2024-01-01 10:00:00', + ) + ); + + // Create multiple posts with identical date + $identical_date = '2024-01-01 12:00:00'; + $post_ids = array(); + for ( $i = 1; $i <= 3; $i++ ) { + $post_ids[] = self::factory()->post->create( + array( + 'post_title' => "Identical Post $i", + 'post_date' => $identical_date, + ) + ); + } + + $post_late = self::factory()->post->create( + array( + 'post_title' => 'Late Post', + 'post_date' => '2024-01-01 14:00:00', + ) + ); + + // Test from first identical post + $this->go_to( get_permalink( $post_ids[0] ) ); + + // Previous should be the early post (different date) + $previous = get_adjacent_post( false, '', true ); + $this->assertInstanceOf( 'WP_Post', $previous ); + $this->assertEquals( $post_early, $previous->ID ); + + // Next should be the second identical post (same date, higher ID) + $next = get_adjacent_post( false, '', false ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertEquals( $post_ids[1], $next->ID ); + + // Test from middle identical post + $this->go_to( get_permalink( $post_ids[1] ) ); + + // Previous should be the first identical post (same date, lower ID) + $previous = get_adjacent_post( false, '', true ); + $this->assertInstanceOf( 'WP_Post', $previous ); + $this->assertEquals( $post_ids[0], $previous->ID ); + + // Next should be the third identical post (same date, higher ID) + $next = get_adjacent_post( false, '', false ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertEquals( $post_ids[2], $next->ID ); + + // Test from last identical post + $this->go_to( get_permalink( $post_ids[2] ) ); + + // Previous should be the second identical post (same date, lower ID) + $previous = get_adjacent_post( false, '', true ); + $this->assertInstanceOf( 'WP_Post', $previous ); + $this->assertEquals( $post_ids[1], $previous->ID ); + + // Next should be the late post (different date) + $next = get_adjacent_post( false, '', false ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertEquals( $post_late, $next->ID ); + } + + /** + * Test get_adjacent_post navigation through all posts with identical dates. + * + * @ticket 8107 + */ + public function test_get_adjacent_post_navigation_through_identical_dates() { + $identical_date = '2024-01-01 12:00:00'; + + // Create 4 posts with identical dates + $post_ids = array(); + for ( $i = 1; $i <= 4; $i++ ) { + $post_ids[] = self::factory()->post->create( + array( + 'post_title' => "Post $i", + 'post_date' => $identical_date, + ) + ); + } + + // Test navigation sequence: 1 -> 2 -> 3 -> 4 + $this->go_to( get_permalink( $post_ids[0] ) ); + + // From post 1, next should be post 2 + $next = get_adjacent_post( false, '', false ); + $this->assertEquals( $post_ids[1], $next->ID ); + + // From post 2, previous should be post 1, next should be post 3 + $this->go_to( get_permalink( $post_ids[1] ) ); + $previous = get_adjacent_post( false, '', true ); + $this->assertEquals( $post_ids[0], $previous->ID ); + $next = get_adjacent_post( false, '', false ); + $this->assertEquals( $post_ids[2], $next->ID ); + + // From post 3, previous should be post 2, next should be post 4 + $this->go_to( get_permalink( $post_ids[2] ) ); + $previous = get_adjacent_post( false, '', true ); + $this->assertEquals( $post_ids[1], $previous->ID ); + $next = get_adjacent_post( false, '', false ); + $this->assertEquals( $post_ids[3], $next->ID ); + + // From post 4, previous should be post 3 + $this->go_to( get_permalink( $post_ids[3] ) ); + $previous = get_adjacent_post( false, '', true ); + $this->assertEquals( $post_ids[2], $previous->ID ); + } + + /** + * Test get_adjacent_post with identical dates and category filtering. + * + * @ticket 8107 + */ + public function test_get_adjacent_post_identical_dates_with_category() { + $identical_date = '2024-01-01 12:00:00'; + $category_id = self::factory()->category->create( array( 'name' => 'Test Category' ) ); + + // Create posts with identical dates, some in category + $post_ids = array(); + for ( $i = 1; $i <= 4; $i++ ) { + $post_id = self::factory()->post->create( + array( + 'post_title' => "Post $i", + 'post_date' => $identical_date, + ) + ); + + // Add every other post to the category + if ( 0 === $i % 2 ) { + wp_set_post_categories( $post_id, array( $category_id ) ); + } + + $post_ids[] = $post_id; + } + + // Test from post 2 (in category) + $this->go_to( get_permalink( $post_ids[1] ) ); + + // With category filtering, should only see posts in same category + $previous = get_adjacent_post( true, '', true, 'category' ); + $this->assertSame( '', $previous ); // No previous post in category + + $next = get_adjacent_post( true, '', false, 'category' ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertEquals( $post_ids[3], $next->ID ); // Post 4 (in category) + } } diff --git a/tests/phpunit/tests/url.php b/tests/phpunit/tests/url.php index 37ceb69cba192..a0dc29741be5d 100644 --- a/tests/phpunit/tests/url.php +++ b/tests/phpunit/tests/url.php @@ -569,4 +569,69 @@ public function test_url_functions_for_dots_in_paths() { ); } } + + /** + * Test get_adjacent_post with posts having identical post_date. + * + * @ticket 8107 + * @covers ::get_adjacent_post + */ + public function test_get_adjacent_post_with_identical_dates() { + $identical_date = gmdate( 'Y-m-d H:i:s', time() ); + + // Create 3 posts with identical dates but different IDs + $post_ids = array(); + for ( $i = 1; $i <= 3; $i++ ) { + $post_ids[] = self::factory()->post->create( + array( + 'post_title' => "Identical Post $i", + 'post_date' => $identical_date, + ) + ); + } + + if ( ! isset( $GLOBALS['post'] ) ) { + $GLOBALS['post'] = null; + } + $orig_post = $GLOBALS['post']; + + // Test from the middle post (2nd post) + $GLOBALS['post'] = get_post( $post_ids[1] ); + + // Previous post should be the 1st post (lower ID, same date) + $previous = get_adjacent_post( false, '', true ); + $this->assertInstanceOf( 'WP_Post', $previous ); + $this->assertSame( $post_ids[0], $previous->ID ); + + // Next post should be the 3rd post (higher ID, same date) + $next = get_adjacent_post( false, '', false ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertSame( $post_ids[2], $next->ID ); + + // Test from the first post + $GLOBALS['post'] = get_post( $post_ids[0] ); + + // Previous should be empty (no earlier posts) + $previous = get_adjacent_post( false, '', true ); + $this->assertSame( '', $previous ); + + // Next should be the 2nd post + $next = get_adjacent_post( false, '', false ); + $this->assertInstanceOf( 'WP_Post', $next ); + $this->assertSame( $post_ids[1], $next->ID ); + + // Test from the last post + $GLOBALS['post'] = get_post( $post_ids[2] ); + + // Previous should be the 2nd post + $previous = get_adjacent_post( false, '', true ); + $this->assertInstanceOf( 'WP_Post', $previous ); + $this->assertSame( $post_ids[1], $previous->ID ); + + // Next should be empty (no later posts) + $next = get_adjacent_post( false, '', false ); + $this->assertSame( '', $next ); + + $GLOBALS['post'] = $orig_post; + } } From 53ce5cce64feac4403f9d21cf672e1c11b1c53c1 Mon Sep 17 00:00:00 2001 From: Ramon Date: Wed, 22 Oct 2025 18:51:02 +1100 Subject: [PATCH 2/6] Add periods to comments. --- tests/phpunit/tests/link/getAdjacentPost.php | 50 ++++++++++---------- tests/phpunit/tests/url.php | 20 ++++---- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 13f73e7286cdb..4d68493bfe8de 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -596,7 +596,7 @@ public function test_get_adjacent_post_cache() { public function test_get_adjacent_post_with_identical_dates() { $identical_date = '2024-01-01 12:00:00'; - // Create posts with identical dates but different IDs + // Create posts with identical dates but different IDs. $post_ids = array(); for ( $i = 1; $i <= 5; $i++ ) { $post_ids[] = self::factory()->post->create( @@ -607,16 +607,16 @@ public function test_get_adjacent_post_with_identical_dates() { ); } - // Test navigation from the middle post (ID: 3rd post) + // 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) + // Previous post should be the 2nd post (lower ID, same date). $previous = get_adjacent_post( false, '', true ); $this->assertInstanceOf( 'WP_Post', $previous ); $this->assertEquals( $post_ids[1], $previous->ID ); - // Next post should be the 4th post (higher ID, same date) + // Next post should be the 4th post (higher ID, same date). $next = get_adjacent_post( false, '', false ); $this->assertInstanceOf( 'WP_Post', $next ); $this->assertEquals( $post_ids[3], $next->ID ); @@ -628,7 +628,7 @@ public function test_get_adjacent_post_with_identical_dates() { * @ticket 8107 */ public function test_get_adjacent_post_mixed_dates_with_identical_groups() { - // Create posts with different dates + // Create posts with different dates. $post_early = self::factory()->post->create( array( 'post_title' => 'Early Post', @@ -636,7 +636,7 @@ public function test_get_adjacent_post_mixed_dates_with_identical_groups() { ) ); - // Create multiple posts with identical date + // Create multiple posts with identical date. $identical_date = '2024-01-01 12:00:00'; $post_ids = array(); for ( $i = 1; $i <= 3; $i++ ) { @@ -655,41 +655,41 @@ public function test_get_adjacent_post_mixed_dates_with_identical_groups() { ) ); - // Test from first identical post + // Test from first identical post. $this->go_to( get_permalink( $post_ids[0] ) ); - // Previous should be the early post (different date) + // Previous should be the early post (different date). $previous = get_adjacent_post( false, '', true ); $this->assertInstanceOf( 'WP_Post', $previous ); $this->assertEquals( $post_early, $previous->ID ); - // Next should be the second identical post (same date, higher ID) + // Next should be the second identical post (same date, higher ID). $next = get_adjacent_post( false, '', false ); $this->assertInstanceOf( 'WP_Post', $next ); $this->assertEquals( $post_ids[1], $next->ID ); - // Test from middle identical post + // Test from middle identical post. $this->go_to( get_permalink( $post_ids[1] ) ); - // Previous should be the first identical post (same date, lower ID) + // Previous should be the first identical post (same date, lower ID). $previous = get_adjacent_post( false, '', true ); $this->assertInstanceOf( 'WP_Post', $previous ); $this->assertEquals( $post_ids[0], $previous->ID ); - // Next should be the third identical post (same date, higher ID) + // Next should be the third identical post (same date, higher ID). $next = get_adjacent_post( false, '', false ); $this->assertInstanceOf( 'WP_Post', $next ); $this->assertEquals( $post_ids[2], $next->ID ); - // Test from last identical post + // Test from last identical post. $this->go_to( get_permalink( $post_ids[2] ) ); - // Previous should be the second identical post (same date, lower ID) + // Previous should be the second identical post (same date, lower ID). $previous = get_adjacent_post( false, '', true ); $this->assertInstanceOf( 'WP_Post', $previous ); $this->assertEquals( $post_ids[1], $previous->ID ); - // Next should be the late post (different date) + // Next should be the late post (different date). $next = get_adjacent_post( false, '', false ); $this->assertInstanceOf( 'WP_Post', $next ); $this->assertEquals( $post_late, $next->ID ); @@ -703,7 +703,7 @@ public function test_get_adjacent_post_mixed_dates_with_identical_groups() { public function test_get_adjacent_post_navigation_through_identical_dates() { $identical_date = '2024-01-01 12:00:00'; - // Create 4 posts with identical dates + // Create 4 posts with identical dates. $post_ids = array(); for ( $i = 1; $i <= 4; $i++ ) { $post_ids[] = self::factory()->post->create( @@ -714,28 +714,28 @@ public function test_get_adjacent_post_navigation_through_identical_dates() { ); } - // Test navigation sequence: 1 -> 2 -> 3 -> 4 + // Test navigation sequence: 1 -> 2 -> 3 -> 4. $this->go_to( get_permalink( $post_ids[0] ) ); - // From post 1, next should be post 2 + // From post 1, next should be post 2. $next = get_adjacent_post( false, '', false ); $this->assertEquals( $post_ids[1], $next->ID ); - // From post 2, previous should be post 1, next should be post 3 + // From post 2, previous should be post 1, next should be post 3. $this->go_to( get_permalink( $post_ids[1] ) ); $previous = get_adjacent_post( false, '', true ); $this->assertEquals( $post_ids[0], $previous->ID ); $next = get_adjacent_post( false, '', false ); $this->assertEquals( $post_ids[2], $next->ID ); - // From post 3, previous should be post 2, next should be post 4 + // From post 3, previous should be post 2, next should be post 4. $this->go_to( get_permalink( $post_ids[2] ) ); $previous = get_adjacent_post( false, '', true ); $this->assertEquals( $post_ids[1], $previous->ID ); $next = get_adjacent_post( false, '', false ); $this->assertEquals( $post_ids[3], $next->ID ); - // From post 4, previous should be post 3 + // From post 4, previous should be post 3. $this->go_to( get_permalink( $post_ids[3] ) ); $previous = get_adjacent_post( false, '', true ); $this->assertEquals( $post_ids[2], $previous->ID ); @@ -750,7 +750,7 @@ public function test_get_adjacent_post_identical_dates_with_category() { $identical_date = '2024-01-01 12:00:00'; $category_id = self::factory()->category->create( array( 'name' => 'Test Category' ) ); - // Create posts with identical dates, some in category + // Create posts with identical dates, some in category. $post_ids = array(); for ( $i = 1; $i <= 4; $i++ ) { $post_id = self::factory()->post->create( @@ -760,7 +760,7 @@ public function test_get_adjacent_post_identical_dates_with_category() { ) ); - // Add every other post to the category + // Add every other post to the category. if ( 0 === $i % 2 ) { wp_set_post_categories( $post_id, array( $category_id ) ); } @@ -768,10 +768,10 @@ public function test_get_adjacent_post_identical_dates_with_category() { $post_ids[] = $post_id; } - // Test from post 2 (in category) + // Test from post 2 (in category). $this->go_to( get_permalink( $post_ids[1] ) ); - // With category filtering, should only see posts in same category + // With category filtering, should only see posts in same category. $previous = get_adjacent_post( true, '', true, 'category' ); $this->assertSame( '', $previous ); // No previous post in category diff --git a/tests/phpunit/tests/url.php b/tests/phpunit/tests/url.php index a0dc29741be5d..50a0056f765d8 100644 --- a/tests/phpunit/tests/url.php +++ b/tests/phpunit/tests/url.php @@ -579,7 +579,7 @@ public function test_url_functions_for_dots_in_paths() { public function test_get_adjacent_post_with_identical_dates() { $identical_date = gmdate( 'Y-m-d H:i:s', time() ); - // Create 3 posts with identical dates but different IDs + // Create 3 posts with identical dates but different IDs. $post_ids = array(); for ( $i = 1; $i <= 3; $i++ ) { $post_ids[] = self::factory()->post->create( @@ -595,40 +595,40 @@ public function test_get_adjacent_post_with_identical_dates() { } $orig_post = $GLOBALS['post']; - // Test from the middle post (2nd post) + // Test from the middle post (2nd post). $GLOBALS['post'] = get_post( $post_ids[1] ); - // Previous post should be the 1st post (lower ID, same date) + // Previous post should be the 1st post (lower ID, same date). $previous = get_adjacent_post( false, '', true ); $this->assertInstanceOf( 'WP_Post', $previous ); $this->assertSame( $post_ids[0], $previous->ID ); - // Next post should be the 3rd post (higher ID, same date) + // Next post should be the 3rd post (higher ID, same date). $next = get_adjacent_post( false, '', false ); $this->assertInstanceOf( 'WP_Post', $next ); $this->assertSame( $post_ids[2], $next->ID ); - // Test from the first post + // Test from the first post. $GLOBALS['post'] = get_post( $post_ids[0] ); - // Previous should be empty (no earlier posts) + // Previous should be empty (no earlier posts). $previous = get_adjacent_post( false, '', true ); $this->assertSame( '', $previous ); - // Next should be the 2nd post + // Next should be the 2nd post. $next = get_adjacent_post( false, '', false ); $this->assertInstanceOf( 'WP_Post', $next ); $this->assertSame( $post_ids[1], $next->ID ); - // Test from the last post + // Test from the last post. $GLOBALS['post'] = get_post( $post_ids[2] ); - // Previous should be the 2nd post + // Previous should be the 2nd post. $previous = get_adjacent_post( false, '', true ); $this->assertInstanceOf( 'WP_Post', $previous ); $this->assertSame( $post_ids[1], $previous->ID ); - // Next should be empty (no later posts) + // Next should be empty (no later posts). $next = get_adjacent_post( false, '', false ); $this->assertSame( '', $next ); From 790581bc2154947c8e7fb70a1da7f4521e98437a Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 23 Oct 2025 09:59:39 +1100 Subject: [PATCH 3/6] Refactor: Prepare WHERE clause for adjacent post queries in `get_adjacent_post` function. This change enhances the SQL query preparation by introducing a separate variable for the WHERE clause, improving readability and maintainability. The version number for the ID-based fallback feature has been updated to 6.9.0. --- src/wp-includes/link-template.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 0827104716722..9fa5015bda67a 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1964,6 +1964,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 = $wpdb->prepare( "WHERE (p.post_date $op %s OR (p.post_date = %s AND p.ID $op %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $op is a string literal, either '<' or '>'. + /** * Filters the WHERE clause in the SQL for an adjacent post query. * @@ -1977,7 +1980,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. - * @since n.e.x.t Adds ID-based fallback for posts with identical dates in adjacent post queries. + * @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. @@ -1985,7 +1988,7 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true. * @param WP_Post $post WP_Post object. */ - $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE (p.post_date $op %s OR (p.post_date = %s AND p.ID $op %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ), $in_same_term, $excluded_terms, $taxonomy, $post ); + $where = apply_filters( "get_{$adjacent}_post_where", $where_prepared, $in_same_term, $excluded_terms, $taxonomy, $post ); /** * Filters the ORDER BY clause in the SQL for an adjacent post query. @@ -2001,7 +2004,7 @@ 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 n.e.x.t Adds ID sort to ensure deterministic ordering for posts with identical dates. + * @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. From 9ce3ceee35058206ef6367f528069a7a3cd0423b Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 23 Oct 2025 13:23:58 +1100 Subject: [PATCH 4/6] Update tests/phpunit/tests/url.php Remove $GLOBALS['post'] = $orig_post; Co-authored-by: Weston Ruter --- tests/phpunit/tests/url.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/phpunit/tests/url.php b/tests/phpunit/tests/url.php index 50a0056f765d8..812df2df4718e 100644 --- a/tests/phpunit/tests/url.php +++ b/tests/phpunit/tests/url.php @@ -631,7 +631,5 @@ public function test_get_adjacent_post_with_identical_dates() { // Next should be empty (no later posts). $next = get_adjacent_post( false, '', false ); $this->assertSame( '', $next ); - - $GLOBALS['post'] = $orig_post; } } From 6f5a0ed461efd3f593911c12c856be09db53e43e Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 23 Oct 2025 13:24:10 +1100 Subject: [PATCH 5/6] Update tests/phpunit/tests/url.php Co-authored-by: Weston Ruter --- tests/phpunit/tests/url.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/phpunit/tests/url.php b/tests/phpunit/tests/url.php index 812df2df4718e..3734891eb19ac 100644 --- a/tests/phpunit/tests/url.php +++ b/tests/phpunit/tests/url.php @@ -590,11 +590,6 @@ public function test_get_adjacent_post_with_identical_dates() { ); } - if ( ! isset( $GLOBALS['post'] ) ) { - $GLOBALS['post'] = null; - } - $orig_post = $GLOBALS['post']; - // Test from the middle post (2nd post). $GLOBALS['post'] = get_post( $post_ids[1] ); From 06ab6231d7d519ba8bd8934e2eb2bbe3a88be15d Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 23 Oct 2025 13:33:15 +1100 Subject: [PATCH 6/6] Refactor: Rename variable for comparison operator in `get_adjacent_post` function. improve code clarity by renaming the `$op` variable to `$comparison_operator`, --- src/wp-includes/link-template.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 9fa5015bda67a..d6f97a845f65e 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1939,8 +1939,8 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo $where .= " AND p.post_status = 'publish'"; } - $op = $previous ? '<' : '>'; - $order = $previous ? 'DESC' : 'ASC'; + $comparison_operator = $previous ? '<' : '>'; + $order = $previous ? 'DESC' : 'ASC'; /** * Filters the JOIN clause in the SQL for an adjacent post query. @@ -1965,7 +1965,7 @@ 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 $op %s OR (p.post_date = %s AND p.ID $op %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $op is a string literal, either '<' or '>'. + $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.