Ticket #15752: WP_Tax_Query.diff
File WP_Tax_Query.diff, 9.5 KB (added by , 14 years ago) |
---|
-
wp-includes/taxonomy.php
527 527 * @return array 528 528 */ 529 529 function get_tax_sql( $tax_query, $primary_table, $primary_id_column ) { 530 global $wpdb; 530 $tax_query_obj = new WP_Tax_Query( $tax_query ); 531 return $tax_query_obj->get_sql( $primary_table, $primary_id_column ); 532 } 531 533 532 $join = ''; 533 $where = array();534 $i = 0;534 class WP_Tax_Query { 535 var $relation = ''; 536 var $queries = array(); 535 537 536 _set_tax_query_defaults( $tax_query ); 538 function __construct( &$tax_query ) { 539 if ( isset( $tax_query['relation'] ) && strtoupper( $tax_query['relation'] ) == 'OR' ) { 540 $this->relation = 'OR'; 541 } else { 542 $this->relation = 'AND'; 543 } 537 544 538 if ( strtoupper( $tax_query['relation'] ) == 'OR' ) { 539 $relation = 'OR'; 540 } else { 541 $relation = 'AND'; 542 } 545 $defaults = array( 546 'taxonomy' => '', 547 'terms' => array(), 548 'include_children' => true, 549 'field' => 'term_id', 550 'operator' => 'IN', 551 ); 543 552 544 foreach ( $tax_query as $query ) {545 if ( ! is_array( $query ) )546 continue;553 foreach ( $tax_query as $query ) { 554 if ( ! is_array( $query ) ) 555 continue; 547 556 548 extract($query );557 $query = array_merge( $defaults, $query ); 549 558 550 if ( ! taxonomy_exists( $taxonomy ) ) 551 return array( 'join' => '', 'where' => ' AND 0 = 1'); 559 $query['terms'] = (array) $query['terms']; 560 561 $this->queries[] = $query; 562 } 563 } 552 564 553 $terms = array_unique( (array) $terms ); 565 function get_sql( $primary_table, $primary_id_column ) { 566 global $wpdb; 554 567 555 if ( empty( $terms ) ) 556 continue; 568 $join = ''; 569 $where = array(); 570 $i = 0; 557 571 558 if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children) {559 _transform_terms( $terms, $taxonomy, $field, 'term_id');572 foreach ( $this->queries as $query ) { 573 extract( $query ); 560 574 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; 575 if ( ! taxonomy_exists( $taxonomy ) ) 576 return array( 'join' => '', 'where' => ' AND 0 = 1'); 567 577 568 _transform_terms( $terms, $taxonomy, 'term_id', 'term_taxonomy_id' ); 569 } 570 else { 571 _transform_terms( $terms, $taxonomy, $field, 'term_taxonomy_id' ); 572 } 578 $terms = array_unique( (array) $terms ); 573 579 574 if ( 'IN' == $operator ) { 580 if ( empty( $terms ) ) 581 continue; 575 582 576 if ( empty( $terms ) ) { 577 if ( 'OR' == $relation ) 578 continue; 579 else 580 return array( 'join' => '', 'where' => ' AND 0 = 1' ); 581 } 583 if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) { 584 $this->_transform_terms( $terms, $taxonomy, $field, 'term_id' ); 582 585 583 $terms = implode( ',', $terms ); 586 $children = array(); 587 foreach ( $terms as $term ) { 588 $children = array_merge( $children, get_term_children( $term, $taxonomy ) ); 589 $children[] = $term; 590 } 591 $terms = $children; 584 592 585 $alias = $i ? 'tt' . $i : $wpdb->term_relationships; 593 $this->_transform_terms( $terms, $taxonomy, 'term_id', 'term_taxonomy_id' ); 594 } 595 else { 596 $this->_transform_terms( $terms, $taxonomy, $field, 'term_taxonomy_id' ); 597 } 586 598 587 $join .= " INNER JOIN $wpdb->term_relationships"; 588 $join .= $i ? " AS $alias" : ''; 589 $join .= " ON ($primary_table.$primary_id_column = $alias.object_id)"; 599 if ( 'IN' == $operator ) { 590 600 591 $where[] = "$alias.term_taxonomy_id $operator ($terms)"; 592 } 593 elseif ( 'NOT IN' == $operator ) { 601 if ( empty( $terms ) ) { 602 if ( 'OR' == $relation ) 603 continue; 604 else 605 return array( 'join' => '', 'where' => ' AND 0 = 1' ); 606 } 594 607 595 if ( empty( $terms ) ) 596 continue; 608 $terms = implode( ',', $terms ); 597 609 598 $terms = implode( ',', $terms );610 $alias = $i ? 'tt' . $i : $wpdb->term_relationships; 599 611 600 $where[] = "$primary_table.$primary_id_column NOT IN ( 601 SELECT object_id 602 FROM $wpdb->term_relationships 603 WHERE term_taxonomy_id IN ($terms) 604 )"; 605 } 612 $join .= " INNER JOIN $wpdb->term_relationships"; 613 $join .= $i ? " AS $alias" : ''; 614 $join .= " ON ($primary_table.$primary_id_column = $alias.object_id)"; 606 615 607 $i++; 608 } 616 $where[] = "$alias.term_taxonomy_id $operator ($terms)"; 617 } 618 elseif ( 'NOT IN' == $operator ) { 609 619 610 if ( !empty( $where ) ) 611 $where = ' AND ( ' . implode( " $relation ", $where ) . ' )'; 612 else 613 $where = ''; 620 if ( empty( $terms ) ) 621 continue; 614 622 615 return compact( 'join', 'where' ); 616 } 623 $terms = implode( ',', $terms ); 617 624 618 function _set_tax_query_defaults( &$tax_query ) { 619 if ( ! isset( $tax_query['relation'] ) ) 620 $tax_query['relation'] = 'AND'; 625 $where[] = "$primary_table.$primary_id_column NOT IN ( 626 SELECT object_id 627 FROM $wpdb->term_relationships 628 WHERE term_taxonomy_id IN ($terms) 629 )"; 630 } 621 631 622 $defaults = array( 623 'taxonomy' => '', 624 'terms' => array(), 625 'include_children' => true, 626 'field' => 'term_id', 627 'operator' => 'IN', 628 ); 632 $i++; 633 } 629 634 630 foreach ( $tax_query as $i => $query ) { 631 if ( ! is_array( $query ) ) 632 continue; 635 if ( !empty( $where ) ) 636 $where = ' AND ( ' . implode( " $relation ", $where ) . ' )'; 637 else 638 $where = ''; 633 639 634 $tax_query[$i] = array_merge( $defaults, $query ); 635 636 $tax_query[$i]['terms'] = (array) $tax_query[$i]['terms']; 640 return compact( 'join', 'where' ); 637 641 } 638 }639 642 640 function _transform_terms( &$terms, $taxonomy, $field, $resulting_field ) {641 global $wpdb;643 function _transform_terms( &$terms, $taxonomy, $field, $resulting_field ) { 644 global $wpdb; 642 645 643 if ( empty( $terms ) )644 return;646 if ( empty( $terms ) ) 647 return; 645 648 646 if ( $field == $resulting_field )647 return;649 if ( $field == $resulting_field ) 650 return; 648 651 649 $resulting_field = esc_sql( $resulting_field );652 $resulting_field = esc_sql( $resulting_field ); 650 653 651 switch ( $field ) {652 case 'slug':653 case 'name':654 $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'";655 $terms = $wpdb->get_col( "656 SELECT $wpdb->term_taxonomy.$resulting_field657 FROM $wpdb->term_taxonomy658 INNER JOIN $wpdb->terms USING (term_id)659 WHERE taxonomy = '$taxonomy'660 AND $wpdb->terms.$field IN ($terms)661 " );662 break;654 switch ( $field ) { 655 case 'slug': 656 case 'name': 657 $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'"; 658 $terms = $wpdb->get_col( " 659 SELECT $wpdb->term_taxonomy.$resulting_field 660 FROM $wpdb->term_taxonomy 661 INNER JOIN $wpdb->terms USING (term_id) 662 WHERE taxonomy = '$taxonomy' 663 AND $wpdb->terms.$field IN ($terms) 664 " ); 665 break; 663 666 664 default: 665 $terms = implode( ',', array_map( 'intval', $terms ) ); 666 $terms = $wpdb->get_col( " 667 SELECT $resulting_field 668 FROM $wpdb->term_taxonomy 669 WHERE taxonomy = '$taxonomy' 670 AND term_id IN ($terms) 671 " ); 667 default: 668 $terms = implode( ',', array_map( 'intval', $terms ) ); 669 $terms = $wpdb->get_col( " 670 SELECT $resulting_field 671 FROM $wpdb->term_taxonomy 672 WHERE taxonomy = '$taxonomy' 673 AND term_id IN ($terms) 674 " ); 675 } 672 676 } 673 677 } 674 678 -
wp-includes/query.php
714 714 * 715 715 * @since 3.1.0 716 716 * @access public 717 * @var array717 * @var object WP_Tax_Query 718 718 */ 719 var $tax_query = array();719 var $tax_query; 720 720 721 721 /** 722 722 * Holds the data for a single object that is queried. … … 1584 1584 ); 1585 1585 } 1586 1586 1587 _set_tax_query_defaults( $tax_query );1587 $tax_query_obj = new WP_Tax_Query( $tax_query ); 1588 1588 1589 foreach ( $tax_query as $query ) { 1590 if ( ! is_array( $query ) ) 1591 continue; 1592 1589 foreach ( $tax_query_obj->queries as $query ) { 1593 1590 if ( 'IN' == $query['operator'] ) { 1594 1591 switch ( $query['taxonomy'] ) { 1595 1592 case 'category': … … 1604 1601 } 1605 1602 } 1606 1603 1607 return $tax_query ;1604 return $tax_query_obj; 1608 1605 } 1609 1606 1610 1607 /** … … 1942 1939 if ( $this->is_category || $this->is_tag || $this->is_tax ) { 1943 1940 $this->tax_query = $this->parse_tax_query( $q ); 1944 1941 1945 $clauses = call_user_func_array( 'get_tax_sql', array( $this->tax_query, $wpdb->posts, 'ID', &$this));1942 $clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' ); 1946 1943 1947 1944 $join .= $clauses['join']; 1948 1945 $where .= $clauses['where']; … … 1957 1954 } 1958 1955 1959 1956 // Back-compat 1960 $tax_query_in = wp_list_filter( $this->tax_query , array( 'operator' => 'IN' ) );1957 $tax_query_in = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'IN' ) ); 1961 1958 if ( !empty( $tax_query_in ) ) { 1962 1959 if ( !isset( $q['taxonomy'] ) ) { 1963 1960 foreach ( $tax_query_in as $a_tax_query ) { … … 2657 2654 $this->queried_object = NULL; 2658 2655 $this->queried_object_id = 0; 2659 2656 2660 $tax_query_in = wp_list_filter( $this->tax_query , array( 'operator' => 'IN' ) );2657 $tax_query_in = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'IN' ) ); 2661 2658 if ( !empty( $tax_query_in ) ) { 2662 2659 $query = reset( $tax_query_in ); 2663 2660 -
wp-includes/canonical.php
146 146 } elseif ( is_category() || is_tag() || is_tax() ) { // Terms (Tags/categories) 147 147 148 148 $term_count = 0; 149 foreach ( $wp_query->tax_query as $tax_query )149 foreach ( $wp_query->tax_query->queries as $tax_query ) 150 150 $term_count += count( $tax_query['terms'] ); 151 151 152 152 $obj = $wp_query->get_queried_object();