Make WordPress Core


Ignore:
Timestamp:
10/13/2015 03:06:27 AM (9 years ago)
Author:
boonebgorges
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/taxonomy-functions.php

    r35117 r35120  
    11451145    }
    11461146
    1147     // $args can be whatever, only use the args defined in defaults to compute the key.
    1148     $filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
    1149     $key = md5( serialize( wp_array_slice_assoc( $args, array_keys( $defaults ) ) ) . serialize( $taxonomies ) . $filter_key );
    1150     $last_changed = wp_cache_get( 'last_changed', 'terms' );
    1151     if ( ! $last_changed ) {
    1152         $last_changed = microtime();
    1153         wp_cache_set( 'last_changed', $last_changed, 'terms' );
    1154     }
    1155     $cache_key = "get_terms:$key:$last_changed";
    1156     $cache = wp_cache_get( $cache_key, 'terms' );
    1157     if ( false !== $cache ) {
    1158         if ( 'all' === $args['fields'] ) {
    1159             $cache = array_map( 'get_term', $cache );
    1160         }
    1161 
    1162         /**
    1163          * Filter the given taxonomy's terms cache.
    1164          *
    1165          * @since 2.3.0
    1166          *
    1167          * @param array $cache      Cached array of terms for the given taxonomy.
    1168          * @param array $taxonomies An array of taxonomies.
    1169          * @param array $args       An array of get_terms() arguments.
    1170          */
    1171         return apply_filters( 'get_terms', $cache, $taxonomies, $args );
    1172     }
    1173 
    11741147    $_orderby = strtolower( $args['orderby'] );
    11751148    if ( 'count' == $_orderby ) {
     
    14191392    $query = "SELECT $fields FROM $wpdb->terms AS t $join WHERE $where $orderby $order $limits";
    14201393
     1394    // $args can be anything. Only use the args defined in defaults to compute the key.
     1395    $key = md5( serialize( wp_array_slice_assoc( $args, array_keys( $defaults ) ) ) . serialize( $taxonomies ) . $query );
     1396    $last_changed = wp_cache_get( 'last_changed', 'terms' );
     1397    if ( ! $last_changed ) {
     1398        $last_changed = microtime();
     1399        wp_cache_set( 'last_changed', $last_changed, 'terms' );
     1400    }
     1401    $cache_key = "get_terms:$key:$last_changed";
     1402    $cache = wp_cache_get( $cache_key, 'terms' );
     1403    if ( false !== $cache ) {
     1404        if ( 'all' === $_fields ) {
     1405            $cache = array_map( 'get_term', $cache );
     1406        }
     1407
     1408        /**
     1409         * Filter the given taxonomy's terms cache.
     1410         *
     1411         * @since 2.3.0
     1412         *
     1413         * @param array $cache      Cached array of terms for the given taxonomy.
     1414         * @param array $taxonomies An array of taxonomies.
     1415         * @param array $args       An array of get_terms() arguments.
     1416         */
     1417        return apply_filters( 'get_terms', $cache, $taxonomies, $args );
     1418    }
     1419
    14211420    if ( 'count' == $_fields ) {
    14221421        return $wpdb->get_var( $query );
Note: See TracChangeset for help on using the changeset viewer.