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.

Merges [40353] to the 4.7 branch.

Props mboynes.
Fixes #40306.


git-svn-id: https://develop.svn.wordpress.org/branches/4.7@40354 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2017-03-30 16:55:32 +00:00
parent a983452638
commit 52e1c3eff0
2 changed files with 64 additions and 0 deletions

View File

@ -2312,6 +2312,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.
@ -2406,6 +2407,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' ) );
}
}