| 1 | Index: wp-includes/taxonomy.php |
|---|
| 2 | =================================================================== |
|---|
| 3 | --- wp-includes/taxonomy.php (revision 16845) |
|---|
| 4 | +++ wp-includes/taxonomy.php (working copy) |
|---|
| 5 | @@ -527,148 +527,152 @@ |
|---|
| 6 | * @return array |
|---|
| 7 | */ |
|---|
| 8 | function get_tax_sql( $tax_query, $primary_table, $primary_id_column ) { |
|---|
| 9 | - global $wpdb; |
|---|
| 10 | + $tax_query_obj = new WP_Tax_Query( $tax_query ); |
|---|
| 11 | + return $tax_query_obj->get_sql( $primary_table, $primary_id_column ); |
|---|
| 12 | +} |
|---|
| 13 | |
|---|
| 14 | - $join = ''; |
|---|
| 15 | - $where = array(); |
|---|
| 16 | - $i = 0; |
|---|
| 17 | +class WP_Tax_Query { |
|---|
| 18 | + var $relation = ''; |
|---|
| 19 | + var $queries = array(); |
|---|
| 20 | |
|---|
| 21 | - _set_tax_query_defaults( $tax_query ); |
|---|
| 22 | + function __construct( &$tax_query ) { |
|---|
| 23 | + if ( isset( $tax_query['relation'] ) && strtoupper( $tax_query['relation'] ) == 'OR' ) { |
|---|
| 24 | + $this->relation = 'OR'; |
|---|
| 25 | + } else { |
|---|
| 26 | + $this->relation = 'AND'; |
|---|
| 27 | + } |
|---|
| 28 | |
|---|
| 29 | - if ( strtoupper( $tax_query['relation'] ) == 'OR' ) { |
|---|
| 30 | - $relation = 'OR'; |
|---|
| 31 | - } else { |
|---|
| 32 | - $relation = 'AND'; |
|---|
| 33 | - } |
|---|
| 34 | + $defaults = array( |
|---|
| 35 | + 'taxonomy' => '', |
|---|
| 36 | + 'terms' => array(), |
|---|
| 37 | + 'include_children' => true, |
|---|
| 38 | + 'field' => 'term_id', |
|---|
| 39 | + 'operator' => 'IN', |
|---|
| 40 | + ); |
|---|
| 41 | |
|---|
| 42 | - foreach ( $tax_query as $query ) { |
|---|
| 43 | - if ( ! is_array( $query ) ) |
|---|
| 44 | - continue; |
|---|
| 45 | + foreach ( $tax_query as $query ) { |
|---|
| 46 | + if ( ! is_array( $query ) ) |
|---|
| 47 | + continue; |
|---|
| 48 | |
|---|
| 49 | - extract( $query ); |
|---|
| 50 | + $query = array_merge( $defaults, $query ); |
|---|
| 51 | |
|---|
| 52 | - if ( ! taxonomy_exists( $taxonomy ) ) |
|---|
| 53 | - return array( 'join' => '', 'where' => ' AND 0 = 1'); |
|---|
| 54 | + $query['terms'] = (array) $query['terms']; |
|---|
| 55 | + |
|---|
| 56 | + $this->queries[] = $query; |
|---|
| 57 | + } |
|---|
| 58 | + } |
|---|
| 59 | |
|---|
| 60 | - $terms = array_unique( (array) $terms ); |
|---|
| 61 | + function get_sql( $primary_table, $primary_id_column ) { |
|---|
| 62 | + global $wpdb; |
|---|
| 63 | |
|---|
| 64 | - if ( empty( $terms ) ) |
|---|
| 65 | - continue; |
|---|
| 66 | + $join = ''; |
|---|
| 67 | + $where = array(); |
|---|
| 68 | + $i = 0; |
|---|
| 69 | |
|---|
| 70 | - if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) { |
|---|
| 71 | - _transform_terms( $terms, $taxonomy, $field, 'term_id' ); |
|---|
| 72 | + foreach ( $this->queries as $query ) { |
|---|
| 73 | + extract( $query ); |
|---|
| 74 | |
|---|
| 75 | - $children = array(); |
|---|
| 76 | - foreach ( $terms as $term ) { |
|---|
| 77 | - $children = array_merge( $children, get_term_children( $term, $taxonomy ) ); |
|---|
| 78 | - $children[] = $term; |
|---|
| 79 | - } |
|---|
| 80 | - $terms = $children; |
|---|
| 81 | + if ( ! taxonomy_exists( $taxonomy ) ) |
|---|
| 82 | + return array( 'join' => '', 'where' => ' AND 0 = 1'); |
|---|
| 83 | |
|---|
| 84 | - _transform_terms( $terms, $taxonomy, 'term_id', 'term_taxonomy_id' ); |
|---|
| 85 | - } |
|---|
| 86 | - else { |
|---|
| 87 | - _transform_terms( $terms, $taxonomy, $field, 'term_taxonomy_id' ); |
|---|
| 88 | - } |
|---|
| 89 | + $terms = array_unique( (array) $terms ); |
|---|
| 90 | |
|---|
| 91 | - if ( 'IN' == $operator ) { |
|---|
| 92 | + if ( empty( $terms ) ) |
|---|
| 93 | + continue; |
|---|
| 94 | |
|---|
| 95 | - if ( empty( $terms ) ) { |
|---|
| 96 | - if ( 'OR' == $relation ) |
|---|
| 97 | - continue; |
|---|
| 98 | - else |
|---|
| 99 | - return array( 'join' => '', 'where' => ' AND 0 = 1' ); |
|---|
| 100 | - } |
|---|
| 101 | + if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) { |
|---|
| 102 | + $this->_transform_terms( $terms, $taxonomy, $field, 'term_id' ); |
|---|
| 103 | |
|---|
| 104 | - $terms = implode( ',', $terms ); |
|---|
| 105 | + $children = array(); |
|---|
| 106 | + foreach ( $terms as $term ) { |
|---|
| 107 | + $children = array_merge( $children, get_term_children( $term, $taxonomy ) ); |
|---|
| 108 | + $children[] = $term; |
|---|
| 109 | + } |
|---|
| 110 | + $terms = $children; |
|---|
| 111 | |
|---|
| 112 | - $alias = $i ? 'tt' . $i : $wpdb->term_relationships; |
|---|
| 113 | + $this->_transform_terms( $terms, $taxonomy, 'term_id', 'term_taxonomy_id' ); |
|---|
| 114 | + } |
|---|
| 115 | + else { |
|---|
| 116 | + $this->_transform_terms( $terms, $taxonomy, $field, 'term_taxonomy_id' ); |
|---|
| 117 | + } |
|---|
| 118 | |
|---|
| 119 | - $join .= " INNER JOIN $wpdb->term_relationships"; |
|---|
| 120 | - $join .= $i ? " AS $alias" : ''; |
|---|
| 121 | - $join .= " ON ($primary_table.$primary_id_column = $alias.object_id)"; |
|---|
| 122 | + if ( 'IN' == $operator ) { |
|---|
| 123 | |
|---|
| 124 | - $where[] = "$alias.term_taxonomy_id $operator ($terms)"; |
|---|
| 125 | - } |
|---|
| 126 | - elseif ( 'NOT IN' == $operator ) { |
|---|
| 127 | + if ( empty( $terms ) ) { |
|---|
| 128 | + if ( 'OR' == $relation ) |
|---|
| 129 | + continue; |
|---|
| 130 | + else |
|---|
| 131 | + return array( 'join' => '', 'where' => ' AND 0 = 1' ); |
|---|
| 132 | + } |
|---|
| 133 | |
|---|
| 134 | - if ( empty( $terms ) ) |
|---|
| 135 | - continue; |
|---|
| 136 | + $terms = implode( ',', $terms ); |
|---|
| 137 | |
|---|
| 138 | - $terms = implode( ',', $terms ); |
|---|
| 139 | + $alias = $i ? 'tt' . $i : $wpdb->term_relationships; |
|---|
| 140 | |
|---|
| 141 | - $where[] = "$primary_table.$primary_id_column NOT IN ( |
|---|
| 142 | - SELECT object_id |
|---|
| 143 | - FROM $wpdb->term_relationships |
|---|
| 144 | - WHERE term_taxonomy_id IN ($terms) |
|---|
| 145 | - )"; |
|---|
| 146 | - } |
|---|
| 147 | + $join .= " INNER JOIN $wpdb->term_relationships"; |
|---|
| 148 | + $join .= $i ? " AS $alias" : ''; |
|---|
| 149 | + $join .= " ON ($primary_table.$primary_id_column = $alias.object_id)"; |
|---|
| 150 | |
|---|
| 151 | - $i++; |
|---|
| 152 | - } |
|---|
| 153 | + $where[] = "$alias.term_taxonomy_id $operator ($terms)"; |
|---|
| 154 | + } |
|---|
| 155 | + elseif ( 'NOT IN' == $operator ) { |
|---|
| 156 | |
|---|
| 157 | - if ( !empty( $where ) ) |
|---|
| 158 | - $where = ' AND ( ' . implode( " $relation ", $where ) . ' )'; |
|---|
| 159 | - else |
|---|
| 160 | - $where = ''; |
|---|
| 161 | + if ( empty( $terms ) ) |
|---|
| 162 | + continue; |
|---|
| 163 | |
|---|
| 164 | - return compact( 'join', 'where' ); |
|---|
| 165 | -} |
|---|
| 166 | + $terms = implode( ',', $terms ); |
|---|
| 167 | |
|---|
| 168 | -function _set_tax_query_defaults( &$tax_query ) { |
|---|
| 169 | - if ( ! isset( $tax_query['relation'] ) ) |
|---|
| 170 | - $tax_query['relation'] = 'AND'; |
|---|
| 171 | + $where[] = "$primary_table.$primary_id_column NOT IN ( |
|---|
| 172 | + SELECT object_id |
|---|
| 173 | + FROM $wpdb->term_relationships |
|---|
| 174 | + WHERE term_taxonomy_id IN ($terms) |
|---|
| 175 | + )"; |
|---|
| 176 | + } |
|---|
| 177 | |
|---|
| 178 | - $defaults = array( |
|---|
| 179 | - 'taxonomy' => '', |
|---|
| 180 | - 'terms' => array(), |
|---|
| 181 | - 'include_children' => true, |
|---|
| 182 | - 'field' => 'term_id', |
|---|
| 183 | - 'operator' => 'IN', |
|---|
| 184 | - ); |
|---|
| 185 | + $i++; |
|---|
| 186 | + } |
|---|
| 187 | |
|---|
| 188 | - foreach ( $tax_query as $i => $query ) { |
|---|
| 189 | - if ( ! is_array( $query ) ) |
|---|
| 190 | - continue; |
|---|
| 191 | + if ( !empty( $where ) ) |
|---|
| 192 | + $where = ' AND ( ' . implode( " $relation ", $where ) . ' )'; |
|---|
| 193 | + else |
|---|
| 194 | + $where = ''; |
|---|
| 195 | |
|---|
| 196 | - $tax_query[$i] = array_merge( $defaults, $query ); |
|---|
| 197 | - |
|---|
| 198 | - $tax_query[$i]['terms'] = (array) $tax_query[$i]['terms']; |
|---|
| 199 | + return compact( 'join', 'where' ); |
|---|
| 200 | } |
|---|
| 201 | -} |
|---|
| 202 | |
|---|
| 203 | -function _transform_terms( &$terms, $taxonomy, $field, $resulting_field ) { |
|---|
| 204 | - global $wpdb; |
|---|
| 205 | + function _transform_terms( &$terms, $taxonomy, $field, $resulting_field ) { |
|---|
| 206 | + global $wpdb; |
|---|
| 207 | |
|---|
| 208 | - if ( empty( $terms ) ) |
|---|
| 209 | - return; |
|---|
| 210 | + if ( empty( $terms ) ) |
|---|
| 211 | + return; |
|---|
| 212 | |
|---|
| 213 | - if ( $field == $resulting_field ) |
|---|
| 214 | - return; |
|---|
| 215 | + if ( $field == $resulting_field ) |
|---|
| 216 | + return; |
|---|
| 217 | |
|---|
| 218 | - $resulting_field = esc_sql( $resulting_field ); |
|---|
| 219 | + $resulting_field = esc_sql( $resulting_field ); |
|---|
| 220 | |
|---|
| 221 | - switch ( $field ) { |
|---|
| 222 | - case 'slug': |
|---|
| 223 | - case 'name': |
|---|
| 224 | - $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'"; |
|---|
| 225 | - $terms = $wpdb->get_col( " |
|---|
| 226 | - SELECT $wpdb->term_taxonomy.$resulting_field |
|---|
| 227 | - FROM $wpdb->term_taxonomy |
|---|
| 228 | - INNER JOIN $wpdb->terms USING (term_id) |
|---|
| 229 | - WHERE taxonomy = '$taxonomy' |
|---|
| 230 | - AND $wpdb->terms.$field IN ($terms) |
|---|
| 231 | - " ); |
|---|
| 232 | - break; |
|---|
| 233 | + switch ( $field ) { |
|---|
| 234 | + case 'slug': |
|---|
| 235 | + case 'name': |
|---|
| 236 | + $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'"; |
|---|
| 237 | + $terms = $wpdb->get_col( " |
|---|
| 238 | + SELECT $wpdb->term_taxonomy.$resulting_field |
|---|
| 239 | + FROM $wpdb->term_taxonomy |
|---|
| 240 | + INNER JOIN $wpdb->terms USING (term_id) |
|---|
| 241 | + WHERE taxonomy = '$taxonomy' |
|---|
| 242 | + AND $wpdb->terms.$field IN ($terms) |
|---|
| 243 | + " ); |
|---|
| 244 | + break; |
|---|
| 245 | |
|---|
| 246 | - default: |
|---|
| 247 | - $terms = implode( ',', array_map( 'intval', $terms ) ); |
|---|
| 248 | - $terms = $wpdb->get_col( " |
|---|
| 249 | - SELECT $resulting_field |
|---|
| 250 | - FROM $wpdb->term_taxonomy |
|---|
| 251 | - WHERE taxonomy = '$taxonomy' |
|---|
| 252 | - AND term_id IN ($terms) |
|---|
| 253 | - " ); |
|---|
| 254 | + default: |
|---|
| 255 | + $terms = implode( ',', array_map( 'intval', $terms ) ); |
|---|
| 256 | + $terms = $wpdb->get_col( " |
|---|
| 257 | + SELECT $resulting_field |
|---|
| 258 | + FROM $wpdb->term_taxonomy |
|---|
| 259 | + WHERE taxonomy = '$taxonomy' |
|---|
| 260 | + AND term_id IN ($terms) |
|---|
| 261 | + " ); |
|---|
| 262 | + } |
|---|
| 263 | } |
|---|
| 264 | } |
|---|
| 265 | |
|---|
| 266 | Index: wp-includes/query.php |
|---|
| 267 | =================================================================== |
|---|
| 268 | --- wp-includes/query.php (revision 16844) |
|---|
| 269 | +++ wp-includes/query.php (working copy) |
|---|
| 270 | @@ -714,9 +714,9 @@ |
|---|
| 271 | * |
|---|
| 272 | * @since 3.1.0 |
|---|
| 273 | * @access public |
|---|
| 274 | - * @var array |
|---|
| 275 | + * @var object WP_Tax_Query |
|---|
| 276 | */ |
|---|
| 277 | - var $tax_query = array(); |
|---|
| 278 | + var $tax_query; |
|---|
| 279 | |
|---|
| 280 | /** |
|---|
| 281 | * Holds the data for a single object that is queried. |
|---|
| 282 | @@ -1584,12 +1584,9 @@ |
|---|
| 283 | ); |
|---|
| 284 | } |
|---|
| 285 | |
|---|
| 286 | - _set_tax_query_defaults( $tax_query ); |
|---|
| 287 | + $tax_query_obj = new WP_Tax_Query( $tax_query ); |
|---|
| 288 | |
|---|
| 289 | - foreach ( $tax_query as $query ) { |
|---|
| 290 | - if ( ! is_array( $query ) ) |
|---|
| 291 | - continue; |
|---|
| 292 | - |
|---|
| 293 | + foreach ( $tax_query_obj->queries as $query ) { |
|---|
| 294 | if ( 'IN' == $query['operator'] ) { |
|---|
| 295 | switch ( $query['taxonomy'] ) { |
|---|
| 296 | case 'category': |
|---|
| 297 | @@ -1604,7 +1601,7 @@ |
|---|
| 298 | } |
|---|
| 299 | } |
|---|
| 300 | |
|---|
| 301 | - return $tax_query; |
|---|
| 302 | + return $tax_query_obj; |
|---|
| 303 | } |
|---|
| 304 | |
|---|
| 305 | /** |
|---|
| 306 | @@ -1942,7 +1939,7 @@ |
|---|
| 307 | if ( $this->is_category || $this->is_tag || $this->is_tax ) { |
|---|
| 308 | $this->tax_query = $this->parse_tax_query( $q ); |
|---|
| 309 | |
|---|
| 310 | - $clauses = call_user_func_array( 'get_tax_sql', array( $this->tax_query, $wpdb->posts, 'ID', &$this) ); |
|---|
| 311 | + $clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' ); |
|---|
| 312 | |
|---|
| 313 | $join .= $clauses['join']; |
|---|
| 314 | $where .= $clauses['where']; |
|---|
| 315 | @@ -1957,7 +1954,7 @@ |
|---|
| 316 | } |
|---|
| 317 | |
|---|
| 318 | // Back-compat |
|---|
| 319 | - $tax_query_in = wp_list_filter( $this->tax_query, array( 'operator' => 'IN' ) ); |
|---|
| 320 | + $tax_query_in = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'IN' ) ); |
|---|
| 321 | if ( !empty( $tax_query_in ) ) { |
|---|
| 322 | if ( !isset( $q['taxonomy'] ) ) { |
|---|
| 323 | foreach ( $tax_query_in as $a_tax_query ) { |
|---|
| 324 | @@ -2657,7 +2654,7 @@ |
|---|
| 325 | $this->queried_object = NULL; |
|---|
| 326 | $this->queried_object_id = 0; |
|---|
| 327 | |
|---|
| 328 | - $tax_query_in = wp_list_filter( $this->tax_query, array( 'operator' => 'IN' ) ); |
|---|
| 329 | + $tax_query_in = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'IN' ) ); |
|---|
| 330 | if ( !empty( $tax_query_in ) ) { |
|---|
| 331 | $query = reset( $tax_query_in ); |
|---|
| 332 | |
|---|
| 333 | Index: wp-includes/canonical.php |
|---|
| 334 | =================================================================== |
|---|
| 335 | --- wp-includes/canonical.php (revision 16842) |
|---|
| 336 | +++ wp-includes/canonical.php (working copy) |
|---|
| 337 | @@ -146,7 +146,7 @@ |
|---|
| 338 | } elseif ( is_category() || is_tag() || is_tax() ) { // Terms (Tags/categories) |
|---|
| 339 | |
|---|
| 340 | $term_count = 0; |
|---|
| 341 | - foreach ( $wp_query->tax_query as $tax_query ) |
|---|
| 342 | + foreach ( $wp_query->tax_query->queries as $tax_query ) |
|---|
| 343 | $term_count += count( $tax_query['terms'] ); |
|---|
| 344 | |
|---|
| 345 | $obj = $wp_query->get_queried_object(); |
|---|