wordpress-develop icon indicating copy to clipboard operation
wordpress-develop copied to clipboard

get_adjacent_post: adjacent post query plugin compatibility

Open ramonjd opened this issue 1 month ago • 3 comments

Follow up to https://github.com/WordPress/wordpress-develop/pull/10394

Tests out an idea suggested in https://core.trac.wordpress.org/ticket/64390#comment:10 Props @azaozz

[!NOTE] This is mainly to discuss whether it's worth the change, if so good, if not, I can close.

Description

This PR is a follow-up to #10394 that makes the deterministic ordering changes more defensive and plugin-friendly. It ensures that when plugins modify the get_{$adjacent}_post_where or get_{$adjacent}_post_sort filters, the deterministic logic is not applied on top of their modifications.

Problem

In PR #10394, deterministic ID-based ordering was added to fix adjacent post navigation for posts with identical dates. However, the implementation applied the deterministic logic before the filters ran, which meant:

  1. Plugins modifying the WHERE or SORT clauses via filters would receive SQL that already included the deterministic changes
  2. Plugins couldn't opt out or modify the SQL in ways that might conflict with the deterministic logic
  3. This could break plugins that parse or manipulate the SQL clauses

Solution

This PR implements a defensive approach that:

  1. Applies filters first with the original (non-deterministic) SQL clauses
  2. Only applies deterministic logic if filters don't modify the clauses - checks if the filtered value equals the original prepared value
  3. Respects plugin modifications - when filters modify the SQL, their changes are preserved and deterministic logic is not applied

Implementation:

  • For WHERE clause: Only applies ID-based fallback if $where === $where_prepared (filter didn't modify it)
  • For SORT clause: Only applies ID-based sorting if $sort === $sort_prepared (filter didn't modify it)

Test Steps

Automated Tests

Run the PHPUnit tests:

npm run test:php -- --filter Tests_Link_GetAdjacentPost

Manual Testing

1. Verify Default Behavior (No Filters)

  1. Create test scenario:

    • Create multiple posts with identical post_date values (bulk publish drafts)
    • Navigate between posts
  2. Expected Results:

    • Navigation works deterministically, you should be able to navigate through all posts with identical dates

2. Verify Filter Modifications Are Respected

Test WHERE Filter:

  1. Add test filter to functions.php or a test plugin:
// Test filter for next post WHERE clause
add_filter( 'get_next_post_where', function( $where ) {
	// Modify the WHERE clause - deterministic fallback should NOT be applied.
	return $where . ' AND 1=1';
}, 10, 1 );

// Test filter for previous post WHERE clause
add_filter( 'get_previous_post_where', function( $where ) {
	// Modify the WHERE clause - deterministic fallback should NOT be applied.
	return $where . ' AND 1=1';
}, 10, 1 );
  1. Verify behavior:
    • Navigate between posts, rhe deterministic ID fallback should NOT be applied (no AND p.ID in WHERE clause)

Test SORT Filter:

  1. Remove WHERE filters, add SORT filter:
add_filter( 'get_next_post_sort', function( $sort, $post, $order ) {
	// Remove ID from sort - deterministic ID sort should NOT be applied.
	return "ORDER BY p.post_date $order LIMIT 1";
}, 10, 3 );

add_filter( 'get_previous_post_sort', function( $sort, $post, $order ) {
	return "ORDER BY p.post_date $order LIMIT 1";
}, 10, 3 );
  1. Verify behavior:
    • Create posts with identical dates
    • Navigate between posts, deterministic ID sort is NOT applied

3. Verify Unmodified Filters Still Get Deterministic Logic

  1. Add filters that don't modify the clauses:
add_filter( 'get_next_post_where', function( $where ) {
	// Return unchanged - deterministic fallback should be applied.
	return $where;
}, 10, 1 );

add_filter( 'get_next_post_sort', function( $sort ) {
	// Return unchanged - deterministic ID sort should be applied.
	return $sort;
}, 10, 1 );
  1. Verify behavior:
    • Navigation works deterministically, you should be able to navigate through all posts with identical dates

Trac ticket: https://core.trac.wordpress.org/ticket/64390

ramonjd avatar Dec 12 '25 01:12 ramonjd