WordPress.org

Make WordPress Core

Changeset 17686


Ignore:
Timestamp:
04/22/2011 07:09:48 PM (7 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.