From a8c199cf4a14e93cc46217a9754c7e29031b47a4 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Thu, 29 Sep 2022 11:57:13 +0100 Subject: [PATCH 1/8] Add caching to `get_adjacent_post`. --- src/wp-includes/link-template.php | 14 +++- tests/phpunit/tests/link/getAdjacentPost.php | 77 ++++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index de9988be1f319..6add336279fcb 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1969,9 +1969,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 ) { + $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 ); @@ -1984,7 +1990,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 ); diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 505d52a1dccde..103503f664c1e 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -350,4 +350,81 @@ public function filter_excluded_terms( $excluded_terms ) { $excluded_terms[] = $this->exclude_term; return $excluded_terms; } + + /** + * @ticket 41131 + */ + public function test_get_adjacent_post_cache() { + global $wpdb; + // 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 + $this->assertEquals( $post_one, get_adjacent_post( false, '', true ) ); + $this->assertNotEquals( $post_two, get_adjacent_post( false, '', true ) ); + + // Query count to test cachcing. + $num_queries = $wpdb->num_queries; + $this->assertNotEquals( $post_two, get_adjacent_post( false, '', true ) ); + $this->assertEquals( $post_one, get_adjacent_post( false, '', true ) ); + $this->assertSame( $num_queries, $wpdb->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 = $wpdb->num_queries; + + $this->assertEquals( $post_one, get_adjacent_post( false, '', true ) ); + $this->assertSame( $num_queries + 1, $wpdb->num_queries ); + + $this->assertEquals( $post_four, get_adjacent_post( true, '', false ) ); + $num_queries = $wpdb->num_queries; + $this->assertEquals( $post_four, get_adjacent_post( true, '', false ) ); + $this->assertSame( $num_queries, $wpdb->num_queries ); + wp_set_object_terms( $post_four->ID, 'themes', 'post_tag', false ); + + $num_queries = $wpdb->num_queries; + $this->assertEquals( $post_four, get_adjacent_post( true, '', false ) ); + $this->assertSame( $num_queries + 2, $wpdb->num_queries ); + } } From 8df0a78407b3fae76138280c2e0fd9c4cc728ad9 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Thu, 8 Dec 2022 14:59:42 +0000 Subject: [PATCH 2/8] Apply suggestions from code review Co-authored-by: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> --- src/wp-includes/link-template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 6add336279fcb..588aa30550c81 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1972,7 +1972,7 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo $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 ) { + if ( $in_same_term || ! empty( $excluded_terms ) ) { $last_changed .= wp_cache_get_last_changed( 'terms' ); } $cache_key = "adjacent_post:$key:$last_changed"; From a4b31c0c34c45feb2ed370e588555e98a26adb19 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Thu, 8 Dec 2022 15:13:22 +0000 Subject: [PATCH 3/8] Apply suggestions from code review Co-authored-by: Mukesh Panchal --- tests/phpunit/tests/link/getAdjacentPost.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 103503f664c1e..30d1ec9747bda 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -356,7 +356,7 @@ public function filter_excluded_terms( $excluded_terms ) { */ public function test_get_adjacent_post_cache() { global $wpdb; - // Need some sample posts to test adjacency + // Need some sample posts to test adjacency. $post_one = self::factory()->post->create_and_get( array( 'post_title' => 'First', From 11572214776c507a8e122d1c1c8b996c7993980e Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 3 Jan 2023 15:47:47 +0000 Subject: [PATCH 4/8] Apply suggestions from code review Co-authored-by: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> --- tests/phpunit/tests/link/getAdjacentPost.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 30d1ec9747bda..6f6c12eee978e 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -385,27 +385,27 @@ public function test_get_adjacent_post_cache() { ) ); - // Assign some terms + // 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 + // Test normal post adjacency. $this->go_to( get_permalink( $post_two->ID ) ); // Test getting the right result $this->assertEquals( $post_one, get_adjacent_post( false, '', true ) ); $this->assertNotEquals( $post_two, get_adjacent_post( false, '', true ) ); - // Query count to test cachcing. + // Query count to test caching. $num_queries = $wpdb->num_queries; $this->assertNotEquals( $post_two, get_adjacent_post( false, '', true ) ); $this->assertEquals( $post_one, get_adjacent_post( false, '', true ) ); $this->assertSame( $num_queries, $wpdb->num_queries ); - // Test creating new post busts cache + // Test creating new post busts cache. $post_five = self::factory()->post->create_and_get( array( 'post_title' => 'Five', From e2cc137c057a55eb937b5521895ae4368ce3c6b3 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 3 Jan 2023 16:03:19 +0000 Subject: [PATCH 5/8] Improve tests. --- tests/phpunit/tests/link/getAdjacentPost.php | 35 ++++++++++---------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 6f6c12eee978e..a2f4a2dc4f388 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -355,7 +355,6 @@ public function filter_excluded_terms( $excluded_terms ) { * @ticket 41131 */ public function test_get_adjacent_post_cache() { - global $wpdb; // Need some sample posts to test adjacency. $post_one = self::factory()->post->create_and_get( array( @@ -396,14 +395,16 @@ public function test_get_adjacent_post_cache() { $this->go_to( get_permalink( $post_two->ID ) ); // Test getting the right result - $this->assertEquals( $post_one, get_adjacent_post( false, '', true ) ); - $this->assertNotEquals( $post_two, get_adjacent_post( false, '', true ) ); + $first_run = get_adjacent_post( false, '', true ); + $this->assertEquals( $post_one, $first_run, 'Get first post when on second post' ); + $this->assertNotEquals( $post_two, $first_run, 'Do not get second post when on second post' ); // Query count to test caching. - $num_queries = $wpdb->num_queries; - $this->assertNotEquals( $post_two, get_adjacent_post( false, '', true ) ); - $this->assertEquals( $post_one, get_adjacent_post( false, '', true ) ); - $this->assertSame( $num_queries, $wpdb->num_queries ); + $num_queries = get_num_queries(); + $second_run = get_adjacent_post( false, '', true ); + $this->assertNotEquals( $post_two, $second_run, 'Do not get second post when on second post on second run' ); + $this->assertEquals( $post_one, $second_run, '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( @@ -412,19 +413,19 @@ public function test_get_adjacent_post_cache() { 'post_date' => '2012-04-01 12:00:00', ) ); - $num_queries = $wpdb->num_queries; + $num_queries = get_num_queries(); - $this->assertEquals( $post_one, get_adjacent_post( false, '', true ) ); - $this->assertSame( $num_queries + 1, $wpdb->num_queries ); + $this->assertEquals( $post_one, get_adjacent_post( false, '', true ), 'Get first post after new post is added' ); + $this->assertSame( get_num_queries() - $num_queries, 1, 'Check to see query uncached after adding new post' ); - $this->assertEquals( $post_four, get_adjacent_post( true, '', false ) ); - $num_queries = $wpdb->num_queries; - $this->assertEquals( $post_four, get_adjacent_post( true, '', false ) ); - $this->assertSame( $num_queries, $wpdb->num_queries ); + $this->assertEquals( $post_four, get_adjacent_post( true, '', false ), 'Get forth post after new post is added' ); + $num_queries = get_num_queries(); + $this->assertEquals( $post_four, get_adjacent_post( true, '', false ), '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 = $wpdb->num_queries; - $this->assertEquals( $post_four, get_adjacent_post( true, '', false ) ); - $this->assertSame( $num_queries + 2, $wpdb->num_queries ); + $num_queries = get_num_queries(); + $this->assertEquals( $post_four, get_adjacent_post( true, '', false ) , 'Check to see query uncached after adding new term' ); + $this->assertSame( get_num_queries() - $num_queries,2, 'Check to see query uncached after adding new term' ); } } From 2366f755c8ed24b130bb63e25008c7dd8ef9085f Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 17 Jan 2023 13:49:15 +0000 Subject: [PATCH 6/8] Fix lints --- tests/phpunit/tests/link/getAdjacentPost.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index a2f4a2dc4f388..4fbaf0c22ad78 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -397,13 +397,13 @@ public function test_get_adjacent_post_cache() { // Test getting the right result $first_run = get_adjacent_post( false, '', true ); $this->assertEquals( $post_one, $first_run, 'Get first post when on second post' ); - $this->assertNotEquals( $post_two, $first_run, 'Do not get second post when on second post' ); + $this->assertNotEquals( $post_two, $first_run, 'Do not get 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, 'Do not get second post when on second post on second run' ); - $this->assertEquals( $post_one, $second_run, 'Get first post when on second post on second run' ); + $second_run = get_adjacent_post( false, '', true ); + $this->assertNotEquals( $post_two, $second_run, 'Do not get second post when on second post on second run' ); + $this->assertEquals( $post_one, $second_run, 'Get first post when on second post on second run' ); $this->assertSame( $num_queries, get_num_queries() ); // Test creating new post busts cache. @@ -416,7 +416,7 @@ public function test_get_adjacent_post_cache() { $num_queries = get_num_queries(); $this->assertEquals( $post_one, get_adjacent_post( false, '', true ), 'Get first post after new post is added' ); - $this->assertSame( get_num_queries() - $num_queries, 1, 'Check to see query uncached after adding new post' ); + $this->assertSame( get_num_queries() - $num_queries, 1, 'Check to see query uncached after adding new post' ); $this->assertEquals( $post_four, get_adjacent_post( true, '', false ), 'Get forth post after new post is added' ); $num_queries = get_num_queries(); @@ -425,7 +425,7 @@ public function test_get_adjacent_post_cache() { 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 ) , 'Check to see query uncached after adding new term' ); - $this->assertSame( get_num_queries() - $num_queries,2, 'Check to see query uncached after adding new term' ); + $this->assertEquals( $post_four, get_adjacent_post( true, '', false ), 'Check to see query uncached after adding new term' ); + $this->assertSame( get_num_queries() - $num_queries, 2, 'Check to see query uncached after adding new term' ); } } From dce5189745dd1b687ca339ac24bf9a9c52f6732a Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Wed, 18 Jan 2023 10:17:47 +0000 Subject: [PATCH 7/8] Improve message in unit tests. --- tests/phpunit/tests/link/getAdjacentPost.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index 4fbaf0c22ad78..c82b46a9e8eda 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -396,14 +396,14 @@ public function test_get_adjacent_post_cache() { // Test getting the right result $first_run = get_adjacent_post( false, '', true ); - $this->assertEquals( $post_one, $first_run, 'Get first post when on second post' ); - $this->assertNotEquals( $post_two, $first_run, 'Do not get second post when on second post' ); + $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, 'Do not get second post when on second post on second run' ); - $this->assertEquals( $post_one, $second_run, 'Get first post when on second post on second run' ); + $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. @@ -415,17 +415,17 @@ public function test_get_adjacent_post_cache() { ); $num_queries = get_num_queries(); - $this->assertEquals( $post_one, get_adjacent_post( false, '', true ), 'Get first post after new post is added' ); - $this->assertSame( get_num_queries() - $num_queries, 1, 'Check to see query uncached after adding new post' ); + $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 ), 'Get forth post 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 ), 'Get forth post after new post is added' ); + $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 ), 'Check to see query uncached after adding new term' ); - $this->assertSame( get_num_queries() - $num_queries, 2, 'Check to see query uncached after adding new term' ); + $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' ); } } From b5945b324bcb5543bdaa783df19fef0bf0a61ab5 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Wed, 18 Jan 2023 10:19:36 +0000 Subject: [PATCH 8/8] Apply suggestions from code review Co-authored-by: Mukesh Panchal --- tests/phpunit/tests/link/getAdjacentPost.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/link/getAdjacentPost.php b/tests/phpunit/tests/link/getAdjacentPost.php index c82b46a9e8eda..d365aa49dd7d9 100644 --- a/tests/phpunit/tests/link/getAdjacentPost.php +++ b/tests/phpunit/tests/link/getAdjacentPost.php @@ -394,7 +394,7 @@ public function test_get_adjacent_post_cache() { // Test normal post adjacency. $this->go_to( get_permalink( $post_two->ID ) ); - // Test getting the right result + // 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' );