From a160be35b1295ad9930d5e2d59d942bddafbd7dd Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Fri, 25 Sep 2015 13:46:36 +0000 Subject: [PATCH] Bust term query cache when modifying term meta. The 'last_changed' incrementor is used to invalidate the `get_terms()` query cache. Since `get_terms()` queries may reference 'meta_query', changing term metadata could change the results of the queries. So we invalidate the cache on add, delete, and update. See #10142. git-svn-id: https://develop.svn.wordpress.org/trunk@34538 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/taxonomy-functions.php | 27 ++++++- tests/phpunit/tests/term/meta.php | 107 +++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/taxonomy-functions.php b/src/wp-includes/taxonomy-functions.php index 59fc9a0bf1..3d091e9165 100644 --- a/src/wp-includes/taxonomy-functions.php +++ b/src/wp-includes/taxonomy-functions.php @@ -1488,7 +1488,14 @@ function get_terms( $taxonomies, $args = '' ) { * @return int|bool Meta ID on success, false on failure. */ function add_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) { - return add_metadata( 'term', $term_id, $meta_key, $meta_value, $unique ); + $added = add_metadata( 'term', $term_id, $meta_key, $meta_value, $unique ); + + // Bust term query cache. + if ( $added ) { + wp_cache_set( 'last_changed', microtime(), 'terms' ); + } + + return $added; } /** @@ -1502,7 +1509,14 @@ function add_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) { * @return bool True on success, false on failure. */ function delete_term_meta( $term_id, $meta_key, $meta_value = '' ) { - return delete_metadata( 'term', $term_id, $meta_key, $meta_value ); + $deleted = delete_metadata( 'term', $term_id, $meta_key, $meta_value ); + + // Bust term query cache. + if ( $deleted ) { + wp_cache_set( 'last_changed', microtime(), 'terms' ); + } + + return $deleted; } /** @@ -1536,7 +1550,14 @@ function get_term_meta( $term_id, $key = '', $single = false ) { * @return int|bool Meta ID if the key didn't previously exist. True on successful update. False on failure. */ function update_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) { - return update_metadata( 'term', $term_id, $meta_key, $meta_value, $prev_value ); + $updated = update_metadata( 'term', $term_id, $meta_key, $meta_value, $prev_value ); + + // Bust term query cache. + if ( $updated ) { + wp_cache_set( 'last_changed', microtime(), 'terms' ); + } + + return $updated; } /** diff --git a/tests/phpunit/tests/term/meta.php b/tests/phpunit/tests/term/meta.php index bdd4b369e3..7550f3173b 100644 --- a/tests/phpunit/tests/term/meta.php +++ b/tests/phpunit/tests/term/meta.php @@ -144,4 +144,111 @@ class Tests_Term_Meta extends WP_UnitTestCase { } } } + + public function test_adding_term_meta_should_bust_get_terms_cache() { + $terms = $this->factory->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) ); + + add_term_meta( $terms[0], 'foo', 'bar' ); + + // Prime cache. + $found = get_terms( 'wptests_tax', array( + 'hide_empty' => false, + 'fields' => 'ids', + 'meta_query' => array( + array( + 'key' => 'foo', + 'value' => 'bar', + ), + ), + ) ); + + $this->assertEqualSets( array( $terms[0] ), $found ); + + add_term_meta( $terms[1], 'foo', 'bar' ); + + $found = get_terms( 'wptests_tax', array( + 'hide_empty' => false, + 'fields' => 'ids', + 'meta_query' => array( + array( + 'key' => 'foo', + 'value' => 'bar', + ), + ), + ) ); + + $this->assertEqualSets( array( $terms[0], $terms[1] ), $found ); + } + + public function test_updating_term_meta_should_bust_get_terms_cache() { + $terms = $this->factory->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) ); + + add_term_meta( $terms[0], 'foo', 'bar' ); + add_term_meta( $terms[1], 'foo', 'baz' ); + + // Prime cache. + $found = get_terms( 'wptests_tax', array( + 'hide_empty' => false, + 'fields' => 'ids', + 'meta_query' => array( + array( + 'key' => 'foo', + 'value' => 'bar', + ), + ), + ) ); + + $this->assertEqualSets( array( $terms[0] ), $found ); + + update_term_meta( $terms[1], 'foo', 'bar' ); + + $found = get_terms( 'wptests_tax', array( + 'hide_empty' => false, + 'fields' => 'ids', + 'meta_query' => array( + array( + 'key' => 'foo', + 'value' => 'bar', + ), + ), + ) ); + + $this->assertEqualSets( array( $terms[0], $terms[1] ), $found ); + } + + public function test_deleting_term_meta_should_bust_get_terms_cache() { + $terms = $this->factory->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) ); + + add_term_meta( $terms[0], 'foo', 'bar' ); + add_term_meta( $terms[1], 'foo', 'bar' ); + + // Prime cache. + $found = get_terms( 'wptests_tax', array( + 'hide_empty' => false, + 'fields' => 'ids', + 'meta_query' => array( + array( + 'key' => 'foo', + 'value' => 'bar', + ), + ), + ) ); + + $this->assertEqualSets( array( $terms[0], $terms[1] ), $found ); + + delete_term_meta( $terms[1], 'foo', 'bar' ); + + $found = get_terms( 'wptests_tax', array( + 'hide_empty' => false, + 'fields' => 'ids', + 'meta_query' => array( + array( + 'key' => 'foo', + 'value' => 'bar', + ), + ), + ) ); + + $this->assertEqualSets( array( $terms[0] ), $found ); + } }