Add cache invalidation when updating a term, example: create a category, assign it to a post, edit the category. Currently, the post's term cache is not updated. When updating terms in a given taxonomy, invalidate the object term caches linked to that taxonomy.
Introduce `get_taxonomy_last_changed()`, `set_taxonomy_last_changed()`, and `post_taxonomy_is_fresh()`. `post_taxonomy_is_fresh()` is only called in `get_object_term_cache()` - at which point the taxonomy's `last_changed` value is checked against the post's `{$taxonomy}_last_changed` value. `set_taxonomy_last_changed()` is called whenever directory database queries are made that insert new terms or affect existing terms. Fixes #22526. git-svn-id: https://develop.svn.wordpress.org/trunk@27101 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
9b85472ac9
commit
e33ef0c6ac
|
@ -1876,6 +1876,7 @@ function wp_delete_term( $term, $taxonomy, $args = array() ) {
|
|||
do_action( 'edit_term_taxonomies', $edit_tt_ids );
|
||||
$wpdb->update( $wpdb->term_taxonomy, compact( 'parent' ), array( 'parent' => $term_obj->term_id) + compact( 'taxonomy' ) );
|
||||
do_action( 'edited_term_taxonomies', $edit_tt_ids );
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
}
|
||||
|
||||
$objects = $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $tt_id ) );
|
||||
|
@ -1910,6 +1911,7 @@ function wp_delete_term( $term, $taxonomy, $args = array() ) {
|
|||
$wpdb->delete( $wpdb->terms, array( 'term_id' => $term ) );
|
||||
|
||||
clean_term_cache($term, $taxonomy);
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
|
||||
do_action( 'delete_term', $term, $tt_id, $taxonomy, $deleted_term );
|
||||
do_action( "delete_$taxonomy", $term, $tt_id, $deleted_term );
|
||||
|
@ -2162,6 +2164,7 @@ function wp_insert_term( $term, $taxonomy, $args = array() ) {
|
|||
do_action( 'edit_terms', $alias->term_id, $taxonomy );
|
||||
$wpdb->update($wpdb->terms, compact('term_group'), array('term_id' => $alias->term_id) );
|
||||
do_action( 'edited_terms', $alias->term_id, $taxonomy );
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2223,6 +2226,7 @@ function wp_insert_term( $term, $taxonomy, $args = array() ) {
|
|||
$term_id = apply_filters('term_id_filter', $term_id, $tt_id);
|
||||
|
||||
clean_term_cache($term_id, $taxonomy);
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
|
||||
do_action("created_term", $term_id, $tt_id, $taxonomy);
|
||||
do_action("created_$taxonomy", $term_id, $tt_id);
|
||||
|
@ -2329,6 +2333,7 @@ function wp_set_object_terms($object_id, $terms, $taxonomy, $append = false) {
|
|||
}
|
||||
|
||||
wp_cache_delete( $object_id, $taxonomy . '_relationships' );
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
|
||||
do_action('set_object_terms', $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids);
|
||||
return $tt_ids;
|
||||
|
@ -2407,6 +2412,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 ) );
|
||||
do_action( 'deleted_term_relationships', $object_id, $tt_ids );
|
||||
wp_update_term_count( $tt_ids, $taxonomy );
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
|
||||
return (bool) $deleted;
|
||||
}
|
||||
|
@ -2565,6 +2571,7 @@ function wp_update_term( $term_id, $taxonomy, $args = array() ) {
|
|||
do_action( 'edit_terms', $alias->term_id, $taxonomy );
|
||||
$wpdb->update( $wpdb->terms, compact('term_group'), array( 'term_id' => $alias->term_id ) );
|
||||
do_action( 'edited_terms', $alias->term_id, $taxonomy );
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2600,6 +2607,7 @@ function wp_update_term( $term_id, $taxonomy, $args = array() ) {
|
|||
$term_id = apply_filters('term_id_filter', $term_id, $tt_id);
|
||||
|
||||
clean_term_cache($term_id, $taxonomy);
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
|
||||
do_action("edited_term", $term_id, $tt_id, $taxonomy);
|
||||
do_action("edited_$taxonomy", $term_id, $tt_id);
|
||||
|
@ -2738,9 +2746,12 @@ function clean_object_term_cache($object_ids, $object_type) {
|
|||
|
||||
$taxonomies = get_object_taxonomies( $object_type );
|
||||
|
||||
foreach ( $object_ids as $id )
|
||||
foreach ( $taxonomies as $taxonomy )
|
||||
foreach ( $object_ids as $id ) {
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
wp_cache_delete($id, "{$taxonomy}_relationships");
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
}
|
||||
}
|
||||
|
||||
do_action('clean_object_term_cache', $object_ids, $object_type);
|
||||
}
|
||||
|
@ -2800,6 +2811,7 @@ function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) {
|
|||
}
|
||||
|
||||
do_action('clean_term_cache', $ids, $taxonomy);
|
||||
set_taxonomy_last_changed( $taxonomy );
|
||||
}
|
||||
|
||||
wp_cache_set( 'last_changed', microtime(), 'terms' );
|
||||
|
@ -2819,6 +2831,9 @@ function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) {
|
|||
* @return bool|array Empty array if $terms found, but not $taxonomy. False if nothing is in cache for $taxonomy and $id.
|
||||
*/
|
||||
function get_object_term_cache($id, $taxonomy) {
|
||||
if ( ! post_taxonomy_is_fresh( $id, $taxonomy ) ) {
|
||||
return false;
|
||||
}
|
||||
$cache = wp_cache_get($id, "{$taxonomy}_relationships");
|
||||
return $cache;
|
||||
}
|
||||
|
@ -3117,6 +3132,7 @@ function _update_post_term_count( $terms, $taxonomy ) {
|
|||
$wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
|
||||
do_action( 'edited_term_taxonomy', $term, $taxonomy );
|
||||
}
|
||||
set_taxonomy_last_changed( $taxonomy->name );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3142,6 +3158,7 @@ function _update_generic_term_count( $terms, $taxonomy ) {
|
|||
$wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
|
||||
do_action( 'edited_term_taxonomy', $term, $taxonomy );
|
||||
}
|
||||
set_taxonomy_last_changed( $taxonomy->name );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3469,3 +3486,53 @@ function wp_check_term_hierarchy_for_loops( $parent, $term_id, $taxonomy ) {
|
|||
|
||||
return $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the 'last_changed' value for the passed taxonomy. Retrieves
|
||||
* from cache, if present
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param string $taxonomy
|
||||
* @return int
|
||||
*/
|
||||
function get_taxonomy_last_changed( $taxonomy ) {
|
||||
$last_changed = wp_cache_get( 'last_changed', $taxonomy );
|
||||
if ( ! $last_changed ) {
|
||||
$last_changed = microtime();
|
||||
wp_cache_set( 'last_changed', $last_changed, $taxonomy );
|
||||
}
|
||||
return $last_changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset 'last_changed' for the passed taxonomy
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param string $taxonomy
|
||||
* @return int
|
||||
*/
|
||||
function set_taxonomy_last_changed( $taxonomy ) {
|
||||
wp_cache_delete( 'last_changed', $taxonomy );
|
||||
return get_taxonomy_last_changed( $taxonomy );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a post's cache for the passed taxonomy
|
||||
* is in sync.
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $taxonomy
|
||||
* @return boolean
|
||||
*/
|
||||
function post_taxonomy_is_fresh( $id, $taxonomy ) {
|
||||
$last_changed = get_taxonomy_last_changed( $taxonomy );
|
||||
$post_last_changed = wp_cache_get( $id, $taxonomy . '_last_changed' );
|
||||
if ( ! $post_last_changed || $last_changed !== $post_last_changed ) {
|
||||
wp_cache_set( $id, $last_changed, $taxonomy . '_last_changed' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -568,6 +568,56 @@ class Tests_Term extends WP_UnitTestCase {
|
|||
$this->assertEquals( 0, $count );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 22526
|
||||
*/
|
||||
function test_get_taxonomy_last_changed() {
|
||||
$last_changed = get_taxonomy_last_changed( 'category' );
|
||||
$last_changed_cache = wp_cache_get( 'last_changed', 'category' );
|
||||
$this->assertEquals( $last_changed, $last_changed_cache );
|
||||
wp_cache_delete( 'last_changed', 'category' );
|
||||
$this->assertEquals( $last_changed, $last_changed_cache );
|
||||
$last_changed = get_taxonomy_last_changed( 'category' );
|
||||
$this->assertNotEquals( $last_changed, $last_changed_cache );
|
||||
|
||||
$last_changed2 = get_taxonomy_last_changed( 'category' );
|
||||
$this->factory->category->create();
|
||||
$last_changed3 = get_taxonomy_last_changed( 'category' );
|
||||
$this->assertNotEquals( $last_changed2, $last_changed3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 22526
|
||||
*/
|
||||
function test_set_taxonomy_last_changed() {
|
||||
$last_changed1 = set_taxonomy_last_changed( 'category' );
|
||||
$last_changed2 = set_taxonomy_last_changed( 'category' );
|
||||
$this->assertNotEquals( $last_changed1, $last_changed2 );
|
||||
|
||||
$last_changed3 = set_taxonomy_last_changed( 'category' );
|
||||
$last_changed4 = get_taxonomy_last_changed( 'category' );
|
||||
$this->assertEquals( $last_changed3, $last_changed4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 22526
|
||||
*/
|
||||
function test_post_taxonomy_is_fresh() {
|
||||
$post_id = $this->factory->post->create();
|
||||
$term_id = $this->factory->category->create( array( 'name' => 'Foo' ) );
|
||||
wp_set_post_categories( $post_id, $term_id );
|
||||
|
||||
$this->assertFalse( post_taxonomy_is_fresh( $post_id, 'category' ) );
|
||||
$this->assertTrue( post_taxonomy_is_fresh( $post_id, 'category' ) );
|
||||
$this->assertTrue( post_taxonomy_is_fresh( $post_id, 'category' ) );
|
||||
|
||||
wp_update_term( $term_id, 'category', array( 'name' => 'Bar' ) );
|
||||
|
||||
$this->assertFalse( post_taxonomy_is_fresh( $post_id, 'category' ) );
|
||||
get_the_category( $post_id );
|
||||
$this->assertTrue( post_taxonomy_is_fresh( $post_id, 'category' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 22526
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue