WordPress.org

Make WordPress Core

Ticket #10142: 10142.diff

File 10142.diff, 20.0 KB (added by boonebgorges, 4 years ago)
  • src/wp-admin/includes/schema.php

    diff --git src/wp-admin/includes/schema.php src/wp-admin/includes/schema.php
    index dd36834..d809ec5 100644
    function wp_get_db_schema( $scope = 'all', $blog_id = null ) { 
    5757        $max_index_length = 191;
    5858
    5959        // Blog specific tables.
    60         $blog_tables = "CREATE TABLE $wpdb->terms (
     60        $blog_tables = "CREATE TABLE $wpdb->termmeta (
     61  meta_id bigint(20) unsigned NOT NULL auto_increment,
     62  term_id bigint(20) unsigned NOT NULL default '0',
     63  meta_key varchar(255) default NULL,
     64  meta_value longtext,
     65  PRIMARY KEY  (meta_id),
     66  KEY term_id (term_id),
     67  KEY meta_key (meta_key($max_index_length))
     68) $charset_collate;
     69CREATE TABLE $wpdb->terms (
    6170 term_id bigint(20) unsigned NOT NULL auto_increment,
    6271 name varchar(200) NOT NULL default '',
    6372 slug varchar(200) NOT NULL default '',
  • src/wp-includes/default-filters.php

    diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php
    index e9ddc47..20684e2 100644
    add_filter( 'pingback_ping_source_uri', 'pingback_ping_source_uri' ); 
    201201add_filter( 'xmlrpc_pingback_error',    'xmlrpc_pingback_error'               );
    202202add_filter( 'title_save_pre',           'trim'                                );
    203203add_filter( 'get_comment_metadata',     'wp_lazyload_comment_meta',     10, 2 );
     204add_filter( 'get_term_metadata',        'wp_lazyload_term_meta',        10, 2 );
    204205
    205206add_filter( 'http_request_host_is_external', 'allowed_http_request_hosts', 10, 2 );
    206207
  • src/wp-includes/taxonomy-functions.php

    diff --git src/wp-includes/taxonomy-functions.php src/wp-includes/taxonomy-functions.php
    index 280f440..74dd8a5 100644
    function get_term_to_edit( $id, $taxonomy ) { 
    10031003 *                                           no effect on non-hierarchical taxonomies. Default false.
    10041004 *     @type string       $cache_domain      Unique cache key to be produced when this query is stored in an
    10051005 *                                           object cache. Default is 'core'.
     1006 *     @type bool         $update_term_meta_cache Whether to prime meta caches for matched terms. Default true.
    10061007 * }
    10071008 * @return array|int|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies
    10081009 *                        do not exist.
    function get_terms( $taxonomies, $args = '' ) { 
    10261027                'hide_empty' => true, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(),
    10271028                'number' => '', 'fields' => 'all', 'name' => '', 'slug' => '', 'parent' => '', 'childless' => false,
    10281029                'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'description__like' => '',
    1029                 'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core' );
     1030                'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core',
     1031                'update_term_meta_cache' => true );
    10301032        $args = wp_parse_args( $args, $defaults );
    10311033        $args['number'] = absint( $args['number'] );
    10321034        $args['offset'] = absint( $args['offset'] );
    function get_terms( $taxonomies, $args = '' ) { 
    13641366                update_term_cache( $terms );
    13651367        }
    13661368
     1369        // Prime termmeta cache.
     1370        if ( $args['update_term_meta_cache'] ) {
     1371                $term_ids = wp_list_pluck( $terms, 'term_id' );
     1372                update_termmeta_cache( $term_ids );
     1373        }
     1374
    13671375        if ( empty($terms) ) {
    13681376                wp_cache_add( $cache_key, array(), 'terms', DAY_IN_SECONDS );
    13691377
    function get_terms( $taxonomies, $args = '' ) { 
    14451453}
    14461454
    14471455/**
     1456 * Add meta data field to a comment.
     1457 *
     1458 * @since 4.4.0
     1459 *
     1460 * @param int    $term_id    Term ID.
     1461 * @param string $meta_key   Metadata name.
     1462 * @param mixed  $meta_value Metadata value.
     1463 * @param bool   $unique     Optional, default is false. Whether the same key should not be added.
     1464 * @return int|bool Meta ID on success, false on failure.
     1465 */
     1466function add_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) {
     1467        return add_metadata( 'term', $term_id, $meta_key, $meta_value, $unique );
     1468}
     1469
     1470/**
     1471 * Remove metadata matching criteria from a term.
     1472 *
     1473 * You can match based on the key, or key and value. Removing based on key and
     1474 * value, will keep from removing duplicate metadata with the same key. It also
     1475 * allows removing all metadata matching key, if needed.
     1476 *
     1477 * @since 4.4.0
     1478 *
     1479 * @param int    $term_id    Term ID.
     1480 * @param string $meta_key   Metadata name.
     1481 * @param mixed  $meta_value Optional. Metadata value.
     1482 * @return bool True on success, false on failure.
     1483 */
     1484function delete_term_meta( $term_id, $meta_key, $meta_value = '' ) {
     1485        return delete_metadata( 'term', $term_id, $meta_key, $meta_value );
     1486}
     1487
     1488/**
     1489 * Retrieve meta field for a term.
     1490 *
     1491 * @since 4.4.0
     1492 *
     1493 * @param int    $term_id Term ID.
     1494 * @param string $key     Optional. The meta key to retrieve. By default, returns data for all keys.
     1495 * @param bool   $single  Whether to return a single value.
     1496 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
     1497 *  is true.
     1498 */
     1499function get_term_meta( $term_id, $key = '', $single = false ) {
     1500        return get_metadata( 'term', $term_id, $key, $single );
     1501}
     1502
     1503/**
     1504 * Update term meta field based on term ID.
     1505 *
     1506 * Use the $prev_value parameter to differentiate between meta fields with the
     1507 * same key and term ID.
     1508 *
     1509 * If the meta field for the term does not exist, it will be added.
     1510 *
     1511 * @since 4.4.0
     1512 *
     1513 * @param int    $term_id    Term ID.
     1514 * @param string $meta_key   Metadata key.
     1515 * @param mixed  $meta_value Metadata value.
     1516 * @param mixed  $prev_value Optional. Previous value to check before removing.
     1517 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
     1518 */
     1519function update_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) {
     1520        return update_metadata( 'term', $term_id, $meta_key, $meta_value, $prev_value );
     1521}
     1522
     1523/**
     1524 * Updates metadata cache for list of term IDs.
     1525 *
     1526 * Performs SQL query to retrieve the metadata for the term IDs and updates the
     1527 * metadata cache for the terms. Therefore, the functions, which call this
     1528 * function, do not need to perform SQL queries on their own.
     1529 *
     1530 * @since 4.4.0
     1531 *
     1532 * @param array $term_ids List of post IDs.
     1533 * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success.
     1534 */
     1535function update_termmeta_cache( $term_ids ) {
     1536        return update_meta_cache( 'term', $term_ids );
     1537}
     1538
     1539/**
     1540 * Lazy load termmeta when inside of a `WP_Query` loop.
     1541 *
     1542 * @since 4.4.0
     1543 *
     1544 * @param null $check   The `$check` param passed from the 'pre_term_metadata' hook.
     1545 * @param int  $term_id ID of the term whose metadata is being cached.
     1546 * @return null In order not to short-circuit `get_metadata()`.
     1547 */
     1548function wp_lazyload_term_meta( $check, $term_id ) {
     1549        global $wp_query;
     1550
     1551        if ( $wp_query instanceof WP_Query && ! empty( $wp_query->posts ) && ! empty( $wp_query->get( 'update_post_term_cache' ) ) ) {
     1552                // We can only lazyload if the entire post object is present.
     1553                $posts = array();
     1554                foreach ( $wp_query->posts as $post ) {
     1555                        if ( $post instanceof WP_Post ) {
     1556                                $posts[] = $post;
     1557                        }
     1558                }
     1559
     1560                if ( empty( $posts ) ) {
     1561                        return;
     1562                }
     1563
     1564                // Fetch cached term_ids for each post. Keyed by term_id for faster lookup.
     1565                $term_ids = array();
     1566                foreach ( $posts as $post ) {
     1567                        $taxonomies = get_object_taxonomies( $post->post_type );
     1568                        foreach ( $taxonomies as $taxonomy ) {
     1569                                $terms = get_object_term_cache( $post->ID, $taxonomy );
     1570                                if ( false !== $terms ) {
     1571                                        foreach ( $terms as $term ) {
     1572                                                if ( ! isset( $term_ids[ $term->term_id ] ) ) {
     1573                                                        $term_ids[ $term->term_id ] = 1;
     1574                                                }
     1575                                        }
     1576                                }
     1577                        }
     1578                }
     1579
     1580                if ( $term_ids ) {
     1581                        update_termmeta_cache( array_keys( $term_ids ) );
     1582                }
     1583        }
     1584
     1585        return $check;
     1586}
     1587
     1588/**
    14481589 * Check if Term exists.
    14491590 *
    14501591 * Formerly is_term(), introduced in 2.3.0.
    function wp_delete_category( $cat_ID ) { 
    20162157 *                           term objects being returned, 'ids' will return an array of integers, and 'names' an array
    20172158 *                           of strings.
    20182159 *     @type int    $parent  Optional. Limit results to the direct children of a given term ID.
     2160 *     @type bool   $update_term_meta_cache Whether to prime termmeta cache for matched terms. Only applies when
     2161 *                                          `$fields` is 'all', 'all_with_object_id', or 'term_id'. Default: true.
    20192162 * }
    20202163 * @return array|WP_Error The requested term data or empty array if no terms found.
    20212164 *                        WP_Error if any of the $taxonomies don't exist.
    function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { 
    20432186                'order'   => 'ASC',
    20442187                'fields'  => 'all',
    20452188                'parent'  => '',
     2189                'update_term_meta_cache' => true,
    20462190        );
    20472191        $args = wp_parse_args( $args, $defaults );
    20482192
    function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { 
    21432287                }
    21442288        }
    21452289
     2290        // Update termmeta cache, if necessary.
     2291        if ( $args['update_term_meta_cache'] && ( 'all' === $fields || 'all_with_object_ids' === $fields || 'term_id' === $fields ) ) {
     2292                if ( 'term_id' === $fields ) {
     2293                        $term_ids = $fields;
     2294                } else {
     2295                        $term_ids = wp_list_pluck( $terms, 'term_id' );
     2296                }
     2297
     2298                update_termmeta_cache( $term_ids );
     2299        }
     2300
    21462301        if ( ! $terms ) {
    21472302                $terms = array();
    21482303        } elseif ( $objects && 'all_with_object_id' !== $fields ) {
    function update_object_term_cache($object_ids, $object_type) { 
    32783433        $terms = wp_get_object_terms( $ids, $taxonomies, array(
    32793434                'fields' => 'all_with_object_id',
    32803435                'orderby' => 'none',
     3436                'update_term_meta_cache' => false,
    32813437        ) );
    32823438
    32833439        $object_terms = array();
  • src/wp-includes/wp-db.php

    diff --git src/wp-includes/wp-db.php src/wp-includes/wp-db.php
    index a0c59cf..6ee7eca 100644
    class wpdb { 
    266266         * @var array
    267267         */
    268268        var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
    269                 'terms', 'term_taxonomy', 'term_relationships', 'commentmeta' );
     269                'terms', 'term_taxonomy', 'term_relationships', 'termmeta', 'commentmeta' );
    270270
    271271        /**
    272272         * List of deprecated WordPress tables
    class wpdb { 
    382382         */
    383383        public $term_taxonomy;
    384384
     385        /**
     386         * WordPress Term Meta table.
     387         *
     388         * @since 4.4.0
     389         * @access public
     390         * @var string
     391         */
     392        public $termmeta;
     393
    385394        /*
    386395         * Global and Multisite tables
    387396         */
  • tests/phpunit/tests/term/getTerms.php

    diff --git tests/phpunit/tests/term/getTerms.php tests/phpunit/tests/term/getTerms.php
    index b170648..8eb40e2 100644
    class Tests_Term_getTerms extends WP_UnitTestCase { 
    2222                $num_queries = $wpdb->num_queries;
    2323
    2424                // last_changed and num_queries should bump
    25                 $terms = get_terms( 'post_tag' );
     25                $terms = get_terms( 'post_tag', array( 'update_term_meta_cache' => false ) );
    2626                $this->assertEquals( 3, count( $terms ) );
    2727                $time1 = wp_cache_get( 'last_changed', 'terms' );
    2828                $this->assertNotEmpty( $time1 );
    class Tests_Term_getTerms extends WP_UnitTestCase { 
    3131                $num_queries = $wpdb->num_queries;
    3232
    3333                // Again. last_changed and num_queries should remain the same.
    34                 $terms = get_terms( 'post_tag' );
     34                $terms = get_terms( 'post_tag', array( 'update_term_meta_cache' => false ) );
    3535                $this->assertEquals( 3, count( $terms ) );
    3636                $this->assertEquals( $time1, wp_cache_get( 'last_changed', 'terms' ) );
    3737                $this->assertEquals( $num_queries, $wpdb->num_queries );
    class Tests_Term_getTerms extends WP_UnitTestCase { 
    15021502                }
    15031503        }
    15041504
     1505        /**
     1506         * @ticket 10142
     1507         */
     1508        public function test_termmeta_cache_should_be_primed_by_default() {
     1509                global $wpdb;
     1510
     1511                register_taxonomy( 'wptests_tax', 'post' );
     1512                $terms = $this->factory->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
     1513                add_term_meta( $terms[0], 'foo', 'bar' );
     1514                add_term_meta( $terms[1], 'foo', 'bar' );
     1515                add_term_meta( $terms[2], 'foo', 'bar' );
     1516
     1517                $found = get_terms( 'wptests_tax', array(
     1518                        'hide_empty' => false,
     1519                        'include' => $terms,
     1520                ) );
     1521
     1522                $num_queries = $wpdb->num_queries;
     1523
     1524                foreach ( $terms as $t ) {
     1525                        $this->assertSame( 'bar', get_term_meta( $t, 'foo', true ) );
     1526                }
     1527
     1528                $this->assertSame( $num_queries, $wpdb->num_queries );
     1529        }
     1530
     1531        /**
     1532         * @ticket 10142
     1533         */
     1534        public function test_termmeta_cache_should_not_be_primed_when_update_term_meta_cache_is_false() {
     1535                global $wpdb;
     1536
     1537                register_taxonomy( 'wptests_tax', 'post' );
     1538                $terms = $this->factory->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
     1539                add_term_meta( $terms[0], 'foo', 'bar' );
     1540                add_term_meta( $terms[1], 'foo', 'bar' );
     1541                add_term_meta( $terms[2], 'foo', 'bar' );
     1542
     1543                $found = get_terms( 'wptests_tax', array(
     1544                        'hide_empty' => false,
     1545                        'include' => $terms,
     1546                        'update_term_meta_cache' => false,
     1547                ) );
     1548
     1549                $num_queries = $wpdb->num_queries;
     1550
     1551                foreach ( $terms as $t ) {
     1552                        $this->assertSame( 'bar', get_term_meta( $t, 'foo', true ) );
     1553                }
     1554
     1555                $this->assertSame( $num_queries + 3, $wpdb->num_queries );
     1556        }
     1557
    15051558        protected function create_hierarchical_terms_and_posts() {
    15061559                $terms = array();
    15071560
  • new file tests/phpunit/tests/term/meta.php

    diff --git tests/phpunit/tests/term/meta.php tests/phpunit/tests/term/meta.php
    new file mode 100644
    index 0000000..bdd4b36
    - +  
     1<?php
     2
     3/**
     4 * @group taxonomy
     5 * @group meta
     6 * @ticket 10142
     7 */
     8class Tests_Term_Meta extends WP_UnitTestCase {
     9        public function setUp() {
     10                parent::setUp();
     11                register_taxonomy( 'wptests_tax', 'post' );
     12        }
     13
     14        public function test_add() {
     15                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     16
     17                $this->assertNotEmpty( add_term_meta( $t, 'foo', 'bar' ) );
     18        }
     19
     20        public function test_add_unique() {
     21                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     22
     23                $this->assertNotEmpty( add_term_meta( $t, 'foo', 'bar' ) );
     24                $this->assertFalse( add_term_meta( $t, 'foo', 'bar', true ) );
     25        }
     26
     27        public function test_delete() {
     28                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     29                add_term_meta( $t, 'foo', 'bar' );
     30
     31                $this->assertTrue( delete_term_meta( $t, 'foo' ) );
     32        }
     33
     34        public function test_delete_with_invalid_meta_key_should_return_false() {
     35                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     36
     37                $this->assertFalse( delete_term_meta( $t, 'foo' ) );
     38        }
     39
     40        public function test_delete_should_respect_meta_value() {
     41                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     42                add_term_meta( $t, 'foo', 'bar' );
     43                add_term_meta( $t, 'foo', 'baz' );
     44
     45                $this->assertTrue( delete_term_meta( $t, 'foo', 'bar' ) );
     46
     47                $metas = get_term_meta( $t, 'foo', false );
     48                $this->assertSame( array( 'baz' ), $metas );
     49        }
     50
     51        public function test_get_with_no_key_should_fetch_all_keys() {
     52                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     53                add_term_meta( $t, 'foo', 'bar' );
     54                add_term_meta( $t, 'foo1', 'baz' );
     55
     56                $found = get_term_meta( $t );
     57                $expected = array(
     58                        'foo' => array( 'bar' ),
     59                        'foo1' => array( 'baz' ),
     60                );
     61
     62                $this->assertEqualSets( $expected, $found );
     63        }
     64
     65        public function test_get_with_key_should_fetch_all_for_key() {
     66                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     67                add_term_meta( $t, 'foo', 'bar' );
     68                add_term_meta( $t, 'foo', 'baz' );
     69                add_term_meta( $t, 'foo1', 'baz' );
     70
     71                $found = get_term_meta( $t, 'foo' );
     72                $expected = array( 'bar', 'baz' );
     73
     74                $this->assertEqualSets( $expected, $found );
     75        }
     76
     77        public function test_get_should_respect_single_true() {
     78                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     79                add_term_meta( $t, 'foo', 'bar' );
     80                add_term_meta( $t, 'foo', 'baz' );
     81
     82                $found = get_term_meta( $t, 'foo', true );
     83                $this->assertEquals( 'bar', $found );
     84        }
     85
     86        public function test_update_should_pass_to_add_when_no_value_exists_for_key() {
     87                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     88
     89                $actual = update_term_meta( $t, 'foo', 'bar' );
     90                $this->assertInternalType( 'int', $actual );
     91                $this->assertNotEmpty( $actual );
     92
     93                $meta = get_term_meta( $t, 'foo', true );
     94                $this->assertSame( 'bar', $meta );
     95        }
     96
     97        public function test_update_should_return_true_when_updating_existing_value_for_key() {
     98                $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     99
     100                add_term_meta( $t, 'foo', 'bar' );
     101
     102                $actual = update_term_meta( $t, 'foo', 'baz' );
     103                $this->assertTrue( $actual );
     104
     105                $meta = get_term_meta( $t, 'foo', true );
     106                $this->assertSame( 'baz', $meta );
     107        }
     108
     109        public function test_term_meta_should_be_lazy_loaded_for_all_terms_in_wp_query_loop() {
     110                global $wpdb;
     111
     112                $p = $this->factory->post->create( array( 'post_status' => 'publish' ) );
     113
     114                register_taxonomy( 'wptests_tax', 'post' );
     115                $terms = $this->factory->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
     116                wp_set_object_terms( $p, $terms, 'wptests_tax' );
     117                foreach ( $terms as $t ) {
     118                        add_term_meta( $t, 'foo', 'bar' );
     119                }
     120
     121                // Create another term, which should *not* be lazy loaded because it's unattached.
     122                $orphan_term = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     123                add_term_meta( $orphan_term, 'foo', 'bar' );
     124
     125                $this->go_to( get_permalink( $p ) );
     126
     127                if ( have_posts() ) {
     128                        while ( have_posts() ) {
     129                                the_post();
     130
     131                                // First request will hit the database.
     132                                $num_queries = $wpdb->num_queries;
     133                                $this->assertSame( 'bar', get_term_meta( $terms[0], 'foo', true ) );
     134                                $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     135
     136                                // Second and third requests should be in cache.
     137                                $this->assertSame( 'bar', get_term_meta( $terms[1], 'foo', true ) );
     138                                $this->assertSame( 'bar', get_term_meta( $terms[2], 'foo', true ) );
     139                                $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     140
     141                                // Querying a term not primed should result in a hit.
     142                                $this->assertSame( 'bar', get_term_meta( $orphan_term, 'foo', true ) );
     143                                $this->assertSame( $num_queries + 2, $wpdb->num_queries );
     144                        }
     145                }
     146        }
     147}
  • tests/phpunit/tests/term/wpGetObjectTerms.php

    diff --git tests/phpunit/tests/term/wpGetObjectTerms.php tests/phpunit/tests/term/wpGetObjectTerms.php
    index 75d40bb..5843fc2 100644
    class Tests_Term_WpGetObjectTerms extends WP_UnitTestCase { 
    418418                $this->assertEqualSets( array( $t1, $t2 ), $found );
    419419        }
    420420
     421        /**
     422         * @ticket 10142
     423         */
     424        public function test_termmeta_cache_should_be_primed_by_default() {
     425                global $wpdb;
     426
     427                register_taxonomy( 'wptests_tax', 'post' );
     428                $terms = $this->factory->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
     429                add_term_meta( $terms[0], 'foo', 'bar' );
     430                add_term_meta( $terms[1], 'foo', 'bar' );
     431                add_term_meta( $terms[2], 'foo', 'bar' );
     432
     433                $p = $this->factory->post->create();
     434                wp_set_object_terms( $p, $terms, 'wptests_tax' );
     435
     436                $found = wp_get_object_terms( $p, 'wptests_tax' );
     437
     438                $num_queries = $wpdb->num_queries;
     439
     440                foreach ( $terms as $t ) {
     441                        $this->assertSame( 'bar', get_term_meta( $t, 'foo', true ) );
     442                }
     443
     444                $this->assertSame( $num_queries, $wpdb->num_queries );
     445        }
     446
     447        /**
     448         * @ticket 10142
     449         */
     450        public function test_termmeta_cache_should_not_be_primed_when_update_term_meta_cache_is_false() {
     451                global $wpdb;
     452
     453                register_taxonomy( 'wptests_tax', 'post' );
     454                $terms = $this->factory->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
     455                add_term_meta( $terms[0], 'foo', 'bar' );
     456                add_term_meta( $terms[1], 'foo', 'bar' );
     457                add_term_meta( $terms[2], 'foo', 'bar' );
     458
     459                $p = $this->factory->post->create();
     460                wp_set_object_terms( $p, $terms, 'wptests_tax' );
     461
     462                $found = wp_get_object_terms( $p, 'wptests_tax', array(
     463                        'update_term_meta_cache' => false,
     464                ) );
     465
     466                $num_queries = $wpdb->num_queries;
     467
     468                foreach ( $terms as $t ) {
     469                        $this->assertSame( 'bar', get_term_meta( $t, 'foo', true ) );
     470                }
     471
     472                $this->assertSame( $num_queries + 3, $wpdb->num_queries );
     473        }
     474
    421475        public function filter_get_object_terms( $terms ) {
    422476                $term_ids = wp_list_pluck( $terms, 'term_id' );
    423477                // all terms should still be objects