Taxonomy: Better error handling when fetching object terms from cache.

Since [37573], `get_object_term_cache()` has expected term IDs to be
stored in the taxonomy relationship cache. The function would then
reach directly into the 'terms' cache to fetch the data corresponding
to a given term, before returning a `WP_Term` object. This caused
problems when, for one reason or another, term data was cached
inconsistently:

* If the 'terms' cache is empty for a given term ID, despite the earlier call to `_prime_term_caches()`, `get_term()` would return an error object.
* If the array of cached term IDs contains an invalid ID, `get_term()` would return an error object.

We avoid these errors by no longer touching the 'terms' cache directly,
but running term IDs through `get_term()` and allowing that function to
reference the cache (and database, as needed). If `get_term()` returns
an error object for any of the cached term IDs, `get_object_term_cache()`
will return that error object alone. This change ensures that upstream
functions, like `get_the_terms()`, return `WP_Error` objects in a
predictable fashion.

Props dd32, michalzuber.
Fixes #37291.

git-svn-id: https://develop.svn.wordpress.org/trunk@38776 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges
2016-10-11 01:55:58 +00:00
parent b87156d05f
commit 5fef526cca
2 changed files with 38 additions and 3 deletions

View File

@@ -390,4 +390,30 @@ class Tests_Term_Cache extends WP_UnitTestCase {
$this->assertSame( $term_meta, 'bar' );
$this->assertEquals( $num_queries, $wpdb->num_queries );
}
/**
* @ticket 37291
*/
public function test_get_object_term_cache_should_return_error_if_any_term_is_an_error() {
register_taxonomy( 'wptests_tax', 'post' );
$t = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax' ) );
$p = self::factory()->post->create();
wp_set_object_terms( $p, $t, 'wptests_tax' );
// Prime cache.
$terms = get_the_terms( $p, 'wptests_tax' );
$this->assertEqualSets( array( $t ), wp_list_pluck( $terms, 'term_id' ) );
/*
* Modify cached array to insert an empty term ID,
* which will trigger an error in get_term().
*/
$cached_ids = wp_cache_get( $p, 'wptests_tax_relationships' );
$cached_ids[] = 0;
wp_cache_set( $p, $cached_ids, 'wptests_tax_relationships' );
$terms = get_the_terms( $p, 'wptests_tax' );
$this->assertWPError( $terms );
}
}