Make WordPress Core

Ticket #35816: 35816.3.diff

File 35816.3.diff, 20.2 KB (added by boonebgorges, 9 years ago)
  • new file src/wp-includes/class-wp-metadata-lazyloader.php

    diff --git src/wp-includes/class-wp-metadata-lazyloader.php src/wp-includes/class-wp-metadata-lazyloader.php
    new file mode 100644
    index 0000000..881b834
    - +  
     1<?php
     2
     3/**
     4 * Lazyloader for object metadata.
     5 *
     6 * When loading many objects of a given type, such as posts in a WP_Query loop, it often makes
     7 * sense to prime various metadata caches at the beginning of the loop. This means fetching all
     8 * relevant metadata with a single database query, a technique that has the potential to improve
     9 * performance dramatically in some cases.
     10 *
     11 * In cases where the given metadata may not even be used in the loop, we can improve performance
     12 * even more by only priming the metadata cache for affected items the first time a piece of metadata
     13 * is requested - ie, by lazyloading it. So, for example, comment meta may not be loaded into the
     14 * cache in the comments section of a post until the first time get_comment_meta() is called in the
     15 * context of the comment loop.
     16 *
     17 * WP uses the WP_Metadata_Lazyloader class to queue objects for metadata cache priming. The class
     18 * then detects the relevant get_*_meta() function call, and queries the metadata of all queued objects.
     19 *
     20 * Do not access this class directly. Use the wp_metadata_lazyloader() function.
     21 *
     22 * @since 4.5.0
     23 */
     24class WP_Metadata_Lazyloader {
     25        /**
     26         * Pending objects queue.
     27         *
     28         * @since 4.5.0
     29         * @var array
     30         */
     31        protected $pending_objects;
     32
     33        /**
     34         * Settings for supported object types.
     35         *
     36         * @since 4.5.0
     37         * @var array
     38         */
     39        protected $settings = array();
     40
     41        /**
     42         * Constructor.
     43         *
     44         * @since 4.5.0
     45         */
     46        public function __construct() {
     47                $this->settings = array(
     48                        'term' => array(
     49                                'filter'   => 'get_term_metadata',
     50                                'callback' => array( $this, 'lazyload_term_meta' ),
     51                        ),
     52                        'comment' => array(
     53                                'filter'   => 'get_comment_metadata',
     54                                'callback' => array( $this, 'lazyload_comment_meta' ),
     55                        ),
     56                );
     57        }
     58
     59        /**
     60         * Add objects to the metadata lazyload queue.
     61         *
     62         * @since 4.5.0
     63         *
     64         * @param string $object_type Type of object whose meta is to be lazyloaded. Accepts 'term' or 'comment'.
     65         * @param array  $object_ids  Array of object IDs.
     66         * @return bool|WP_Error True on success, WP_Error on failure.
     67         */
     68        public function queue_objects( $object_type, $object_ids ) {
     69                if ( ! isset( $this->settings[ $object_type ] ) ) {
     70                        return new WP_Error( 'invalid_object_type', __( 'Invalid object type' ) );
     71                }
     72
     73                $type_settings = $this->settings[ $object_type ];
     74
     75                if ( ! isset( $this->pending_objects[ $object_type ] ) ) {
     76                        $this->pending_objects[ $object_type ] = array();
     77                }
     78
     79                foreach ( $object_ids as $object_id ) {
     80                        // Keyed by ID for faster lookup.
     81                        if ( ! isset( $this->pending_objects[ $object_type ][ $object_id ] ) ) {
     82                                $this->pending_objects[ $object_type ][ $object_id ] = 1;
     83                        }
     84                }
     85
     86                add_filter( $type_settings['filter'], $type_settings['callback'] );
     87
     88                /**
     89                 * Fires after objects are added to the metadata lazyload queue.
     90                 *
     91                 * @since 4.5.0
     92                 *
     93                 * @param array                  $object_ids  Object IDs.
     94                 * @param string                 $object_type Type of object being queued.
     95                 * @param WP_Metadata_Lazyloader $lazyloader  The lazyloader object.
     96                 */
     97                do_action( 'metadata_lazyloader_queued_objects', $object_ids, $object_type, $this );
     98        }
     99
     100        /**
     101         * Reset lazyload queue for a given object type.
     102         *
     103         * @since 4.5.0
     104         *
     105         * @param string $object_type Object type. Accepts 'comment' or 'term'.
     106         * @return bool|WP_Error True on success, WP_Error on failure.
     107         */
     108        public function reset_queue( $object_type ) {
     109                if ( ! isset( $this->settings[ $object_type ] ) ) {
     110                        return new WP_Error( 'invalid_object_type', __( 'Invalid object type' ) );
     111                }
     112
     113                $type_settings = $this->settings[ $object_type ];
     114
     115                $this->pending_objects[ $object_type ] = array();
     116                remove_filter( $type_settings['filter'], $type_settings['callback'] );
     117        }
     118
     119        /**
     120         * Lazyloads term meta for queued terms.
     121         *
     122         * This method is public so that it can be used as a filter callback. As a rule, there
     123         * is no need to invoke it directly.
     124         *
     125         * @since 4.5.0
     126         * @access public
     127         *
     128         * @param mixed $check The `$check` param passed from the 'get_term_metadata' hook.
     129         * @return mixed In order not to short-circuit `get_metadata()`. Generally, this is `null`, but it could be
     130         *               another value if filtered by a plugin.
     131         */
     132        public function lazyload_term_meta( $check ) {
     133                if ( ! empty( $this->pending_objects['term'] ) ) {
     134                        update_termmeta_cache( array_keys( $this->pending_objects['term'] ) );
     135
     136                        // No need to run again for this set of terms.
     137                        $this->reset_queue( 'term' );
     138                }
     139
     140                return $check;
     141        }
     142
     143        /**
     144         * Lazyload comment meta for queued comments.
     145         *
     146         * This method is public so that it can be used as a filter callback. As a rule, there is no need to invoke it
     147         * directly, from either inside or outside the `WP_Query` object.
     148         *
     149         * @since 4.5.0
     150         *
     151         * @param mixed $check The `$check` param passed from the 'get_comment_metadata' hook.
     152         * @return mixed The original value of `$check`, so as not to short-circuit `get_comment_metadata()`.
     153         */
     154        public function lazyload_comment_meta( $check ) {
     155                if ( ! empty( $this->pending_objects['comment'] ) ) {
     156                        update_meta_cache( 'comment', array_keys( $this->pending_objects['comment'] ) );
     157
     158                        // No need to run again for this set of comments.
     159                        $this->reset_queue( 'comment' );
     160                }
     161
     162                return $check;
     163        }
     164}
  • src/wp-includes/comment-template.php

    diff --git src/wp-includes/comment-template.php src/wp-includes/comment-template.php
    index 4738dec..54df8b9 100644
    function comments_template( $file = '/comments.php', $separate_comments = false 
    13931393         */
    13941394        $wp_query->comments = apply_filters( 'comments_array', $comments_flat, $post->ID );
    13951395
    1396         // Set up lazy-loading for comment metadata.
    1397         add_action( 'get_comment_metadata', array( $wp_query, 'lazyload_comment_meta' ), 10, 2 );
    1398 
    13991396        $comments = &$wp_query->comments;
    14001397        $wp_query->comment_count = count($wp_query->comments);
    14011398        $wp_query->max_num_comment_pages = $comment_query->max_num_pages;
    function wp_list_comments( $args = array(), $comments = null ) { 
    20302027        if ( null === $r['reverse_top_level'] )
    20312028                $r['reverse_top_level'] = ( 'desc' == get_option('comment_order') );
    20322029
     2030        wp_queue_comments_for_comment_meta_lazyload( $_comments );
     2031
    20332032        if ( empty( $r['walker'] ) ) {
    20342033                $walker = new Walker_Comment;
    20352034        } else {
  • src/wp-includes/comment.php

    diff --git src/wp-includes/comment.php src/wp-includes/comment.php
    index 6d8f6e8..e3cabe5 100644
    function update_comment_meta($comment_id, $meta_key, $meta_value, $prev_value = 
    469469}
    470470
    471471/**
     472 * Queue comments for metadata lazyloading.
     473 *
     474 * @since 4.5.0
     475 *
     476 * @param array $comments Array of comment objects.
     477 */
     478function wp_queue_comments_for_comment_meta_lazyload( $comments ) {
     479        // Don't use `wp_list_pluck()` to avoid by-reference manipulation.
     480        $comment_ids = array();
     481        if ( is_array( $comments ) ) {
     482                foreach ( $comments as $comment ) {
     483                        if ( $comment instanceof WP_Comment ) {
     484                                $comment_ids[] = $comment->comment_ID;
     485                        }
     486                }
     487        }
     488
     489        if ( $comment_ids ) {
     490                $lazyloader = wp_metadata_lazyloader();
     491                $lazyloader->queue_objects( 'comment', $comment_ids );
     492        }
     493}
     494
     495/**
    472496 * Sets the cookies used to store an unauthenticated commentator's identity. Typically used
    473497 * to recall previous comments by this commentator that are still held in moderation.
    474498 *
  • src/wp-includes/meta.php

    diff --git src/wp-includes/meta.php src/wp-includes/meta.php
    index 86cc324..9ed3091 100644
    function update_meta_cache($meta_type, $object_ids) { 
    852852}
    853853
    854854/**
     855 * Get the metadata lazyloading queue.
     856 *
     857 * @since 4.5.0
     858 *
     859 * @return WP_Metadata_Lazyloader $lazyloader Metadata lazyloader queue.
     860 */
     861function wp_metadata_lazyloader() {
     862        static $wp_metadata_lazyloader;
     863
     864        if ( null === $wp_metadata_lazyloader ) {
     865                $wp_metadata_lazyloader = new WP_Metadata_Lazyloader();
     866        }
     867
     868        return $wp_metadata_lazyloader;
     869}
     870
     871/**
    855872 * Given a meta query, generates SQL clauses to be appended to a main query.
    856873 *
    857874 * @since 3.2.0
  • src/wp-includes/post.php

    diff --git src/wp-includes/post.php src/wp-includes/post.php
    index 43361d4..3154fa7 100644
    function wp_delete_auto_drafts() { 
    59485948}
    59495949
    59505950/**
     5951 * Queue posts for lazyloading of term meta.
     5952 *
     5953 * @since 4.5.0
     5954 *
     5955 * @param array $posts Array of WP_Post objects.
     5956 */
     5957function wp_queue_posts_for_term_meta_lazyload( $posts ) {
     5958        $post_type_taxonomies = $term_ids = array();
     5959        foreach ( $posts as $post ) {
     5960                if ( ! ( $post instanceof WP_Post ) ) {
     5961                        continue;
     5962                }
     5963
     5964                if ( ! isset( $post_type_taxonomies[ $post->post_type ] ) ) {
     5965                        $post_type_taxonomies[ $post->post_type ] = get_object_taxonomies( $post->post_type );
     5966                }
     5967
     5968                foreach ( $post_type_taxonomies[ $post->post_type ] as $taxonomy ) {
     5969                        // Term cache should already be primed by `update_post_term_cache()`.
     5970                        $terms = get_object_term_cache( $post->ID, $taxonomy );
     5971                        if ( false !== $terms ) {
     5972                                foreach ( $terms as $term ) {
     5973                                        if ( ! isset( $term_ids[ $term->term_id ] ) ) {
     5974                                                $term_ids[] = $term->term_id;
     5975                                        }
     5976                                }
     5977                        }
     5978                }
     5979        }
     5980
     5981        if ( $term_ids ) {
     5982                $lazyloader = wp_metadata_lazyloader();
     5983                $lazyloader->queue_objects( 'term', $term_ids );
     5984        }
     5985}
     5986
     5987/**
    59515988 * Update the custom taxonomies' term counts when a post's status is changed.
    59525989 *
    59535990 * For example, default posts term counts (for custom taxonomies) don't include
  • src/wp-includes/query.php

    diff --git src/wp-includes/query.php src/wp-includes/query.php
    index a8fbbc5..053f4e9 100644
    class WP_Query { 
    36053605                if ( $this->posts )
    36063606                        $this->posts = array_map( 'get_post', $this->posts );
    36073607
    3608 
    3609                 if ( $q['update_post_term_cache'] ) {
    3610                         add_filter( 'get_term_metadata', array( $this, 'lazyload_term_meta' ), 10, 2 );
    3611                 }
    3612 
    36133608                if ( ! $q['suppress_filters'] ) {
    36143609                        /**
    36153610                         * Filter the raw post results array, prior to status checks.
    class WP_Query { 
    37383733
    37393734                // If comments have been fetched as part of the query, make sure comment meta lazy-loading is set up.
    37403735                if ( ! empty( $this->comments ) ) {
    3741                         add_filter( 'get_comment_metadata', array( $this, 'lazyload_comment_meta' ), 10, 2 );
     3736                        wp_queue_comments_for_comment_meta_lazyload( $this->comments );
    37423737                }
    37433738
    37443739                if ( ! $q['suppress_filters'] ) {
    class WP_Query { 
    37703765                        $this->posts = array();
    37713766                }
    37723767
     3768                if ( $q['update_post_term_cache'] ) {
     3769                        wp_queue_posts_for_term_meta_lazyload( $this->posts );
     3770                }
     3771
    37733772                return $this->posts;
    37743773        }
    37753774
    class WP_Query { 
    48344833        }
    48354834
    48364835        /**
    4837          * Lazy-loads termmeta for located posts.
    4838          *
    4839          * As a rule, term queries (`get_terms()` and `wp_get_object_terms()`) prime the metadata cache for matched
    4840          * terms by default. However, this can cause a slight performance penalty, especially when that metadata is
    4841          * not actually used. In the context of a `WP_Query` instance, we're able to avoid this potential penalty.
    4842          * `update_object_term_cache()`, called from `update_post_caches()`, does not 'update_term_meta_cache'.
    4843          * Instead, the first time `get_term_meta()` is called from within a `WP_Query` loop, the current method
    4844          * detects the fact, and then primes the metadata cache for all terms attached to all posts in the loop,
    4845          * with a single database query.
    4846          *
    4847          * This method is public so that it can be used as a filter callback. As a rule, there is no need to invoke it
    4848          * directly, from either inside or outside the `WP_Query` object.
     4836         * Lazyload term meta for posts in the loop.
    48494837         *
    48504838         * @since 4.4.0
    4851          * @access public
     4839         * @deprecated 4.5.0 See wp_queue_posts_for_term_meta_lazyload().
    48524840         *
    4853          * @param mixed $check  The `$check` param passed from the 'get_term_metadata' hook.
    4854          * @param int  $term_id ID of the term whose metadata is being cached.
    4855          * @return mixed In order not to short-circuit `get_metadata()`. Generally, this is `null`, but it could be
    4856          *               another value if filtered by a plugin.
     4841         * @param mixed $check
     4842         * @param int   $term_id
     4843         * @return mixed
    48574844         */
    48584845        public function lazyload_term_meta( $check, $term_id ) {
    4859                 // We can only lazyload if the entire post object is present.
    4860                 $posts = array();
    4861                 foreach ( $this->posts as $post ) {
    4862                         if ( $post instanceof WP_Post ) {
    4863                                 $posts[] = $post;
    4864                         }
    4865                 }
    4866 
    4867                 if ( ! empty( $posts ) ) {
    4868                         // Fetch cached term_ids for each post. Keyed by term_id for faster lookup.
    4869                         $term_ids = array();
    4870                         foreach ( $posts as $post ) {
    4871                                 $taxonomies = get_object_taxonomies( $post->post_type );
    4872                                 foreach ( $taxonomies as $taxonomy ) {
    4873                                         // Term cache should already be primed by 'update_post_term_cache'.
    4874                                         $terms = get_object_term_cache( $post->ID, $taxonomy );
    4875                                         if ( false !== $terms ) {
    4876                                                 foreach ( $terms as $term ) {
    4877                                                         if ( ! isset( $term_ids[ $term->term_id ] ) ) {
    4878                                                                 $term_ids[ $term->term_id ] = 1;
    4879                                                         }
    4880                                                 }
    4881                                         }
    4882                                 }
    4883                         }
    4884 
    4885                         /*
    4886                          * Only update the metadata cache for terms belonging to these posts if the term_id passed
    4887                          * to `get_term_meta()` matches one of those terms. This prevents a single call to
    4888                          * `get_term_meta()` from priming metadata for all `WP_Query` objects.
    4889                          */
    4890                         if ( isset( $term_ids[ $term_id ] ) ) {
    4891                                 update_termmeta_cache( array_keys( $term_ids ) );
    4892                                 remove_filter( 'get_term_metadata', array( $this, 'lazyload_term_meta' ), 10, 2 );
    4893                         }
    4894                 }
    4895 
    4896                 // If no terms were found, there's no need to run this again.
    4897                 if ( empty( $term_ids ) ) {
    4898                         remove_filter( 'get_term_metadata', array( $this, 'lazyload_term_meta' ), 10, 2 );
    4899                 }
    4900 
     4846                _deprecated_function( __METHOD__, '4.5.0' );
    49014847                return $check;
    49024848        }
    49034849
    49044850        /**
    4905          * Lazy-load comment meta when inside of a `WP_Query` loop.
    4906          *
    4907          * This method is public so that it can be used as a filter callback. As a rule, there is no need to invoke it
    4908          * directly, from either inside or outside the `WP_Query` object.
     4851         * Lazyload comment meta for comments in the loop.
    49094852         *
    49104853         * @since 4.4.0
     4854         * @deprecated 4.5.0 See wp_queue_comments_for_comment_meta_lazyload().
    49114855         *
    4912          * @param mixed $check     The `$check` param passed from the 'get_comment_metadata' hook.
    4913          * @param int  $comment_id ID of the comment whose metadata is being cached.
    4914          * @return mixed The original value of `$check`, to not affect 'get_comment_metadata'.
     4856         * @param mixed $check
     4857         * @param int   $comment_id
     4858         * @return mixed
    49154859         */
    49164860        public function lazyload_comment_meta( $check, $comment_id ) {
    4917                 // Don't use `wp_list_pluck()` to avoid by-reference manipulation.
    4918                 $comment_ids = array();
    4919                 if ( is_array( $this->comments ) ) {
    4920                         foreach ( $this->comments as $comment ) {
    4921                                 $comment_ids[] = $comment->comment_ID;
    4922                         }
    4923                 }
    4924 
    4925                 /*
    4926                  * Only update the metadata cache for comments belonging to these posts if the comment_id passed
    4927                  * to `get_comment_meta()` matches one of those comments. This prevents a single call to
    4928                  * `get_comment_meta()` from priming metadata for all `WP_Query` objects.
    4929                  */
    4930                 if ( in_array( $comment_id, $comment_ids ) ) {
    4931                         update_meta_cache( 'comment', $comment_ids );
    4932                         remove_filter( 'get_comment_metadata', array( $this, 'lazyload_comment_meta' ), 10, 2 );
    4933                 } elseif ( empty( $comment_ids ) ) {
    4934                         remove_filter( 'get_comment_metadata', array( $this, 'lazyload_comment_meta' ), 10, 2 );
    4935                 }
    4936 
     4861                _deprecated_function( __METHOD__, '4.5.0' );
    49374862                return $check;
    49384863        }
    49394864}
  • src/wp-settings.php

    diff --git src/wp-settings.php src/wp-settings.php
    index ef1d2cd..3c21597 100644
    require( ABSPATH . WPINC . '/class-wp-roles.php' ); 
    126126require( ABSPATH . WPINC . '/class-wp-role.php' );
    127127require( ABSPATH . WPINC . '/class-wp-user.php' );
    128128require( ABSPATH . WPINC . '/query.php' );
     129require( ABSPATH . WPINC . '/class-wp-metadata-lazyloader.php' );
    129130require( ABSPATH . WPINC . '/date.php' );
    130131require( ABSPATH . WPINC . '/theme.php' );
    131132require( ABSPATH . WPINC . '/class-wp-theme.php' );
  • tests/phpunit/tests/term/meta.php

    diff --git tests/phpunit/tests/term/meta.php tests/phpunit/tests/term/meta.php
    index f6c7b90..1024881 100644
    class Tests_Term_Meta extends WP_UnitTestCase { 
    134134                                // First request will hit the database.
    135135                                $num_queries = $wpdb->num_queries;
    136136                                $this->assertSame( 'bar', get_term_meta( $terms[0], 'foo', true ) );
    137                                 $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     137                                $num_queries++;
     138                                $this->assertSame( $num_queries, $wpdb->num_queries );
    138139
    139140                                // Second and third requests should be in cache.
    140141                                $this->assertSame( 'bar', get_term_meta( $terms[1], 'foo', true ) );
    141142                                $this->assertSame( 'bar', get_term_meta( $terms[2], 'foo', true ) );
    142                                 $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     143                                $this->assertSame( $num_queries, $wpdb->num_queries );
    143144
    144145                                // Querying a term not primed should result in a hit.
     146                                $num_queries++;
    145147                                $this->assertSame( 'bar', get_term_meta( $orphan_term, 'foo', true ) );
    146                                 $this->assertSame( $num_queries + 2, $wpdb->num_queries );
     148                                $this->assertSame( $num_queries, $wpdb->num_queries );
    147149                        }
    148150                }
    149151        }
    150152
    151         /**
    152          * @ticket 34073
    153          */
    154         public function test_term_meta_should_be_lazy_loaded_only_for_the_queries_in_which_the_term_has_posts() {
    155                 global $wpdb;
    156 
    157                 $posts = self::factory()->post->create_many( 3, array( 'post_status' => 'publish' ) );
    158                 register_taxonomy( 'wptests_tax', 'post' );
    159                 $terms = self::factory()->term->create_many( 6, array( 'taxonomy' => 'wptests_tax' ) );
    160 
    161                 wp_set_object_terms( $posts[0], array( $terms[0], $terms[1] ), 'wptests_tax' );
    162                 wp_set_object_terms( $posts[1], array( $terms[2], $terms[3] ), 'wptests_tax' );
    163                 wp_set_object_terms( $posts[2], array( $terms[0], $terms[4], $terms[5] ), 'wptests_tax' );
    164 
    165                 foreach ( $terms as $t ) {
    166                         add_term_meta( $t, 'foo', 'bar' );
    167                 }
    168 
    169                 $q0 = new WP_Query( array( 'p' => $posts[0], 'cache_results' => true ) );
    170                 $q1 = new WP_Query( array( 'p' => $posts[1], 'cache_results' => true ) );
    171                 $q2 = new WP_Query( array( 'p' => $posts[2], 'cache_results' => true ) );
    172 
    173                 /*
    174                  * $terms[0] belongs to both $posts[0] and $posts[2], so `get_term_meta( $terms[0] )` should prime
    175                  * the cache for term matched by $q0 and $q2.
    176                  */
    177 
    178                 // First request will hit the database.
    179                 $num_queries = $wpdb->num_queries;
    180 
    181                 // Prime caches.
    182                 $this->assertSame( 'bar', get_term_meta( $terms[0], 'foo', true ) );
    183 
    184                 // Two queries: one for $q0 and one for $q2.
    185                 $num_queries += 2;
    186                 $this->assertSame( $num_queries, $wpdb->num_queries );
    187 
    188                 // Next requests should be in cache.
    189                 $this->assertSame( 'bar', get_term_meta( $terms[1], 'foo', true ) );
    190                 $this->assertSame( 'bar', get_term_meta( $terms[4], 'foo', true ) );
    191                 $this->assertSame( 'bar', get_term_meta( $terms[5], 'foo', true ) );
    192                 $this->assertSame( $num_queries, $wpdb->num_queries );
    193 
    194                 // Querying for $terms[2] will prime $terms[3] as well.
    195                 $this->assertSame( 'bar', get_term_meta( $terms[2], 'foo', true ) );
    196                 $num_queries++;
    197                 $this->assertSame( $num_queries, $wpdb->num_queries );
    198 
    199                 $this->assertSame( 'bar', get_term_meta( $terms[3], 'foo', true ) );
    200                 $this->assertSame( $num_queries, $wpdb->num_queries );
    201         }
    202 
    203         public function test_adding_term_meta_should_bust_get_terms_cache() {
    204                 $terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) );
    205 
    206                 add_term_meta( $terms[0], 'foo', 'bar' );
    207 
    208                 // Prime cache.
    209                 $found = get_terms( 'wptests_tax', array(
    210                         'hide_empty' => false,
    211                         'fields' => 'ids',
    212                         'meta_query' => array(
    213                                 array(
    214                                         'key' => 'foo',
    215                                         'value' => 'bar',
    216                                 ),
    217                         ),
    218                 ) );
    219 
    220                 $this->assertEqualSets( array( $terms[0] ), $found );
    221 
    222                 add_term_meta( $terms[1], 'foo', 'bar' );
    223 
    224                 $found = get_terms( 'wptests_tax', array(
    225                         'hide_empty' => false,
    226                         'fields' => 'ids',
    227                         'meta_query' => array(
    228                                 array(
    229                                         'key' => 'foo',
    230                                         'value' => 'bar',
    231                                 ),
    232                         ),
    233                 ) );
    234 
    235                 $this->assertEqualSets( array( $terms[0], $terms[1] ), $found );
    236         }
    237 
    238153        public function test_updating_term_meta_should_bust_get_terms_cache() {
    239154                $terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) );
    240155