WordPress.org

Make WordPress Core

Changeset 17686


Ignore:
Timestamp:
04/22/11 19:09:48 (3 years ago)
Author:
ryan
Message:

Handle term intersection requests containg inexistent terms. Props scribu. fixes #17194

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/taxonomy.php

    r17652 r17686  
    540540     *      Default: 'term_id' 
    541541     * - 'operator' string (optional) 
    542      *      Possible values: 'IN' and 'NOT IN'. 
     542     *      Possible values: 'AND', 'IN' or 'NOT IN'. 
    543543     *      Default: 'IN' 
    544544     * - 'include_children' bool (optional) Whether to include child terms. 
     
    549549     * @var array 
    550550     */ 
    551     var $queries = array(); 
     551    public $queries = array(); 
    552552 
    553553    /** 
     
    558558     * @var string 
    559559     */ 
    560     var $relation; 
     560    public $relation; 
    561561 
    562562    /** 
    563      * PHP4 type constructor. 
     563     * Standard response when the query should not return any rows. 
     564     * 
     565     * @since 3.2.0 
     566     * @access private 
     567     * @var string 
     568     */ 
     569    private static $no_results = array( 'join' => '', 'where' => ' AND 0 = 1' ); 
     570 
     571    /** 
     572     * Constructor. 
    564573     * 
    565574     * Parses a compact tax query and sets defaults. 
     
    582591     *    ), 
    583592     *  ) 
    584      * 
    585      * @return WP_Tax_Query 
    586593     */ 
    587     function WP_Tax_Query( $tax_query ) { 
     594    public function __construct( $tax_query ) { 
    588595        if ( isset( $tax_query['relation'] ) && strtoupper( $tax_query['relation'] ) == 'OR' ) { 
    589596            $this->relation = 'OR'; 
     
    622629     * @return array 
    623630     */ 
    624     function get_sql( $primary_table, $primary_id_column ) { 
     631    public function get_sql( $primary_table, $primary_id_column ) { 
    625632        global $wpdb; 
    626633 
     
    630637 
    631638        foreach ( $this->queries as $query ) { 
     639            $this->clean_query( $query ); 
     640 
     641            if ( is_wp_error( $query ) ) { 
     642                return self::$no_results; 
     643            } 
     644 
    632645            extract( $query ); 
    633  
    634             if ( ! taxonomy_exists( $taxonomy ) ) 
    635                 return array( 'join' => '', 'where' => ' AND 0 = 1'); 
    636  
    637             $terms = array_unique( (array) $terms ); 
    638  
    639             if ( empty( $terms ) ) 
    640                 continue; 
    641  
    642             if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) { 
    643                 $this->_transform_terms( $terms, $taxonomy, $field, 'term_id' ); 
    644  
    645                 $children = array(); 
    646                 foreach ( $terms as $term ) { 
    647                     $children = array_merge( $children, get_term_children( $term, $taxonomy ) ); 
    648                     $children[] = $term; 
    649                 } 
    650                 $terms = $children; 
    651  
    652                 $this->_transform_terms( $terms, $taxonomy, 'term_id', 'term_taxonomy_id' ); 
    653             } 
    654             else { 
    655                 $this->_transform_terms( $terms, $taxonomy, $field, 'term_taxonomy_id' ); 
    656             } 
    657646 
    658647            if ( 'IN' == $operator ) { 
     
    662651                        continue; 
    663652                    else 
    664                         return array( 'join' => '', 'where' => ' AND 0 = 1' ); 
     653                        return self::$no_results; 
    665654                } 
    666655 
     
    715704 
    716705    /** 
    717      * Transforms a list of terms, from one field to another. 
     706     * Validates a single query. 
    718707     * 
    719      * @since 3.1.0 
     708     * @since 3.2.0 
    720709     * @access private 
    721710     * 
    722      * @param array &$terms The list of terms 
    723      * @param string $taxonomy The taxonomy of the terms 
    724      * @param string $field The initial field 
     711     * @param array &$query The single query 
     712     */ 
     713    private function clean_query( &$query ) { 
     714        if ( ! taxonomy_exists( $query['taxonomy'] ) ) { 
     715            $query = new WP_Error( 'Invalid taxonomy' ); 
     716            return; 
     717        } 
     718 
     719        $query['terms'] = array_unique( (array) $query['terms'] ); 
     720 
     721        if ( is_taxonomy_hierarchical( $query['taxonomy'] ) && $query['include_children'] ) { 
     722            $this->transform_query( $query, 'term_id' ); 
     723 
     724            if ( is_wp_error( $query ) ) 
     725                return; 
     726 
     727            $children = array(); 
     728            foreach ( $query['terms'] as $term ) { 
     729                $children = array_merge( $children, get_term_children( $term, $query['taxonomy'] ) ); 
     730                $children[] = $term; 
     731            } 
     732            $query['terms'] = $children; 
     733        } 
     734 
     735        $this->transform_query( $query, 'term_taxonomy_id' ); 
     736    } 
     737 
     738    /** 
     739     * Transforms a single query, from one field to another. 
     740     * 
     741     * @since 3.2.0 
     742     * @access private 
     743     * 
     744     * @param array &$query The single query 
    725745     * @param string $resulting_field The resulting field 
    726746     */ 
    727     function _transform_terms( &$terms, $taxonomy, $field, $resulting_field ) { 
     747    private function transform_query( &$query, $resulting_field ) { 
    728748        global $wpdb; 
    729749 
    730         if ( empty( $terms ) ) 
     750        if ( empty( $query['terms'] ) ) 
    731751            return; 
    732752 
    733         if ( $field == $resulting_field ) 
     753        if ( $query['field'] == $resulting_field ) 
    734754            return; 
    735755 
    736756        $resulting_field = esc_sql( $resulting_field ); 
    737757 
    738         switch ( $field ) { 
     758        switch ( $query['field'] ) { 
    739759            case 'slug': 
    740760            case 'name': 
    741                 $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'"; 
     761                $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $query['terms'] ) ) . "'"; 
    742762                $terms = $wpdb->get_col( " 
    743763                    SELECT $wpdb->term_taxonomy.$resulting_field 
    744764                    FROM $wpdb->term_taxonomy 
    745765                    INNER JOIN $wpdb->terms USING (term_id) 
    746                     WHERE taxonomy = '$taxonomy' 
    747                     AND $wpdb->terms.$field IN ($terms) 
     766                    WHERE taxonomy = '{$query['taxonomy']}' 
     767                    AND $wpdb->terms.{$query['field']} IN ($terms) 
    748768                " ); 
    749769                break; 
    750770 
    751771            default: 
    752                 $terms = implode( ',', array_map( 'intval', $terms ) ); 
     772                $terms = implode( ',', array_map( 'intval', $query['terms'] ) ); 
    753773                $terms = $wpdb->get_col( " 
    754774                    SELECT $resulting_field 
    755775                    FROM $wpdb->term_taxonomy 
    756                     WHERE taxonomy = '$taxonomy' 
     776                    WHERE taxonomy = '{$query['taxonomy']}' 
    757777                    AND term_id IN ($terms) 
    758778                " ); 
    759779        } 
     780 
     781        if ( 'AND' == $query['operator'] && count( $terms ) < count( $query['terms'] ) ) { 
     782            $query = new WP_Error( 'Inexistent terms' ); 
     783            return; 
     784        } 
     785 
     786        $query['terms'] = $terms; 
     787        $query['field'] = $resulting_field; 
    760788    } 
    761789} 
Note: See TracChangeset for help on using the changeset viewer.