From 0d28b59c0b485817b2e99c9bef4abae71015245f Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Tue, 13 Oct 2015 03:06:27 +0000 Subject: [PATCH] Use a more reliable method for generating `get_terms()` cache key. Previously, the cache key included a serialization of `list_terms_exclusions` callbacks, to ensure that the cache was differentiated properly for different uses of the `list_terms_exclusions` filter. This strategy was flawed in a couple of ways: serialization doesn't work equally well for all callable types; the serialization required reaching into the `$wp_filter` global; serializing the callback itself didn't properly account for the possibility that the callback might return different values in different contexts; the cache key didn't account for other filters that similarly affect the cached values, such as `terms_clauses`. We skirt all these issues by concatenating the cache key using the SQL query string, which will reflect all filters applied earlier in `get_terms()`. Props boonebgorges, wonderboymusic. Fixes #21267. git-svn-id: https://develop.svn.wordpress.org/trunk@35120 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/taxonomy-functions.php | 53 +++++++++++++------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/wp-includes/taxonomy-functions.php b/src/wp-includes/taxonomy-functions.php index 88f944edc2..a20ce7c719 100644 --- a/src/wp-includes/taxonomy-functions.php +++ b/src/wp-includes/taxonomy-functions.php @@ -1144,33 +1144,6 @@ function get_terms( $taxonomies, $args = '' ) { } } - // $args can be whatever, only use the args defined in defaults to compute the key. - $filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : ''; - $key = md5( serialize( wp_array_slice_assoc( $args, array_keys( $defaults ) ) ) . serialize( $taxonomies ) . $filter_key ); - $last_changed = wp_cache_get( 'last_changed', 'terms' ); - if ( ! $last_changed ) { - $last_changed = microtime(); - wp_cache_set( 'last_changed', $last_changed, 'terms' ); - } - $cache_key = "get_terms:$key:$last_changed"; - $cache = wp_cache_get( $cache_key, 'terms' ); - if ( false !== $cache ) { - if ( 'all' === $args['fields'] ) { - $cache = array_map( 'get_term', $cache ); - } - - /** - * Filter the given taxonomy's terms cache. - * - * @since 2.3.0 - * - * @param array $cache Cached array of terms for the given taxonomy. - * @param array $taxonomies An array of taxonomies. - * @param array $args An array of get_terms() arguments. - */ - return apply_filters( 'get_terms', $cache, $taxonomies, $args ); - } - $_orderby = strtolower( $args['orderby'] ); if ( 'count' == $_orderby ) { $orderby = 'tt.count'; @@ -1418,6 +1391,32 @@ function get_terms( $taxonomies, $args = '' ) { $query = "SELECT $fields FROM $wpdb->terms AS t $join WHERE $where $orderby $order $limits"; + // $args can be anything. Only use the args defined in defaults to compute the key. + $key = md5( serialize( wp_array_slice_assoc( $args, array_keys( $defaults ) ) ) . serialize( $taxonomies ) . $query ); + $last_changed = wp_cache_get( 'last_changed', 'terms' ); + if ( ! $last_changed ) { + $last_changed = microtime(); + wp_cache_set( 'last_changed', $last_changed, 'terms' ); + } + $cache_key = "get_terms:$key:$last_changed"; + $cache = wp_cache_get( $cache_key, 'terms' ); + if ( false !== $cache ) { + if ( 'all' === $_fields ) { + $cache = array_map( 'get_term', $cache ); + } + + /** + * Filter the given taxonomy's terms cache. + * + * @since 2.3.0 + * + * @param array $cache Cached array of terms for the given taxonomy. + * @param array $taxonomies An array of taxonomies. + * @param array $args An array of get_terms() arguments. + */ + return apply_filters( 'get_terms', $cache, $taxonomies, $args ); + } + if ( 'count' == $_fields ) { return $wpdb->get_var( $query ); }