Changeset 34529
- Timestamp:
- 09/25/2015 03:58:59 AM (9 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/schema.php
r34298 r34529 58 58 59 59 // 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; 69 CREATE TABLE $wpdb->terms ( 61 70 term_id bigint(20) unsigned NOT NULL auto_increment, 62 71 name varchar(200) NOT NULL default '', -
trunk/src/wp-admin/includes/upgrade.php
r34030 r34529 2629 2629 $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" ); 2630 2630 } 2631 2632 // Upgrade versions prior to 4.4. 2633 if ( $wp_current_db_version < 34370 ) { 2634 // If compatible termmeta table is found, use it, but enforce a proper index. 2635 if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->termmeta}'" ) && $wpdb->get_results( "SHOW INDEX FROM {$wpdb->termmeta} WHERE Column_name = 'meta_key'" ) ) { 2636 $wpdb->query( "ALTER TABLE $wpdb->termmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 2637 } 2638 } 2631 2639 } 2632 2640 -
trunk/src/wp-includes/default-filters.php
r34270 r34529 202 202 add_filter( 'title_save_pre', 'trim' ); 203 203 add_filter( 'get_comment_metadata', 'wp_lazyload_comment_meta', 10, 2 ); 204 add_filter( 'get_term_metadata', 'wp_lazyload_term_meta', 10, 2 ); 204 205 205 206 add_filter( 'http_request_host_is_external', 'allowed_http_request_hosts', 10, 2 ); -
trunk/src/wp-includes/taxonomy-functions.php
r34516 r34529 958 958 * @since 4.2.0 Introduced 'name' and 'childless' parameters. 959 959 * @since 4.4.0 Introduced the ability to pass 'term_id' as an alias of 'id' for the `orderby` parameter. 960 * Introduced the 'meta_query' and 'update_term_meta_cache' parameters. 960 961 * 961 962 * @global wpdb $wpdb WordPress database abstraction object. … … 1014 1015 * @type string $cache_domain Unique cache key to be produced when this query is stored in an 1015 1016 * object cache. Default is 'core'. 1017 * @type bool $update_term_meta_cache Whether to prime meta caches for matched terms. Default true. 1018 * @type array $meta_query Meta query clauses to limit retrieved terms by. 1019 * See `WP_Meta_Query`. Default empty. 1016 1020 * } 1017 1021 * @return array|int|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies … … 1037 1041 'number' => '', 'fields' => 'all', 'name' => '', 'slug' => '', 'parent' => '', 'childless' => false, 1038 1042 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'description__like' => '', 1039 'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core' ); 1043 'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core', 1044 'update_term_meta_cache' => true, 'meta_query' => '' ); 1040 1045 $args = wp_parse_args( $args, $defaults ); 1041 1046 $args['number'] = absint( $args['number'] ); … … 1295 1300 $like = '%' . $wpdb->esc_like( $args['search'] ) . '%'; 1296 1301 $where .= $wpdb->prepare( ' AND ((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like ); 1302 } 1303 1304 // Meta query support. 1305 $join = ''; 1306 if ( ! empty( $args['meta_query'] ) ) { 1307 $mquery = new WP_Meta_Query( $args['meta_query'] ); 1308 $mq_sql = $mquery->get_sql( 'term', 't', 'term_id' ); 1309 1310 $join .= $mq_sql['join']; 1311 $where .= $mq_sql['where']; 1297 1312 } 1298 1313 … … 1342 1357 $fields = implode( ', ', apply_filters( 'get_terms_fields', $selects, $args, $taxonomies ) ); 1343 1358 1344 $join = "INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";1359 $join .= " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id"; 1345 1360 1346 1361 $pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits' ); … … 1373 1388 if ( 'all' == $_fields ) { 1374 1389 update_term_cache( $terms ); 1390 } 1391 1392 // Prime termmeta cache. 1393 if ( $args['update_term_meta_cache'] ) { 1394 $term_ids = wp_list_pluck( $terms, 'term_id' ); 1395 update_termmeta_cache( $term_ids ); 1375 1396 } 1376 1397 … … 1456 1477 1457 1478 /** 1479 * Adds metadata to a term. 1480 * 1481 * @since 4.4.0 1482 * 1483 * @param int $term_id Term ID. 1484 * @param string $meta_key Metadata name. 1485 * @param mixed $meta_value Metadata value. 1486 * @param bool $unique Optional. Whether to bail if an entry with the same key is found for the term. 1487 * Default false. 1488 * @return int|bool Meta ID on success, false on failure. 1489 */ 1490 function add_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) { 1491 return add_metadata( 'term', $term_id, $meta_key, $meta_value, $unique ); 1492 } 1493 1494 /** 1495 * Removes metadata matching criteria from a term. 1496 * 1497 * @since 4.4.0 1498 * 1499 * @param int $term_id Term ID. 1500 * @param string $meta_key Metadata name. 1501 * @param mixed $meta_value Optional. Metadata value. If provided, rows will only be removed that match the value. 1502 * @return bool True on success, false on failure. 1503 */ 1504 function delete_term_meta( $term_id, $meta_key, $meta_value = '' ) { 1505 return delete_metadata( 'term', $term_id, $meta_key, $meta_value ); 1506 } 1507 1508 /** 1509 * Retrieves metadata for a term. 1510 * 1511 * @since 4.4.0 1512 * 1513 * @param int $term_id Term ID. 1514 * @param string $key Optional. The meta key to retrieve. If no key is provided, fetches all metadata for the term. 1515 * @param bool $single Whether to return a single value. If false, an array of all values matching the 1516 * `$term_id`/`$key` pair will be returned. Default: false. 1517 * @return mixed If `$single` is false, an array of metadata values. If `$single` is true, a single metadata value. 1518 */ 1519 function get_term_meta( $term_id, $key = '', $single = false ) { 1520 return get_metadata( 'term', $term_id, $key, $single ); 1521 } 1522 1523 /** 1524 * Updates term metadata. 1525 * 1526 * Use the `$prev_value` parameter to differentiate between meta fields with the same key and term ID. 1527 * 1528 * If the meta field for the term does not exist, it will be added. 1529 * 1530 * @since 4.4.0 1531 * 1532 * @param int $term_id Term ID. 1533 * @param string $meta_key Metadata key. 1534 * @param mixed $meta_value Metadata value. 1535 * @param mixed $prev_value Optional. Previous value to check before removing. 1536 * @return int|bool Meta ID if the key didn't previously exist. True on successful update. False on failure. 1537 */ 1538 function update_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) { 1539 return update_metadata( 'term', $term_id, $meta_key, $meta_value, $prev_value ); 1540 } 1541 1542 /** 1543 * Updates metadata cache for list of term IDs. 1544 * 1545 * Performs SQL query to retrieve all metadata for the terms matching `$term_ids` and stores them in the cache. 1546 * Subsequent calls to `get_term_meta()` will not need to query the database. 1547 * 1548 * @since 4.4.0 1549 * 1550 * @param array $term_ids List of term IDs. 1551 * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success. 1552 */ 1553 function update_termmeta_cache( $term_ids ) { 1554 return update_meta_cache( 'term', $term_ids ); 1555 } 1556 1557 /** 1558 * Lazy-loads termmeta when inside of a `WP_Query` loop. 1559 * 1560 * As a rule, term queries (`get_terms()` and `wp_get_object_terms()`) prime the metadata cache for matched terms by 1561 * default. However, this can cause a slight performance penalty, especially when that metadata is not actually used. 1562 * In the context of a `WP_Query` loop, we're able to avoid this potential penalty. `update_object_term_cache()`, 1563 * called from `update_post_caches()`, does not 'update_term_meta_cache'. Instead, the first time `get_term_meta()` is 1564 * called from within a `WP_Query` loop, the current function detects the fact, and then primes the metadata cache for 1565 * all terms attached to all posts in the loop, with a single database query. 1566 * 1567 * @since 4.4.0 1568 * 1569 * @param null $check The `$check` param passed from the 'pre_term_metadata' hook. 1570 * @param int $term_id ID of the term whose metadata is being cached. 1571 * @return null In order not to short-circuit `get_metadata()`. 1572 */ 1573 function wp_lazyload_term_meta( $check, $term_id ) { 1574 global $wp_query; 1575 1576 if ( $wp_query instanceof WP_Query && ! empty( $wp_query->posts ) && $wp_query->get( 'update_post_term_cache' ) ) { 1577 // We can only lazyload if the entire post object is present. 1578 $posts = array(); 1579 foreach ( $wp_query->posts as $post ) { 1580 if ( $post instanceof WP_Post ) { 1581 $posts[] = $post; 1582 } 1583 } 1584 1585 if ( empty( $posts ) ) { 1586 return; 1587 } 1588 1589 // Fetch cached term_ids for each post. Keyed by term_id for faster lookup. 1590 $term_ids = array(); 1591 foreach ( $posts as $post ) { 1592 $taxonomies = get_object_taxonomies( $post->post_type ); 1593 foreach ( $taxonomies as $taxonomy ) { 1594 // No extra queries. Term cache should already be primed by 'update_post_term_cache'. 1595 $terms = get_object_term_cache( $post->ID, $taxonomy ); 1596 if ( false !== $terms ) { 1597 foreach ( $terms as $term ) { 1598 if ( ! isset( $term_ids[ $term->term_id ] ) ) { 1599 $term_ids[ $term->term_id ] = 1; 1600 } 1601 } 1602 } 1603 } 1604 } 1605 1606 if ( $term_ids ) { 1607 update_termmeta_cache( array_keys( $term_ids ) ); 1608 } 1609 } 1610 1611 return $check; 1612 } 1613 1614 /** 1458 1615 * Check if Term exists. 1459 1616 * … … 2012 2169 * @since 4.2.0 Added support for 'taxonomy', 'parent', and 'term_taxonomy_id' values of `$orderby`. 2013 2170 * Introduced `$parent` argument. 2171 * @since 4.4.0 Introduced `$meta_query` and `$update_term_meta_cache` arguments. 2014 2172 * 2015 2173 * @global wpdb $wpdb WordPress database abstraction object. … … 2027 2185 * of strings. 2028 2186 * @type int $parent Optional. Limit results to the direct children of a given term ID. 2187 * @type bool $update_term_meta_cache Whether to prime termmeta cache for matched terms. Only applies when 2188 * `$fields` is 'all', 'all_with_object_id', or 'term_id'. Default true. 2189 * @type array $meta_query Meta query clauses to limit retrieved terms by. See `WP_Meta_Query`. 2190 * Default empty. 2029 2191 * } 2030 2192 * @return array|WP_Error The requested term data or empty array if no terms found. … … 2054 2216 'fields' => 'all', 2055 2217 'parent' => '', 2218 'update_term_meta_cache' => true, 2219 'meta_query' => '', 2056 2220 ); 2057 2221 $args = wp_parse_args( $args, $defaults ); … … 2127 2291 } 2128 2292 2293 // Meta query support. 2294 $meta_query_join = ''; 2295 if ( ! empty( $args['meta_query'] ) ) { 2296 $mquery = new WP_Meta_Query( $args['meta_query'] ); 2297 $mq_sql = $mquery->get_sql( 'term', 't', 'term_id' ); 2298 2299 $meta_query_join .= $mq_sql['join']; 2300 2301 // Strip leading AND. 2302 $where[] = preg_replace( '/^\s*AND/', '', $mq_sql['where'] ); 2303 } 2304 2129 2305 $where = implode( ' AND ', $where ); 2130 2306 2131 $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";2307 $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"; 2132 2308 2133 2309 $objects = false; … … 2152 2328 $terms[$key] = sanitize_term_field( 'term_taxonomy_id', $tt_id, 0, $taxonomy, 'raw' ); // 0 should be the term id, however is not needed when using raw context. 2153 2329 } 2330 } 2331 2332 // Update termmeta cache, if necessary. 2333 if ( $args['update_term_meta_cache'] && ( 'all' === $fields || 'all_with_object_ids' === $fields || 'term_id' === $fields ) ) { 2334 if ( 'term_id' === $fields ) { 2335 $term_ids = $fields; 2336 } else { 2337 $term_ids = wp_list_pluck( $terms, 'term_id' ); 2338 } 2339 2340 update_termmeta_cache( $term_ids ); 2154 2341 } 2155 2342 … … 3289 3476 'fields' => 'all_with_object_id', 3290 3477 'orderby' => 'none', 3478 'update_term_meta_cache' => false, 3291 3479 ) ); 3292 3480 -
trunk/src/wp-includes/version.php
r34030 r34529 12 12 * @global int $wp_db_version 13 13 */ 14 $wp_db_version = 34 030;14 $wp_db_version = 34528; 15 15 16 16 /** -
trunk/src/wp-includes/wp-db.php
r34478 r34529 267 267 */ 268 268 var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta', 269 'terms', 'term_taxonomy', 'term_relationships', ' commentmeta' );269 'terms', 'term_taxonomy', 'term_relationships', 'termmeta', 'commentmeta' ); 270 270 271 271 /** … … 382 382 */ 383 383 public $term_taxonomy; 384 385 /** 386 * WordPress Term Meta table. 387 * 388 * @since 4.4.0 389 * @access public 390 * @var string 391 */ 392 public $termmeta; 384 393 385 394 /* -
trunk/tests/phpunit/tests/term/getTerms.php
r33903 r34529 23 23 24 24 // 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 ) ); 26 26 $this->assertEquals( 3, count( $terms ) ); 27 27 $time1 = wp_cache_get( 'last_changed', 'terms' ); … … 32 32 33 33 // 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 ) ); 35 35 $this->assertEquals( 3, count( $terms ) ); 36 36 $this->assertEquals( $time1, wp_cache_get( 'last_changed', 'terms' ) ); … … 1503 1503 } 1504 1504 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 1505 1583 protected function create_hierarchical_terms_and_posts() { 1506 1584 $terms = array(); -
trunk/tests/phpunit/tests/term/wpGetObjectTerms.php
r31270 r34529 419 419 } 420 420 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 421 501 public function filter_get_object_terms( $terms ) { 422 502 $term_ids = wp_list_pluck( $terms, 'term_id' );
Note: See TracChangeset
for help on using the changeset viewer.