Ticket #14162: 14162.2.diff
File 14162.2.diff, 18.5 KB (added by , 9 years ago) |
---|
-
src/wp-includes/category-functions.php
319 319 * pass to it. This is one of the features with using pass by reference in PHP. 320 320 * 321 321 * @since 2.3.0 322 * @since 4.4.0 The `$category` parameter now also accepts a WP_Term object. 322 323 * @access private 323 324 * 324 * @param array|object $category Category Row object or array325 * @param array|object|WP_Term $category Category Row object or array 325 326 */ 326 327 function _make_cat_compat( &$category ) { 327 328 if ( is_object( $category ) && ! is_wp_error( $category ) ) { 328 $category->cat_ID = &$category->term_id;329 $category->category_count = &$category->count;330 $category->category_description = &$category->description;331 $category->cat_name = &$category->name;332 $category->category_nicename = &$category->slug;333 $category->category_parent = &$category->parent;329 $category->cat_ID = $category->term_id; 330 $category->category_count = $category->count; 331 $category->category_description = $category->description; 332 $category->cat_name = $category->name; 333 $category->category_nicename = $category->slug; 334 $category->category_parent = $category->parent; 334 335 } elseif ( is_array( $category ) && isset( $category['term_id'] ) ) { 335 336 $category['cat_ID'] = &$category['term_id']; 336 337 $category['category_count'] = &$category['count']; -
src/wp-includes/class-wp-term.php
1 <?php 2 /** 3 * Taxonomy API: WP_Term class 4 * 5 * @package WordPress 6 * @subpackage Taxonomy 7 * @since 4.4.0 8 */ 9 10 /** 11 * Core class used to implement the WP_Term object. 12 * 13 * @since 4.4.0 14 */ 15 final class WP_Term { 16 17 /** 18 * Term ID. 19 * 20 * @since 4.4.0 21 * @access public 22 * @var int 23 */ 24 public $term_id; 25 26 /** 27 * The term's name. 28 * 29 * @since 4.4.0 30 * @access public 31 * @var string 32 */ 33 public $name = ''; 34 35 /** 36 * The term's slug. 37 * 38 * @since 4.4.0 39 * @access public 40 * @var string 41 */ 42 public $slug = ''; 43 44 /** 45 * The term's term_group. 46 * 47 * @since 4.4.0 48 * @access public 49 * @var string 50 */ 51 public $term_group = ''; 52 53 /** 54 * Term Taxonomy ID. 55 * 56 * @since 4.4.0 57 * @access public 58 * @var int 59 */ 60 public $term_taxonomy_id = 0; 61 62 /** 63 * The term's taxonomy name. 64 * 65 * @since 4.4.0 66 * @access public 67 * @var string 68 */ 69 public $taxonomy = ''; 70 71 /** 72 * The term's description. 73 * 74 * @since 4.4.0 75 * @access public 76 * @var string 77 */ 78 public $description = ''; 79 80 /** 81 * ID of a term's parent term. 82 * 83 * @since 4.4.0 84 * @access public 85 * @var int 86 */ 87 public $parent = 0; 88 89 /** 90 * Cached object count for this term. 91 * 92 * @since 4.4.0 93 * @access public 94 * @var int 95 */ 96 public $count = 0; 97 98 /** 99 * Stores the term object's sanitization level. 100 * 101 * Does not correspond to a database field. 102 * 103 * @since 4.4.0 104 * @access public 105 * @var string 106 */ 107 public $filter = 'raw'; 108 109 /** 110 * Retrieve WP_Term instance. 111 * 112 * @since 4.4.0 113 * @access public 114 * @static 115 * 116 * @global wpdb $wpdb WordPress database abstraction object. 117 * 118 * @param int $term_id Term ID. 119 * @return WP_Term|false Term object, false otherwise. 120 */ 121 public static function get_instance( $term_id ) { 122 global $wpdb; 123 124 $term_id = (int) $term_id; 125 if ( ! $term_id ) { 126 return false; 127 } 128 129 $_term = wp_cache_get( $term_id, 'terms' ); 130 131 // If there isn't a cached version, hit the database. 132 if ( ! $_term ) { 133 $_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.term_id = %d LIMIT 1", $term_id ) ); 134 if ( ! $_term ) { 135 return false; 136 } 137 138 $_term = sanitize_term( $_term, $_term->taxonomy, 'raw' ); 139 wp_cache_add( $term_id, $_term, 'terms' ); 140 } elseif ( empty( $_term->filter ) ) { 141 $_term = sanitize_term( $_term, $_term->taxonomy, 'raw' ); 142 } 143 144 return new WP_Term( $_term ); 145 } 146 147 /** 148 * Constructor. 149 * 150 * @since 4.4.0 151 * @access public 152 * 153 * @param WP_Term|object $term Term object. 154 */ 155 public function __construct( $term ) { 156 foreach ( get_object_vars( $term ) as $key => $value ) { 157 $this->$key = $value; 158 } 159 } 160 161 /** 162 * Sanitizes term fields, according to the filter type provided. 163 * 164 * @since 4.4.0 165 * @access public 166 * 167 * @param string $filter Filter context. Accepts 'edit', 'db', 'display', 'attribute', 'js', 'raw'. 168 * @return WP_Term Sanitized WP_Term instance. 169 */ 170 public function filter( $filter ) { 171 if ( isset( $this->filter ) && $this->filter === $filter ) { 172 return $this; 173 } 174 175 return sanitize_term( $this, $this->taxonomy, $filter ); 176 } 177 178 /** 179 * Converts an object to array. 180 * 181 * @since 4.4.0 182 * @access public 183 * 184 * @return array Object as array. 185 */ 186 public function to_array() { 187 return get_object_vars( $this ); 188 } 189 } -
src/wp-includes/taxonomy-functions.php
708 708 * @todo Better formatting for DocBlock 709 709 * 710 710 * @since 2.3.0 711 * @since 4.4.0 Converted to return a WP_Term object if `$output` is `OBJECT`. 711 712 * 712 713 * @global wpdb $wpdb WordPress database abstraction object. 713 714 * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. 714 715 * 715 * @param int|object $term If integer, will get from database. If object will apply filters and return $term. 716 * @param int|WP_Term|object $term If integer, term data will be fetched from the database, or from the cache if 717 * available. If stdClass object (as in the results of a database query), will apply 718 * filters and return a `WP_Term` object corresponding to the `$term` data. If `WP_Term`, 719 * will return `$term`. 716 720 * @param string $taxonomy Taxonomy name that $term is part of. 717 721 * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N 718 722 * @param string $filter Optional, default is raw or no WordPress defined filter will applied. 719 * @return object|array|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not720 * exist then WP_Error will be returned.723 * @return mixed Type corresponding to `$output` on success or null on failure. When `$output` is `OBJECT`, 724 * a WP_Term instance is returned. If taxonomy does not exist then WP_Error will be returned. 721 725 */ 722 function get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { 723 global $wpdb; 724 726 function get_term( $term, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) { 725 727 if ( empty( $term ) ) { 726 728 return new WP_Error( 'invalid_term', __( 'Empty Term' ) ); 727 729 } 728 730 729 if ( ! taxonomy_exists( $taxonomy ) ) {731 if ( $taxonomy && ! taxonomy_exists( $taxonomy ) ) { 730 732 return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy' ) ); 731 733 } 732 734 733 if ( is_object($term) && empty($term->filter) ) { 734 wp_cache_add( $term->term_id, $term, $taxonomy ); 735 if ( $term instanceof WP_Term ) { 735 736 $_term = $term; 737 } elseif ( is_object( $term ) ) { 738 if ( empty( $term->filter ) ) { 739 $_term = sanitize_term( $term, $taxonomy, 'raw' ); 740 $_term = new WP_Term( $_term ); 741 } elseif ( 'raw' == $term->filter ) { 742 $_term = new WP_Term( $term ); 743 } else { 744 $_term = WP_Term::get_instance( $term->term_id ); 745 } 736 746 } else { 737 if ( is_object($term) ) 738 $term = $term->term_id; 739 if ( !$term = (int) $term ) 740 return null; 741 if ( ! $_term = wp_cache_get( $term, $taxonomy ) ) { 742 $_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND t.term_id = %d LIMIT 1", $taxonomy, $term) ); 743 if ( ! $_term ) 744 return null; 745 wp_cache_add( $term, $_term, $taxonomy ); 747 $_term = WP_Term::get_instance( $term ); 748 } 749 750 // If a taxonomy was passed, make sure it matches the taxonomy of the located term. 751 if ( $_term && $taxonomy && $taxonomy !== $_term->taxonomy ) { 752 // If there are two terms with the same ID, split the other one to a new term. 753 $new_term_id = _split_shared_term( $_term->term_id, $_term->term_taxonomy_id ); 754 755 // If no split occurred, this is an invalid request. 756 if ( $new_term_id === $_term->term_id ) { 757 return new WP_Error( 'invalid_term', __( 'Empty Term' ) ); 758 } else { 759 // Refetch the term, now that it's no longer shared. 760 return get_term( $_term->term_id, $taxonomy, $output, $filter ); 746 761 } 747 762 } 748 763 764 if ( ! $_term ) { 765 return null; 766 } 767 749 768 /** 750 769 * Filter a term. 751 770 * 752 771 * @since 2.3.0 772 * @since 4.4.0 `$_term` can now also be a WP_Term object. 753 773 * 754 * @param int|object $_term Term object or ID.755 * @param string $taxonomy The taxonomy slug.774 * @param int|object|WP_Term $_term Term object or ID. 775 * @param string $taxonomy The taxonomy slug. 756 776 */ 757 777 $_term = apply_filters( 'get_term', $_term, $taxonomy ); 758 778 … … 763 783 * to the taxonomy slug. 764 784 * 765 785 * @since 2.3.0 786 * @since 4.4.0 `$_term` can now also be a WP_Term object. 766 787 * 767 * @param int|object $_term Term object or ID.768 * @param string $taxonomy The taxonomy slug.788 * @param int|object|WP_Term $_term Term object or ID. 789 * @param string $taxonomy The taxonomy slug. 769 790 */ 770 791 $_term = apply_filters( "get_$taxonomy", $_term, $taxonomy ); 771 $_term = sanitize_term($_term, $taxonomy, $filter);772 792 773 if ( $output == OBJECT ) {774 return $_term;775 } elseif ( $output == ARRAY_A ) { 776 $__term = get_object_vars($_term);777 return $_ _term;793 // Sanitize term, according to the specified filter. 794 $_term = $_term->filter( $filter ); 795 796 if ( $output == ARRAY_A ) { 797 return $_term->to_array(); 778 798 } elseif ( $output == ARRAY_N ) { 779 $__term = array_values(get_object_vars($_term)); 780 return $__term; 781 } else { 782 return $_term; 799 return array_values( $_term->to_array() ); 783 800 } 801 802 return $_term; 784 803 } 785 804 786 805 /** … … 798 817 * @todo Better formatting for DocBlock. 799 818 * 800 819 * @since 2.3.0 801 * @since 4.4.0 `$taxonomy` is optional if `$field` is 'term_taxonomy_id'. 820 * @since 4.4.0 `$taxonomy` is optional if `$field` is 'term_taxonomy_id'. Converted to return 821 * a WP_Term object if `$output` is `OBJECT`. 802 822 * 803 823 * @global wpdb $wpdb WordPress database abstraction object. 804 824 * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. … … 808 828 * @param string $taxonomy Taxonomy name. Optional, if `$field` is 'term_taxonomy_id'. 809 829 * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N 810 830 * @param string $filter Optional, default is raw or no WordPress defined filter will applied. 811 * @return object|array|null|WP_Error|false Term Row from database. 812 * Will return false if $taxonomy does not exist or $term was not found. 831 * @return mixed WP_Term instance. Will return false if `$taxonomy` does not exist or `$term` was not found. 813 832 */ 814 833 function get_term_by( $field, $value, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) { 815 834 global $wpdb; … … 822 841 $tax_clause = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy ); 823 842 824 843 if ( 'slug' == $field ) { 825 $ field = 't.slug';844 $_field = 't.slug'; 826 845 $value = sanitize_title($value); 827 846 if ( empty($value) ) 828 847 return false; … … 829 848 } elseif ( 'name' == $field ) { 830 849 // Assume already escaped 831 850 $value = wp_unslash($value); 832 $ field = 't.name';851 $_field = 't.name'; 833 852 } elseif ( 'term_taxonomy_id' == $field ) { 834 853 $value = (int) $value; 835 $ field = 'tt.term_taxonomy_id';854 $_field = 'tt.term_taxonomy_id'; 836 855 837 856 // No `taxonomy` clause when searching by 'term_taxonomy_id'. 838 857 $tax_clause = ''; … … 844 863 return $term; 845 864 } 846 865 847 $term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE $ field = %s $tax_clause LIMIT 1", $value ) );866 $term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE $_field = %s $tax_clause LIMIT 1", $value ) ); 848 867 if ( ! $term ) 849 868 return false; 850 869 … … 853 872 $taxonomy = $term->taxonomy; 854 873 } 855 874 856 wp_cache_add( $term->term_id, $term, $taxonomy);875 wp_cache_add( $term->term_id, $term, 'terms' ); 857 876 858 /** This filter is documented in wp-includes/taxonomy-functions.php */ 859 $term = apply_filters( 'get_term', $term, $taxonomy ); 860 861 /** This filter is documented in wp-includes/taxonomy-functions.php */ 862 $term = apply_filters( "get_$taxonomy", $term, $taxonomy ); 863 864 $term = sanitize_term($term, $taxonomy, $filter); 865 866 if ( $output == OBJECT ) { 867 return $term; 868 } elseif ( $output == ARRAY_A ) { 869 return get_object_vars($term); 870 } elseif ( $output == ARRAY_N ) { 871 return array_values(get_object_vars($term)); 872 } else { 873 return $term; 874 } 877 return get_term( $term, $taxonomy, $output, $filter ); 875 878 } 876 879 877 880 /** … … 987 990 * @since 2.3.0 988 991 * @since 4.2.0 Introduced 'name' and 'childless' parameters. 989 992 * @since 4.4.0 Introduced the ability to pass 'term_id' as an alias of 'id' for the `orderby` parameter. 990 * Introduced the 'meta_query' and 'update_term_meta_cache' parameters. 993 * Introduced the 'meta_query' and 'update_term_meta_cache' parameters. Converted to return 994 * a list of WP_Term objects. 991 995 * 992 996 * @global wpdb $wpdb WordPress database abstraction object. 993 997 * @global array $wp_filter … … 1048 1052 * @type array $meta_query Meta query clauses to limit retrieved terms by. 1049 1053 * See `WP_Meta_Query`. Default empty. 1050 1054 * } 1051 * @return array|int|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies1052 * do not exist.1055 * @return array|int|WP_Error List of WP_Term instances and their children. Will return WP_Error, if any of $taxonomies 1056 * do not exist. 1053 1057 */ 1054 1058 function get_terms( $taxonomies, $args = '' ) { 1055 1059 global $wpdb; … … 1489 1493 foreach ( $terms as $term ) { 1490 1494 $_terms[ $term->term_id ] = $term->slug; 1491 1495 } 1496 } else { 1497 $_terms = array_map( 'get_term', $terms ); 1492 1498 } 1493 1499 1494 1500 if ( ! empty( $_terms ) ) { … … 3422 3428 foreach ( (array) $terms as $term ) { 3423 3429 $taxonomies[] = $term->taxonomy; 3424 3430 $ids[] = $term->term_id; 3425 wp_cache_delete( $term->term_id, $term->taxonomy);3431 wp_cache_delete( $term->term_id, 'terms' ); 3426 3432 } 3427 3433 $taxonomies = array_unique($taxonomies); 3428 3434 } else { … … 3429 3435 $taxonomies = array($taxonomy); 3430 3436 foreach ( $taxonomies as $taxonomy ) { 3431 3437 foreach ( $ids as $id ) { 3432 wp_cache_delete( $id, $taxonomy);3438 wp_cache_delete( $id, 'terms' ); 3433 3439 } 3434 3440 } 3435 3441 } … … 3552 3558 if ( empty($term_taxonomy) ) 3553 3559 $term_taxonomy = $term->taxonomy; 3554 3560 3555 wp_cache_add( $term->term_id, $term, $term_taxonomy);3561 wp_cache_add( $term->term_id, $term, 'terms' ); 3556 3562 } 3557 3563 } 3558 3564 -
src/wp-includes/taxonomy.php
10 10 /** Core taxonomy functionality */ 11 11 require_once( ABSPATH . WPINC . '/taxonomy-functions.php' ); 12 12 13 /** WP_Term class */ 14 require_once( ABSPATH . WPINC . '/class-wp-term.php' ); 15 13 16 /** WP_Tax_Query class */ 14 17 require_once( ABSPATH . WPINC . '/class-wp-tax-query.php' ); -
tests/phpunit/tests/term/cache.php
103 103 ) ); 104 104 105 105 $term_object = get_term( $term, 'wptests_tax' ); 106 wp_cache_delete( $term, ' wptests_tax' );106 wp_cache_delete( $term, 'terms' ); 107 107 108 108 // Affirm that the cache is empty. 109 $this->assertEmpty( wp_cache_get( $term, ' wptests_tax' ) );109 $this->assertEmpty( wp_cache_get( $term, 'terms' ) ); 110 110 111 111 $num_queries = $wpdb->num_queries; 112 112 … … 128 128 'taxonomy' => 'wptests_tax', 129 129 ) ); 130 130 131 wp_cache_delete( $term, ' wptests_tax' );131 wp_cache_delete( $term, 'terms' ); 132 132 133 133 // Affirm that the cache is empty. 134 $this->assertEmpty( wp_cache_get( $term, ' wptests_tax' ) );134 $this->assertEmpty( wp_cache_get( $term, 'terms' ) ); 135 135 136 136 $num_queries = $wpdb->num_queries; 137 137 138 138 // Prime cache. 139 139 $term_object = get_term( $term, 'wptests_tax' ); 140 $this->assertNotEmpty( wp_cache_get( $term, ' wptests_tax' ) );140 $this->assertNotEmpty( wp_cache_get( $term, 'terms' ) ); 141 141 $this->assertSame( $num_queries + 1, $wpdb->num_queries ); 142 142 143 143 $term_object_2 = get_term( $term, 'wptests_tax' ); … … 155 155 'taxonomy' => 'wptests_tax', 156 156 ) ); 157 157 158 wp_cache_delete( $term, ' wptests_tax' );158 wp_cache_delete( $term, 'terms' ); 159 159 160 160 // Affirm that the cache is empty. 161 $this->assertEmpty( wp_cache_get( $term, ' wptests_tax' ) );161 $this->assertEmpty( wp_cache_get( $term, 'terms' ) ); 162 162 163 163 $num_queries = $wpdb->num_queries; 164 164 165 165 // Prime cache. 166 166 $term_object = get_term_by( 'id', $term, 'wptests_tax' ); 167 $this->assertNotEmpty( wp_cache_get( $term, ' wptests_tax' ) );167 $this->assertNotEmpty( wp_cache_get( $term, 'terms' ) ); 168 168 $this->assertSame( $num_queries + 1, $wpdb->num_queries ); 169 169 170 170 $term_object_2 = get_term( $term, 'wptests_tax' ); -
tests/phpunit/tests/term/getTerm.php
35 35 $this->assertSame( $num_queries, $wpdb->num_queries ); 36 36 } 37 37 38 public function test_passing_term_object_should_not_skip_database_query_when_filter_property_is_set() {39 global $wpdb;40 41 $term = $this->factory->term->create_and_get( array( 'taxonomy' => 'wptests_tax' ) );42 clean_term_cache( $term->term_id, 'wptests_tax' );43 44 $num_queries = $wpdb->num_queries;45 46 $term_a = get_term( $term, 'wptests_tax' );47 48 $this->assertSame( $num_queries + 1, $wpdb->num_queries );49 }50 51 38 public function test_passing_term_string_that_casts_to_int_0_should_return_null() { 52 39 $this->assertSame( null, get_term( 'abc', 'wptests_tax' ) ); 53 40 }