Ticket #12891: scale.12891.5.diff
File scale.12891.5.diff, 9.0 KB (added by , 15 years ago) |
---|
-
wp-includes/taxonomy.php
460 460 * @uses $wpdb 461 461 * @uses wp_parse_args() Creates an array from string $args. 462 462 * 463 * @param mixed $terms Term id/slug/name or array of such to match against463 * @param int|array $term_ids Term id or array of term ids of terms that will be used 464 464 * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names 465 * @param array|string $args 466 * 'include_children' bool Whether to include term children (hierarchical taxonomies only) 467 * 'field' string Which term field is being used. Can be 'term_id', 'slug' or 'name' 468 * 'operator' string Can be 'IN' and 'NOT IN' 469 * 'do_query' bool Whether to execute the query or return the SQL string 470 * 471 * @return WP_Error If the taxonomy does not exist 472 * @return array The list of found object_ids 473 * @return string The SQL string, if do_query is set to false 465 * @param array|string $args Change the order of the object_ids, either ASC or DESC 466 * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success 467 * the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found. 474 468 */ 475 function get_objects_in_term( $term s, $taxonomies, $args = array() ) {469 function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) { 476 470 global $wpdb; 477 471 478 extract( wp_parse_args( $args, array( 479 'include_children' => false, 480 'field' => 'term_id', 481 'operator' => 'IN', 482 'do_query' => true, 483 ) ), EXTR_SKIP ); 472 if ( ! is_array( $term_ids ) ) 473 $term_ids = array( $term_ids ); 484 474 485 $taxonomies = (array) $taxonomies; 475 if ( ! is_array( $taxonomies ) ) 476 $taxonomies = array( $taxonomies ); 486 477 487 foreach ( $taxonomies as $taxonomy ) {478 foreach ( (array) $taxonomies as $taxonomy ) { 488 479 if ( ! taxonomy_exists( $taxonomy ) ) 489 return new WP_Error( 'invalid_taxonomy', sprintf( __( 'Invalid Taxonomy: %s' ), $taxonomy) );480 return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy' ) ); 490 481 } 491 482 492 if ( !in_array( $field, array( 'term_id', 'slug', 'name' ) ) ) 493 $field = 'term_id'; 483 $defaults = array( 'order' => 'ASC' ); 484 $args = wp_parse_args( $args, $defaults ); 485 extract( $args, EXTR_SKIP ); 494 486 495 if ( !in_array( $operator, array( 'IN', 'NOT IN' ) ) ) 496 $operator = 'IN'; 487 $order = ( 'desc' == strtolower( $order ) ) ? 'DESC' : 'ASC'; 497 488 498 $term s = array_unique( (array) $terms );489 $term_ids = array_map('intval', $term_ids ); 499 490 500 if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) {501 $children = array();502 foreach ( $terms as $term ) {503 if ( 'term_id' != $field ) {504 if ( $term = get_term_by( $field, $term, $taxonomy ) )505 $term = $term->term_id;506 else507 continue;508 }509 $children = array_merge( $children, get_term_children( $term, $taxonomy ) );510 $children[] = $term;511 }512 $terms = $children;513 $field = 'term_id';514 }515 516 if ( empty( $terms ) )517 return $do_query ? array() : '';518 519 491 $taxonomies = "'" . implode( "', '", $taxonomies ) . "'"; 492 $term_ids = "'" . implode( "', '", $term_ids ) . "'"; 520 493 521 switch ( $field ) { 522 case 'term_id': 523 $terms = array_map( 'intval', $terms ); 494 $object_ids = $wpdb->get_col("SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tt.term_id IN ($term_ids) ORDER BY tr.object_id $order"); 524 495 525 $terms = implode( ',', $terms ); 526 $sql = " 527 SELECT object_id 528 FROM $wpdb->term_relationships 529 INNER JOIN $wpdb->term_taxonomy USING (term_taxonomy_id) 530 WHERE taxonomy IN ($taxonomies) 531 AND term_id $operator ($terms) 532 "; 533 break; 496 if ( ! $object_ids ) 497 return array(); 534 498 535 case 'slug': 536 case 'name': 537 foreach ( $terms as $i => $term ) { 538 $terms[$i] = sanitize_title_for_query( $term ); 539 } 540 $terms = array_filter($terms); 541 542 $terms = "'" . implode( "','", $terms ) . "'"; 543 $sql = " 544 SELECT object_id 545 FROM $wpdb->term_relationships 546 INNER JOIN $wpdb->term_taxonomy USING (term_taxonomy_id) 547 INNER JOIN $wpdb->terms USING (term_id) 548 WHERE taxonomy IN ($taxonomies) 549 AND $field $operator ($terms) 550 "; 551 break; 552 } 553 554 return $do_query ? $wpdb->get_col( $sql ) : $sql; 499 return $object_ids; 555 500 } 556 501 557 502 /* … … 571 516 * - 'include_children' bool (optional) Whether to include child terms. 572 517 * Default: true 573 518 * 574 * @param string $object_id_column 519 * @param string $primary_table 520 * @param string $primary_id_column 575 521 * @return string 576 522 */ 577 function get_tax_sql( $tax_query, $ object_id_column ) {523 function get_tax_sql( $tax_query, $primary_table, $primary_id_column ) { 578 524 global $wpdb; 579 525 580 $sql = array(); 526 $join = ''; 527 $where = ''; 528 $i = 0; 581 529 foreach ( $tax_query as $query ) { 582 if ( !isset( $query['include_children'] ) ) 583 $query['include_children'] = true; 530 extract( wp_parse_args( $query, array( 531 'taxonomy' => array(), 532 'terms' => array(), 533 'include_children' => true, 534 'field' => 'term_id', 535 'operator' => 'IN', 536 ) ) ); 584 537 585 $ query['do_query'] = false;538 $taxonomies = (array) $taxonomy; 586 539 587 $sql_single = get_objects_in_term( $query['terms'], $query['taxonomy'], $query ); 540 foreach ( $taxonomies as $taxonomy ) { 541 if ( ! taxonomy_exists( $taxonomy ) ) 542 return ' AND 0 = 1'; 543 } 588 544 589 if ( empty( $sql_single ) || is_wp_error( $sql_single) )590 return ' AND 0 = 1';545 if ( !in_array( $operator, array( 'IN', 'NOT IN' ) ) ) 546 $operator = 'IN'; 591 547 592 $sql[] = $sql_single; 593 } 548 $taxonomies = "'" . implode( "', '", $taxonomies ) . "'"; 594 549 595 if ( 1 == count( $sql ) ) { 596 $ids = $wpdb->get_col( $sql[0] ); 597 } else { 598 $r = "SELECT object_id FROM $wpdb->term_relationships WHERE 1=1"; 599 foreach ( $sql as $query ) 600 $r .= " AND object_id IN ($query)"; 550 $terms = array_unique( (array) $terms ); 601 551 602 $ids = $wpdb->get_col( $r ); 552 if ( empty( $terms ) ) 553 continue; 554 555 if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) { 556 _transform_terms( $terms, $taxonomies, $field, 'term_id' ); 557 558 if ( empty( $terms ) ) 559 continue; 560 561 $children = array(); 562 foreach ( $terms as $term ) { 563 $children = array_merge( $children, get_term_children( $term, $taxonomy ) ); 564 $children[] = $term; 565 } 566 $terms = $children; 567 568 _transform_terms( $terms, $taxonomies, 'term_id', 'term_taxonomy_id' ); 569 } 570 else { 571 _transform_terms( $terms, $taxonomies, $field, 'term_taxonomy_id' ); 572 } 573 574 if ( empty( $terms ) ) 575 continue; 576 577 $terms = implode( ',', $terms ); 578 579 if ( 'IN' == $operator ) { 580 $alias = $i ? 'tt' . $i : $wpdb->term_relationships; 581 582 $join .= " INNER JOIN $wpdb->term_relationships"; 583 $join .= $i ? " AS $alias" : ''; 584 $join .= " ON ($primary_table.$primary_id_column = $alias.object_id)"; 585 586 $where .= " AND $alias.term_taxonomy_id $operator ($terms)"; 587 588 $i++; 589 } 590 else { 591 // NOT IN is very slow for some reason 592 $where .= " AND $primary_table.$primary_id_column IN ( 593 SELECT object_id 594 FROM $wpdb->term_relationships 595 WHERE term_taxonomy_id $operator ($terms) 596 )"; 597 } 603 598 } 604 599 605 if ( !empty( $ids ) ) 606 return " AND $object_id_column IN(" . implode( ', ', $ids ) . ")"; 607 else 608 return ' AND 0 = 1'; 600 return compact( 'join', 'where' ); 609 601 } 610 602 603 function _transform_terms( &$terms, $taxonomies, $field, $resulting_field ) { 604 global $wpdb; 611 605 606 if ( $field == $resulting_field ) 607 return; 608 609 $resulting_field = esc_sql( $resulting_field ); 610 611 switch ( $field ) { 612 case 'slug': 613 case 'name': 614 $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'"; 615 $terms = $wpdb->get_col( " 616 SELECT $resulting_field 617 FROM $wpdb->term_taxonomy 618 INNER JOIN $wpdb->terms USING (term_id) 619 WHERE taxonomy IN ($taxonomies) 620 AND $field IN ($terms) 621 " ); 622 break; 623 624 default: 625 $terms = implode( ',', array_map( 'intval', $terms ) ); 626 $terms = $wpdb->get_col( " 627 SELECT $resulting_field 628 FROM $wpdb->term_taxonomy 629 WHERE taxonomy IN ($taxonomies) 630 AND term_id IN ($terms) 631 " ); 632 } 633 } 634 612 635 /** 613 636 * Get all Term data from database by Term ID. 614 637 * -
wp-includes/query.php
1933 1933 // Taxonomies 1934 1934 $q['tax_query'] = $this->parse_tax_query( $q ); 1935 1935 if ( !empty( $q['tax_query'] ) ) { 1936 $clauses = call_user_func_array( 'get_tax_sql', array( $q['tax_query'], $wpdb->posts, 'ID', &$this) ); 1937 1938 $join .= $clauses['join']; 1939 $where .= $clauses['where']; 1940 1936 1941 if ( empty($post_type) ) { 1937 1942 $post_type = 'any'; 1938 1943 $post_status_join = true; … … 1940 1945 $post_status_join = true; 1941 1946 } 1942 1947 1943 $where .= get_tax_sql( $q['tax_query'], "$wpdb->posts.ID" );1944 1945 1948 // Back-compat 1946 1949 $tax_query_in = wp_list_filter( $q['tax_query'], array( 'operator' => 'IN' ) ); 1947 1950 if ( !empty( $tax_query_in ) ) {