Make WordPress Core

Changeset 55083


Ignore:
Timestamp:
01/18/2023 09:56:55 AM (4 years ago)
Author:
spacedmonkey
Message:

Taxonomy: Remove placeholder from WP_Term_Query cache key.

Remove escape placeholder from query cache key, as placeholders are on a based on a unique id on every request. This meant that it is impossible for a cache to be reused, making queries that use escape placeholders such as searches, meta queries or using the description__like / name__like parameters were unable to be cached.

Follow on from [54634].

Props spacedmonkey, peterwilsoncc.
Fixes #57298.

Location:
trunk
Files:
2 edited

Legend:

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

    r54867 r55083  
    775775                }
    776776
    777                 // $args can be anything. Only use the args defined in defaults to compute the key.
    778                 $cache_args = wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) );
    779 
    780                 unset( $cache_args['update_term_meta_cache'] );
    781 
    782                 if ( 'count' !== $_fields && 'all_with_object_id' !== $_fields ) {
    783                         $cache_args['fields'] = 'all';
    784                 }
    785 
    786                 $key          = md5( serialize( $cache_args ) . serialize( $taxonomies ) . $this->request );
    787                 $last_changed = wp_cache_get_last_changed( 'terms' );
    788                 $cache_key    = "get_terms:$key:$last_changed";
    789                 $cache        = wp_cache_get( $cache_key, 'terms' );
     777                $cache_key = $this->generate_cache_key( $args, $this->request );
     778                $cache     = wp_cache_get( $cache_key, 'terms' );
    790779
    791780                if ( false !== $cache ) {
     
    11431132                return $term_objects;
    11441133        }
     1134
     1135        /**
     1136         * Generate cache key.
     1137         *
     1138         * @since 6.2.0
     1139         *
     1140         * @global wpdb $wpdb WordPress database abstraction object.
     1141         *
     1142         * @param array  $args WP_Term_Query arguments.
     1143         * @param string $sql  SQL statement.
     1144         *
     1145         * @return string Cache key.
     1146         */
     1147        protected function generate_cache_key( array $args, $sql ) {
     1148                global $wpdb;
     1149                // $args can be anything. Only use the args defined in defaults to compute the key.
     1150                $cache_args = wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) );
     1151
     1152                unset( $cache_args['update_term_meta_cache'] );
     1153
     1154                if ( 'count' !== $args['fields'] && 'all_with_object_id' !== $args['fields'] ) {
     1155                        $cache_args['fields'] = 'all';
     1156                }
     1157                $taxonomies = (array) $args['taxonomy'];
     1158
     1159                // Replace wpdb placeholder in the SQL statement used by the cache key.
     1160                $sql = $wpdb->remove_placeholder_escape( $sql );
     1161
     1162                $key          = md5( serialize( $cache_args ) . serialize( $taxonomies ) . $sql );
     1163                $last_changed = wp_cache_get_last_changed( 'terms' );
     1164                return "get_terms:$key:$last_changed";
     1165        }
    11451166}
  • trunk/tests/phpunit/tests/term/query.php

    r53942 r55083  
    868868                $this->assertContains( $t1, $q->terms );
    869869        }
     870
     871        /**
     872         * Ensure cache keys are generated without WPDB placeholders.
     873         *
     874         * @ticket 57298
     875         *
     876         * @covers       WP_Term_Query::generate_cache_key
     877         * @dataProvider data_query_cache
     878         */
     879        public function test_generate_cache_key_placeholder( $args ) {
     880                global $wpdb;
     881                $query1 = new WP_Term_Query();
     882                $query1->query( $args );
     883
     884                $query_vars = $query1->query_vars;
     885                $request    = $query1->request;
     886
     887                $reflection = new ReflectionMethod( $query1, 'generate_cache_key' );
     888                $reflection->setAccessible( true );
     889
     890                $cache_key_1 = $reflection->invoke( $query1, $query_vars, $request );
     891
     892                $request_without_placeholder = $wpdb->remove_placeholder_escape( $request );
     893
     894                $cache_key_2 = $reflection->invoke( $query1, $query_vars, $request_without_placeholder );
     895
     896                $this->assertSame( $cache_key_1, $cache_key_2, 'Cache key differs when using wpdb placeholder.' );
     897        }
     898
     899        /**
     900         * Data provider.
     901         *
     902         * @return array[] Test parameters.
     903         */
     904        public function data_query_cache() {
     905                return array(
     906                        'empty query'                => array(
     907                                'args' => array(),
     908                        ),
     909                        'search query'               => array(
     910                                'args' => array(
     911                                        'search' => 'title',
     912                                ),
     913                        ),
     914                        'search name query'          => array(
     915                                'args' => array(
     916                                        'name__like' => 'title',
     917                                ),
     918                        ),
     919                        'search description query'   => array(
     920                                'args' => array(
     921                                        'description__like' => 'title',
     922                                ),
     923                        ),
     924                        'meta query'                 => array(
     925                                'args' => array(
     926                                        'meta_query' => array(
     927                                                array(
     928                                                        'key' => 'color',
     929                                                ),
     930                                        ),
     931                                ),
     932                        ),
     933                        'meta query search'          => array(
     934                                'args' => array(
     935                                        'meta_query' => array(
     936                                                array(
     937                                                        'key'     => 'color',
     938                                                        'value'   => '00',
     939                                                        'compare' => 'LIKE',
     940                                                ),
     941                                        ),
     942                                ),
     943                        ),
     944                        'nested meta query search'   => array(
     945                                'args' => array(
     946                                        'meta_query' => array(
     947                                                'relation' => 'AND',
     948                                                array(
     949                                                        'key'     => 'color',
     950                                                        'value'   => '00',
     951                                                        'compare' => 'LIKE',
     952                                                ),
     953                                                array(
     954                                                        'relation' => 'OR',
     955                                                        array(
     956                                                                'key'     => 'color',
     957                                                                'value'   => '00',
     958                                                                'compare' => 'LIKE',
     959                                                        ),
     960                                                        array(
     961                                                                'relation' => 'AND',
     962                                                                array(
     963                                                                        'key'     => 'wp_test_suite',
     964                                                                        'value'   => '56802',
     965                                                                        'compare' => 'LIKE',
     966                                                                ),
     967                                                                array(
     968                                                                        'key'     => 'wp_test_suite_too',
     969                                                                        'value'   => '56802',
     970                                                                        'compare' => 'LIKE',
     971                                                                ),
     972                                                        ),
     973                                                ),
     974                                        ),
     975                                ),
     976                        ),
     977                        'meta query not like search' => array(
     978                                'args' => array(
     979                                        'meta_query' => array(
     980                                                array(
     981                                                        'key'     => 'color',
     982                                                        'value'   => 'ff',
     983                                                        'compare' => 'NOT LIKE',
     984                                                ),
     985                                        ),
     986                                ),
     987                        ),
     988                );
     989        }
    870990}
Note: See TracChangeset for help on using the changeset viewer.