Make WordPress Core


Ignore:
Timestamp:
06/14/2022 11:41:33 AM (2 years ago)
Author:
spacedmonkey
Message:

Taxonomy: Fix caching issues in WP_Term_Query class.

Introduced [52836] when passing child_of or pad_counts parameters to get_terms or WP_Term_Query class, the array of terms received by the query, was not correctly cached. This
change simplifies the logic in WP_Term_Query and ensures terms are correctly cached. This change also, improves performance, by only caching an array of term ids where possible.

Props denishua, spacedmonkey, oztaser, peterwilsoncc, SergeyBiryukov, georgestephanis, jnz31, knutsp, mukesh27, costdev.
Fixes #55837.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-term-query.php

    r53469 r53496  
    771771        $cache_args = wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) );
    772772
    773         unset( $cache_args['pad_counts'], $cache_args['update_term_meta_cache'] );
     773        unset( $cache_args['update_term_meta_cache'] );
    774774
    775775        if ( 'count' !== $_fields && 'all_with_object_id' !== $_fields ) {
     
    784784        if ( false !== $cache ) {
    785785            if ( 'ids' === $_fields ) {
    786                 $term_ids = wp_list_pluck( $cache, 'term_id' );
    787                 $cache    = array_map( 'intval', $term_ids );
     786                $cache = array_map( 'intval', $cache );
    788787            } elseif ( 'count' !== $_fields ) {
    789                 $term_ids = wp_list_pluck( $cache, 'term_id' );
     788                if ( ( 'all_with_object_id' === $_fields && ! empty( $args['object_ids'] ) ) || ( 'all' === $_fields && $args['pad_counts'] ) ) {
     789                    $term_ids = wp_list_pluck( $cache, 'term_id' );
     790                } else {
     791                    $term_ids = array_map( 'intval', $cache );
     792                }
    790793                _prime_term_caches( $term_ids, $args['update_term_meta_cache'] );
    791794                $term_objects = $this->populate_terms( $cache );
     
    850853        }
    851854
    852         /*
    853          * When querying for terms connected to objects, we may get
    854          * duplicate results. The duplicates should be preserved if
    855          * `$fields` is 'all_with_object_id', but should otherwise be
    856          * removed.
    857          */
    858         if ( ! empty( $args['object_ids'] ) && 'all_with_object_id' !== $_fields ) {
    859             $_tt_ids = array();
    860             $_terms  = array();
    861             foreach ( $terms as $term ) {
    862                 if ( isset( $_tt_ids[ $term->term_id ] ) ) {
    863                     continue;
    864                 }
    865 
    866                 $_tt_ids[ $term->term_id ] = 1;
    867                 $_terms[]                  = $term;
    868             }
    869 
    870             $terms = $_terms;
    871         }
    872 
    873855        // Hierarchical queries are not limited, so 'offset' and 'number' must be handled now.
    874         if ( $hierarchical && $number && is_array( $terms ) ) {
    875             if ( $offset >= count( $terms ) ) {
    876                 $terms        = array();
     856        if ( $hierarchical && $number && is_array( $term_objects ) ) {
     857            if ( $offset >= count( $term_objects ) ) {
    877858                $term_objects = array();
    878859            } else {
    879                 $terms        = array_slice( $terms, $offset, $number, true );
    880860                $term_objects = array_slice( $term_objects, $offset, $number, true );
    881861            }
     
    888868        }
    889869
    890         wp_cache_add( $cache_key, $terms, 'terms' );
    891         $terms = $this->format_terms( $term_objects, $_fields );
    892 
    893         $this->terms = $terms;
     870        if ( 'all_with_object_id' === $_fields && ! empty( $args['object_ids'] ) ) {
     871            $term_cache = array();
     872            foreach ( $term_objects as $term ) {
     873                $object            = new stdClass();
     874                $object->term_id   = $term->term_id;
     875                $object->object_id = $term->object_id;
     876                $term_cache[]      = $object;
     877            }
     878        } elseif ( 'all' === $_fields && $args['pad_counts'] ) {
     879            $term_cache = array();
     880            foreach ( $term_objects as $term ) {
     881                $object          = new stdClass();
     882                $object->term_id = $term->term_id;
     883                $object->count   = $term->count;
     884                $term_cache[]    = $object;
     885            }
     886        } else {
     887            $term_cache = wp_list_pluck( $term_objects, 'term_id' );
     888        }
     889        wp_cache_add( $cache_key, $term_cache, 'terms' );
     890        $this->terms = $this->format_terms( $term_objects, $_fields );
     891
    894892        return $this->terms;
    895893    }
     
    11201118                    $term->object_id = (int) $term_data->object_id;
    11211119                }
     1120                if ( property_exists( $term_data, 'count' ) ) {
     1121                    $term->count = (int) $term_data->count;
     1122                }
    11221123            } else {
    11231124                $term = get_term( $term_data );
Note: See TracChangeset for help on using the changeset viewer.