WordPress.org

Make WordPress Core

Ticket #10142: 10142.2.diff

File 10142.2.diff, 25.6 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-admin/includes/upgrade.php

    diff --git src/wp-admin/includes/upgrade.php src/wp-admin/includes/upgrade.php
    index 967cfe3..0cbca06 100644
    function pre_schema_upgrade() { 
    26282628                $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
    26292629                $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" );
    26302630        }
     2631
     2632        if ( $wp_current_db_version < 34370 ) {
     2633                if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->termmeta}'" ) ) {
     2634                        $wpdb->query( "ALTER TABLE $wpdb->termmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
     2635                }
     2636        }
    26312637}
    26322638
    26332639/**
  • 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 1ab178e..9d40f17 100644
    function get_term_to_edit( $id, $taxonomy ) { 
    948948 * @since 2.3.0
    949949 * @since 4.2.0 Introduced 'name' and 'childless' parameters.
    950950 * @since 4.4.0 Introduced the ability to pass 'term_id' as an alias of 'id' for the `orderby` parameter.
     951 *              Introduced the 'meta_query' and 'update_term_meta_cache' parameters.
    951952 *
    952953 * @global wpdb  $wpdb WordPress database abstraction object.
    953954 * @global array $wp_filter
    function get_term_to_edit( $id, $taxonomy ) { 
    10041005 *                                           no effect on non-hierarchical taxonomies. Default false.
    10051006 *     @type string       $cache_domain      Unique cache key to be produced when this query is stored in an
    10061007 *                                           object cache. Default is 'core'.
     1008 *     @type bool         $update_term_meta_cache Whether to prime meta caches for matched terms. Default true.
     1009 *     @type array        $meta_query             Meta query clauses to limit retrieved comments by.
     1010 *                                                See `WP_Meta_Query`. Default empty.
    10071011 * }
    10081012 * @return array|int|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies
    10091013 *                        do not exist.
    function get_terms( $taxonomies, $args = '' ) { 
    10271031                'hide_empty' => true, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(),
    10281032                'number' => '', 'fields' => 'all', 'name' => '', 'slug' => '', 'parent' => '', 'childless' => false,
    10291033                'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'description__like' => '',
    1030                 'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core' );
     1034                'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core',
     1035                'update_term_meta_cache' => true, 'meta_query' => '' );
    10311036        $args = wp_parse_args( $args, $defaults );
    10321037        $args['number'] = absint( $args['number'] );
    10331038        $args['offset'] = absint( $args['offset'] );
    function get_terms( $taxonomies, $args = '' ) { 
    12871292                $where .= $wpdb->prepare( ' AND ((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like );
    12881293        }
    12891294
     1295        // Meta query support.
     1296        $join = '';
     1297        if ( ! empty( $args['meta_query'] ) ) {
     1298                $mquery = new WP_Meta_Query( $args['meta_query'] );
     1299                $mq_sql = $mquery->get_sql( 'term', 't', 'term_id' );
     1300
     1301                $join  .= $mq_sql['join'];
     1302                $where .= $mq_sql['where'];
     1303        }
     1304
    12901305        $selects = array();
    12911306        switch ( $args['fields'] ) {
    12921307                case 'all':
    function get_terms( $taxonomies, $args = '' ) { 
    13321347         */
    13331348        $fields = implode( ', ', apply_filters( 'get_terms_fields', $selects, $args, $taxonomies ) );
    13341349
    1335         $join = "INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
     1350        $join .= " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
    13361351
    13371352        $pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits' );
    13381353
    function get_terms( $taxonomies, $args = '' ) { 
    13651380                update_term_cache( $terms );
    13661381        }
    13671382
     1383        // Prime termmeta cache.
     1384        if ( $args['update_term_meta_cache'] ) {
     1385                $term_ids = wp_list_pluck( $terms, 'term_id' );
     1386                update_termmeta_cache( $term_ids );
     1387        }
     1388
    13681389        if ( empty($terms) ) {
    13691390                wp_cache_add( $cache_key, array(), 'terms', DAY_IN_SECONDS );
    13701391
    function get_terms( $taxonomies, $args = '' ) { 
    14461467}
    14471468
    14481469/**
     1470 * Add meta data field to a comment.
     1471 *
     1472 * @since 4.4.0
     1473 *
     1474 * @param int    $term_id    Term ID.
     1475 * @param string $meta_key   Metadata name.
     1476 * @param mixed  $meta_value Metadata value.
     1477 * @param bool   $unique     Optional, default is false. Whether the same key should not be added.
     1478 * @return int|bool Meta ID on success, false on failure.
     1479 */
     1480function add_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) {
     1481        return add_metadata( 'term', $term_id, $meta_key, $meta_value, $unique );
     1482}
     1483
     1484/**
     1485 * Remove metadata matching criteria from a term.
     1486 *
     1487 * You can match based on the key, or key and value. Removing based on key and
     1488 * value, will keep from removing duplicate metadata with the same key. It also
     1489 * allows removing all metadata matching key, if needed.
     1490 *
     1491 * @since 4.4.0
     1492 *
     1493 * @param int    $term_id    Term ID.
     1494 * @param string $meta_key   Metadata name.
     1495 * @param mixed  $meta_value Optional. Metadata value.
     1496 * @return bool True on success, false on failure.
     1497 */
     1498function delete_term_meta( $term_id, $meta_key, $meta_value = '' ) {
     1499        return delete_metadata( 'term', $term_id, $meta_key, $meta_value );
     1500}
     1501
     1502/**
     1503 * Retrieve meta field for a term.
     1504 *
     1505 * @since 4.4.0
     1506 *
     1507 * @param int    $term_id Term ID.
     1508 * @param string $key     Optional. The meta key to retrieve. By default, returns data for all keys.
     1509 * @param bool   $single  Whether to return a single value.
     1510 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
     1511 *  is true.
     1512 */
     1513function get_term_meta( $term_id, $key = '', $single = false ) {
     1514        return get_metadata( 'term', $term_id, $key, $single );
     1515}
     1516
     1517/**
     1518 * Update term meta field based on term ID.
     1519 *
     1520 * Use the $prev_value parameter to differentiate between meta fields with the
     1521 * same key and term ID.
     1522 *
     1523 * If the meta field for the term does not exist, it will be added.
     1524 *
     1525 * @since 4.4.0
     1526 *
     1527 * @param int    $term_id    Term ID.
     1528 * @param string $meta_key   Metadata key.
     1529 * @param mixed  $meta_value Metadata value.
     1530 * @param mixed  $prev_value Optional. Previous value to check before removing.
     1531 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
     1532 */
     1533function update_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) {
     1534        return update_metadata( 'term', $term_id, $meta_key, $meta_value, $prev_value );
     1535}
     1536
     1537/**
     1538 * Updates metadata cache for list of term IDs.
     1539 *
     1540 * Performs SQL query to retrieve the metadata for the term IDs and updates the
     1541 * metadata cache for the terms. Therefore, the functions, which call this
     1542 * function, do not need to perform SQL queries on their own.
     1543 *
     1544 * @since 4.4.0
     1545 *
     1546 * @param array $term_ids List of post IDs.
     1547 * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success.
     1548 */
     1549function update_termmeta_cache( $term_ids ) {
     1550        return update_meta_cache( 'term', $term_ids );
     1551}
     1552
     1553/**
     1554 * Lazy load termmeta when inside of a `WP_Query` loop.
     1555 *
     1556 * @since 4.4.0
     1557 *
     1558 * @param null $check   The `$check` param passed from the 'pre_term_metadata' hook.
     1559 * @param int  $term_id ID of the term whose metadata is being cached.
     1560 * @return null In order not to short-circuit `get_metadata()`.
     1561 */
     1562function wp_lazyload_term_meta( $check, $term_id ) {
     1563        global $wp_query;
     1564
     1565        if ( $wp_query instanceof WP_Query && ! empty( $wp_query->posts ) && ! empty( $wp_query->get( 'update_post_term_cache' ) ) ) {
     1566                // We can only lazyload if the entire post object is present.
     1567                $posts = array();
     1568                foreach ( $wp_query->posts as $post ) {
     1569                        if ( $post instanceof WP_Post ) {
     1570                                $posts[] = $post;
     1571                        }
     1572                }
     1573
     1574                if ( empty( $posts ) ) {
     1575                        return;
     1576                }
     1577
     1578                // Fetch cached term_ids for each post. Keyed by term_id for faster lookup.
     1579                $term_ids = array();
     1580                foreach ( $posts as $post ) {
     1581                        $taxonomies = get_object_taxonomies( $post->post_type );
     1582                        foreach ( $taxonomies as $taxonomy ) {
     1583                                $terms = get_object_term_cache( $post->ID, $taxonomy );
     1584                                if ( false !== $terms ) {
     1585                                        foreach ( $terms as $term ) {
     1586                                                if ( ! isset( $term_ids[ $term->term_id ] ) ) {
     1587                                                        $term_ids[ $term->term_id ] = 1;
     1588                                                }
     1589                                        }
     1590                                }
     1591                        }
     1592                }
     1593
     1594                if ( $term_ids ) {
     1595                        update_termmeta_cache( array_keys( $term_ids ) );
     1596                }
     1597        }
     1598
     1599        return $check;
     1600}
     1601
     1602/**
    14491603 * Check if Term exists.
    14501604 *
    14511605 * Formerly is_term(), introduced in 2.3.0.
    function wp_delete_category( $cat_ID ) { 
    20022156 * @since 2.3.0
    20032157 * @since 4.2.0 Added support for 'taxonomy', 'parent', and 'term_taxonomy_id' values of `$orderby`.
    20042158 *              Introduced `$parent` argument.
     2159 * @since 4.4.0 Introduced `$meta_query` and `$update_term_meta_cache` arguments.
    20052160 *
    20062161 * @global wpdb $wpdb WordPress database abstraction object.
    20072162 *
    function wp_delete_category( $cat_ID ) { 
    20172172 *                           term objects being returned, 'ids' will return an array of integers, and 'names' an array
    20182173 *                           of strings.
    20192174 *     @type int    $parent  Optional. Limit results to the direct children of a given term ID.
     2175 *     @type bool   $update_term_meta_cache Whether to prime termmeta cache for matched terms. Only applies when
     2176 *                                          `$fields` is 'all', 'all_with_object_id', or 'term_id'. Default: true.
     2177 *     @type array  $meta_query             Meta query clauses to limit retrieved comments by.
     2178 *                                          See `WP_Meta_Query`. Default empty.
    20202179 * }
    20212180 * @return array|WP_Error The requested term data or empty array if no terms found.
    20222181 *                        WP_Error if any of the $taxonomies don't exist.
    function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { 
    20442203                'order'   => 'ASC',
    20452204                'fields'  => 'all',
    20462205                'parent'  => '',
     2206                'update_term_meta_cache' => true,
     2207                'meta_query' => '',
    20472208        );
    20482209        $args = wp_parse_args( $args, $defaults );
    20492210
    function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { 
    21172278                $where[] = $wpdb->prepare( 'tt.parent = %d', $args['parent'] );
    21182279        }
    21192280
     2281        // Meta query support.
     2282        $meta_query_join = '';
     2283        if ( ! empty( $args['meta_query'] ) ) {
     2284                $mquery = new WP_Meta_Query( $args['meta_query'] );
     2285                $mq_sql = $mquery->get_sql( 'term', 't', 'term_id' );
     2286
     2287                $meta_query_join .= $mq_sql['join'];
     2288
     2289                // Strip leading AND.
     2290                $where[] = preg_replace( '/^\s*AND/', '', $mq_sql['where'] );
     2291        }
     2292
    21202293        $where = implode( ' AND ', $where );
    21212294
    2122         $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE $where $orderby $order";
     2295        $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id $meta_query_join WHERE $where $orderby $order";
    21232296
    21242297        $objects = false;
    21252298        if ( 'all' == $fields || 'all_with_object_id' == $fields ) {
    function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { 
    21442317                }
    21452318        }
    21462319
     2320        // Update termmeta cache, if necessary.
     2321        if ( $args['update_term_meta_cache'] && ( 'all' === $fields || 'all_with_object_ids' === $fields || 'term_id' === $fields ) ) {
     2322                if ( 'term_id' === $fields ) {
     2323                        $term_ids = $fields;
     2324                } else {
     2325                        $term_ids = wp_list_pluck( $terms, 'term_id' );
     2326                }
     2327
     2328                update_termmeta_cache( $term_ids );
     2329        }
     2330
    21472331        if ( ! $terms ) {
    21482332                $terms = array();
    21492333        } elseif ( $objects && 'all_with_object_id' !== $fields ) {
    function update_object_term_cache($object_ids, $object_type) { 
    32793463        $terms = wp_get_object_terms( $ids, $taxonomies, array(
    32803464                'fields' => 'all_with_object_id',
    32813465                'orderby' => 'none',
     3466                'update_term_meta_cache' => false,
    32823467        ) );
    32833468
    32843469        $object_terms = array();
  • src/wp-includes/version.php

    diff --git src/wp-includes/version.php src/wp-includes/version.php
    index a5bf92c..3d43523 100644
    $wp_version = '4.4-alpha-33636-src'; 
    1111 *
    1212 * @global int $wp_db_version
    1313 */
    14 $wp_db_version = 34030;
     14$wp_db_version = 34370;
    1515
    1616/**
    1717 * Holds the TinyMCE version
  • src/wp-includes/wp-db.php

    diff --git src/wp-includes/wp-db.php src/wp-includes/wp-db.php
    index c745cb2..5be4481 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..f1db1aa 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
     1558        /**
     1559         * @ticket 10142
     1560         */
     1561        public function test_meta_query() {
     1562                register_taxonomy( 'wptests_tax', 'post' );
     1563                $terms = $this->factory->term->create_many( 5, array( 'taxonomy' => 'wptests_tax' ) );
     1564                add_term_meta( $terms[0], 'foo', 'bar' );
     1565                add_term_meta( $terms[1], 'foo', 'bar' );
     1566                add_term_meta( $terms[2], 'foo', 'baz' );
     1567                add_term_meta( $terms[3], 'foob', 'ar' );
     1568
     1569                $found = get_terms( 'wptests_tax', array(
     1570                        'hide_empty' => false,
     1571                        'meta_query' => array(
     1572                                array(
     1573                                        'key' => 'foo',
     1574                                        'value' => 'bar',
     1575                                ),
     1576                        ),
     1577                        'fields' => 'ids',
     1578                ) );
     1579
     1580                $this->assertEqualSets( array( $terms[0], $terms[1] ), $found );
     1581        }
     1582
    15051583        protected function create_hierarchical_terms_and_posts() {
    15061584                $terms = array();
    15071585
  • 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..18ef61c 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
     475        /**
     476         * @ticket 10142
     477         */
     478        public function test_meta_query() {
     479                register_taxonomy( 'wptests_tax', 'post' );
     480                $terms = $this->factory->term->create_many( 5, array( 'taxonomy' => 'wptests_tax' ) );
     481                add_term_meta( $terms[0], 'foo', 'bar' );
     482                add_term_meta( $terms[1], 'foo', 'bar' );
     483                add_term_meta( $terms[2], 'foo', 'baz' );
     484                add_term_meta( $terms[3], 'foob', 'ar' );
     485
     486                $p = $this->factory->post->create();
     487                wp_set_object_terms( $p, $terms, 'wptests_tax' );
     488
     489                $found = wp_get_object_terms( $p, 'wptests_tax', array(
     490                        'meta_query' => array(
     491                                array(
     492                                        'key' => 'foo',
     493                                        'value' => 'bar',
     494                                ),
     495                        ),
     496                ) );
     497
     498                $this->assertEqualSets( array( $terms[0], $terms[1] ), wp_list_pluck( $found, 'term_id' ) );
     499        }
     500
    421501        public function filter_get_object_terms( $terms ) {
    422502                $term_ids = wp_list_pluck( $terms, 'term_id' );
    423503                // all terms should still be objects