Invalidate term query caches when setting or deleting term relationships.

Prior to 4.7, term relationships - as set by `wp_set_object_terms()` or
`wp_remove_object_terms()` - did not affect the term query cache. The
introduction of the 'object_ids' parameter in 4.7 means that the query
cache must be aware of object-term relationships. As such, the
'last_changed' incrementor is now invalidated when term relationships
are modified.

This bug only reared its head when delaying term counting, because term
counting performs its own term query cache invalidation.

Props mboynes.
Fixes #40306.

git-svn-id: https://develop.svn.wordpress.org/trunk@40353 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2017-03-30 16:49:47 +00:00
parent 2cd890decc
commit cc1c0639d0
2 changed files with 64 additions and 0 deletions

View File

@ -2282,6 +2282,7 @@ function wp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) {
}
wp_cache_delete( $object_id, $taxonomy . '_relationships' );
wp_cache_delete( 'last_changed', 'terms' );
/**
* Fires after an object's terms have been set.
@ -2376,6 +2377,7 @@ function wp_remove_object_terms( $object_id, $terms, $taxonomy ) {
$deleted = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id ) );
wp_cache_delete( $object_id, $taxonomy . '_relationships' );
wp_cache_delete( 'last_changed', 'terms' );
/**
* Fires immediately after an object-term relationship is deleted.

View File

@ -191,4 +191,66 @@ class Tests_Term_GetTheTerms extends WP_UnitTestCase {
$this->assertSame( $num_queries, $wpdb->num_queries );
}
/**
* @ticket 40306
*/
public function test_term_cache_should_be_invalidated_on_set_object_terms() {
register_taxonomy( 'wptests_tax', 'post' );
// Temporarily disable term counting, which performs its own cache invalidation.
wp_defer_term_counting( true );
// Create Test Category.
$term_id = self::factory()->term->create( array(
'taxonomy' => 'wptests_tax',
) );
$post_id = self::factory()->post->create();
// Prime cache.
get_the_terms( $post_id, 'wptests_tax' );
wp_set_object_terms( $post_id, $term_id, 'wptests_tax' );
$terms = get_the_terms( $post_id, 'wptests_tax' );
// Re-activate term counting so this doesn't affect other tests.
wp_defer_term_counting( false );
$this->assertTrue( is_array( $terms ) );
$this->assertSame( array( $term_id ), wp_list_pluck( $terms, 'term_id' ) );
}
/**
* @ticket 40306
*/
public function test_term_cache_should_be_invalidated_on_remove_object_terms() {
register_taxonomy( 'wptests_tax', 'post' );
// Create Test Category.
$term_ids = self::factory()->term->create_many( 2, array(
'taxonomy' => 'wptests_tax',
) );
$post_id = self::factory()->post->create();
wp_set_object_terms( $post_id, $term_ids, 'wptests_tax' );
// Prime cache.
get_the_terms( $post_id, 'wptests_tax' );
// Temporarily disable term counting, which performs its own cache invalidation.
wp_defer_term_counting( true );
wp_remove_object_terms( $post_id, $term_ids[0], 'wptests_tax' );
$terms = get_the_terms( $post_id, 'wptests_tax' );
// Re-activate term counting so this doesn't affect other tests.
wp_defer_term_counting( false );
$this->assertTrue( is_array( $terms ) );
$this->assertSame( array( $term_ids[1] ), wp_list_pluck( $terms, 'term_id' ) );
}
}