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:
parent
b87156d05f
commit
5fef526cca
|
@ -3010,10 +3010,14 @@ function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) {
|
||||||
* function only fetches relationship data that is already in the cache.
|
* function only fetches relationship data that is already in the cache.
|
||||||
*
|
*
|
||||||
* @since 2.3.0
|
* @since 2.3.0
|
||||||
|
* @since 4.6.2 Returns a WP_Error object if get_term() returns an error for
|
||||||
|
* any of the matched terms.
|
||||||
*
|
*
|
||||||
* @param int $id Term object ID.
|
* @param int $id Term object ID.
|
||||||
* @param string $taxonomy Taxonomy name.
|
* @param string $taxonomy Taxonomy name.
|
||||||
* @return bool|array Array of `WP_Term` objects, if cached False if cache is empty for `$taxonomy` and `$id`.
|
* @return bool|array|WP_Error Array of `WP_Term` objects, if cached.
|
||||||
|
* False if cache is empty for `$taxonomy` and `$id`.
|
||||||
|
* WP_Error if get_term() returns an error object for any term.
|
||||||
*/
|
*/
|
||||||
function get_object_term_cache( $id, $taxonomy ) {
|
function get_object_term_cache( $id, $taxonomy ) {
|
||||||
$_term_ids = wp_cache_get( $id, "{$taxonomy}_relationships" );
|
$_term_ids = wp_cache_get( $id, "{$taxonomy}_relationships" );
|
||||||
|
@ -3038,10 +3042,15 @@ function get_object_term_cache( $id, $taxonomy ) {
|
||||||
|
|
||||||
$terms = array();
|
$terms = array();
|
||||||
foreach ( $term_ids as $term_id ) {
|
foreach ( $term_ids as $term_id ) {
|
||||||
$terms[] = wp_cache_get( $term_id, 'terms' );
|
$term = get_term( $term_id );
|
||||||
|
if ( is_wp_error( $term ) ) {
|
||||||
|
return $term;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_map( 'get_term', $terms );
|
$terms[] = $term;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $terms;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -390,4 +390,30 @@ class Tests_Term_Cache extends WP_UnitTestCase {
|
||||||
$this->assertSame( $term_meta, 'bar' );
|
$this->assertSame( $term_meta, 'bar' );
|
||||||
$this->assertEquals( $num_queries, $wpdb->num_queries );
|
$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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue