Skip to content

Commit

Permalink
Posts, Post Types: Use persistent caching in get_adjacent_post func…
Browse files Browse the repository at this point in the history
…tion.

The function `get_adjacent_post` cached the results of database query in the cache group `counts`. This is a none persistent group and meant cache would not persist on the next request. Change cache to save to the `posts` cache group. Cache invalidation is done by using get last changed value of the `posts` and `terms` group as a salt for the cache key. 

Props spacedmonkey, peterwilsoncc, johnbillion, boonebgorges, mukesh27, dd32.
Fixes #41131.

git-svn-id: https://develop.svn.wordpress.org/trunk@55085 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
spacedmonkey committed Jan 18, 2023
1 parent 15b5159 commit 4108894
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/wp-includes/link-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -1976,9 +1976,15 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo
*/
$sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1", $post, $order );

$query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort";
$query_key = 'adjacent_post_' . md5( $query );
$result = wp_cache_get( $query_key, 'counts' );
$query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort";
$key = md5( $query );
$last_changed = wp_cache_get_last_changed( 'posts' );
if ( $in_same_term || ! empty( $excluded_terms ) ) {
$last_changed .= wp_cache_get_last_changed( 'terms' );
}
$cache_key = "adjacent_post:$key:$last_changed";

$result = wp_cache_get( $cache_key, 'posts' );
if ( false !== $result ) {
if ( $result ) {
$result = get_post( $result );
Expand All @@ -1991,7 +1997,7 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo
$result = '';
}

wp_cache_set( $query_key, $result, 'counts' );
wp_cache_set( $cache_key, $result, 'posts' );

if ( $result ) {
$result = get_post( $result );
Expand Down
78 changes: 78 additions & 0 deletions tests/phpunit/tests/link/getAdjacentPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,82 @@ public function filter_excluded_terms( $excluded_terms ) {
$excluded_terms[] = $this->exclude_term;
return $excluded_terms;
}

/**
* @ticket 41131
*/
public function test_get_adjacent_post_cache() {
// Need some sample posts to test adjacency.
$post_one = self::factory()->post->create_and_get(
array(
'post_title' => 'First',
'post_date' => '2012-01-01 12:00:00',
)
);

$post_two = self::factory()->post->create_and_get(
array(
'post_title' => 'Second',
'post_date' => '2012-02-01 12:00:00',
)
);

$post_three = self::factory()->post->create_and_get(
array(
'post_title' => 'Third',
'post_date' => '2012-03-01 12:00:00',
)
);

$post_four = self::factory()->post->create_and_get(
array(
'post_title' => 'Fourth',
'post_date' => '2012-04-01 12:00:00',
)
);

// Assign some terms.
wp_set_object_terms( $post_one->ID, 'WordPress', 'category', false );
wp_set_object_terms( $post_three->ID, 'WordPress', 'category', false );

wp_set_object_terms( $post_two->ID, 'plugins', 'post_tag', false );
wp_set_object_terms( $post_four->ID, 'plugins', 'post_tag', false );

// Test normal post adjacency.
$this->go_to( get_permalink( $post_two->ID ) );

// Test getting the right result.
$first_run = get_adjacent_post( false, '', true );
$this->assertEquals( $post_one, $first_run, 'Did not get first post when on second post' );
$this->assertNotEquals( $post_two, $first_run, 'Got second post when on second post' );

// Query count to test caching.
$num_queries = get_num_queries();
$second_run = get_adjacent_post( false, '', true );
$this->assertNotEquals( $post_two, $second_run, 'Got second post when on second post on second run' );
$this->assertEquals( $post_one, $second_run, 'Did not get first post when on second post on second run' );
$this->assertSame( $num_queries, get_num_queries() );

// Test creating new post busts cache.
$post_five = self::factory()->post->create_and_get(
array(
'post_title' => 'Five',
'post_date' => '2012-04-01 12:00:00',
)
);
$num_queries = get_num_queries();

$this->assertEquals( $post_one, get_adjacent_post( false, '', true ), 'Did not get first post after new post is added' );
$this->assertSame( get_num_queries() - $num_queries, 1, 'Number of queries run was not one after new post is added' );

$this->assertEquals( $post_four, get_adjacent_post( true, '', false ), 'Did not get forth post after new post is added' );
$num_queries = get_num_queries();
$this->assertEquals( $post_four, get_adjacent_post( true, '', false ), 'Did not get forth post after new post is added' );
$this->assertSame( $num_queries, get_num_queries() );
wp_set_object_terms( $post_four->ID, 'themes', 'post_tag', false );

$num_queries = get_num_queries();
$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' );
}
}

0 comments on commit 4108894

Please sign in to comment.