WordPress.org

Make WordPress Core

Ticket #12891: 12891.diff

File 12891.diff, 7.1 KB (added by scribu, 8 years ago)

Start to pull tax SQL out of WP_Query and into _wp_tax_sql()

  • wp-includes/functions.php

     
    42934293}
    42944294
    42954295/*
     4296 * Used internally to generate an SQL string for searching across multiple taxonomies
     4297 *
     4298 * @access private
     4299 * @since 3.1.0
     4300 *
     4301 * @param array $queries An array of queries
     4302 * @return string SQL string
     4303 */
     4304function _wp_tax_sql( $queries ) {
     4305        global $wpdb;
     4306
     4307        $sql = array();
     4308        foreach ( $queries as $query ) {
     4309                $taxonomy = $query['taxonomy'];
     4310                $terms = (array) $query['terms'];
     4311                $field = $query['field'];
     4312
     4313                if ( !in_array( $field, array( 'term_id', 'slug', 'name' ) ) )
     4314                        $field = 'term_id';
     4315
     4316                $operator = $query['operator'];
     4317                if ( !in_array( $operator, array( 'IN', 'NOT IN' ) ) )
     4318                        $operator = 'IN';
     4319
     4320                switch ( $field ) {
     4321                        case 'term_id':
     4322                                $terms = implode( ',', array_map( 'intval', $terms ) );
     4323                                $terms = $wpdb->prepare( "
     4324                                        SELECT term_taxonomy_id
     4325                                        FROM $wpdb->term_taxonomy
     4326                                        WHERE taxonomy = %s
     4327                                        AND term_id IN ( $terms )
     4328                                ", $taxonomy );
     4329                        break;
     4330
     4331                        case 'slug':
     4332                        case 'name':
     4333                                $terms = "'" . implode( "','", esc_sql( $terms ) ) . "'";
     4334                                $terms = $wpdb->prepare( "
     4335                                        SELECT term_taxonomy_id
     4336                                        FROM $wpdb->term_taxonomy
     4337                                        INNER JOIN $wpdb->terms USING ( term_id )
     4338                                        WHERE taxonomy = %s
     4339                                        AND $field IN ( $terms )
     4340                                ", $taxonomy );
     4341                }
     4342
     4343                $sql[] = " AND term_taxonomy_id $operator ( $terms )";
     4344        }
     4345
     4346        return "SELECT object_id FROM $wpdb->term_relationships WHERE 1=1" .  implode( '', $sql );
     4347}
     4348
     4349/*
    42964350 * Used internally to tidy up the search terms
    42974351 *
    42984352 * @access private
  • wp-includes/query.php

     
    17801780                $search = apply_filters_ref_array('posts_search', array( $search, &$this ) );
    17811781
    17821782                // Category stuff
    1783 
    17841783                if ( empty($q['cat']) || ($q['cat'] == '0') ||
    17851784                                // Bypass cat checks if fetching specific posts
    17861785                                $this->is_singular ) {
     
    18081807                }
    18091808
    18101809                if ( !empty($q['category__in']) ) {
    1811                         $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
    1812                         $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'category' ";
    1813                         $include_cats = "'" . implode("', '", $q['category__in']) . "'";
    1814                         $whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_cats) ";
     1810                        $tax_query[] = array(
     1811                                'taxonomy' => 'category',
     1812                                'terms' => $q['category__in'],
     1813                                'operator' => 'IN',
     1814                                'field' => 'term_id'
     1815                        );
    18151816                }
    18161817
    18171818                if ( !empty($q['category__not_in']) ) {
    1818                         $cat_string = "'" . implode("', '", $q['category__not_in']) . "'";
    1819                         $whichcat .= " AND $wpdb->posts.ID NOT IN ( 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 = 'category' AND tt.term_id IN ($cat_string) )";
     1819                        $tax_query[] = array(
     1820                                'taxonomy' => 'category',
     1821                                'terms' => $q['category__not_in'],
     1822                                'operator' => 'NOT IN',
     1823                                'field' => 'term_id'
     1824                        );
    18201825                }
    18211826
    18221827                // Category stuff for nice URLs
     
    18451850
    18461851                        $q['cat'] = $reqcat;
    18471852
    1848                         $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
    1849                         $whichcat = " AND $wpdb->term_taxonomy.taxonomy = 'category' ";
    18501853                        $in_cats = array($q['cat']);
    18511854                        $in_cats = array_merge($in_cats, get_term_children($q['cat'], 'category'));
    1852                         $in_cats = "'" . implode("', '", $in_cats) . "'";
    1853                         $whichcat .= "AND $wpdb->term_taxonomy.term_id IN ($in_cats)";
    1854                         $groupby = "{$wpdb->posts}.ID";
     1855
     1856                        $tax_query[] = array(
     1857                                'taxonomy' => 'category',
     1858                                'terms' => $in_cats,
     1859                                'operator' => 'IN',
     1860                                'field' => 'term_id'
     1861                        );
    18551862                }
    18561863
    18571864                // Tags
     
    18741881                        }
    18751882                }
    18761883
    1877                 if ( !empty($q['category__in']) || !empty($q['meta_key']) || !empty($q['tag__in']) || !empty($q['tag_slug__in']) ) {
    1878                         $groupby = "{$wpdb->posts}.ID";
    1879                 }
     1884                if ( !empty($q['tag__in']) && empty($q['cat']) ) {
     1885                        $tax_query[] = array(
     1886                                'taxonomy' => 'post_tag',
     1887                                'terms' => $q['tag__in'],
     1888                                'operator' => 'IN',
     1889                                'field' => 'term_id'
     1890                        );
    18801891
    1881                 if ( !empty($q['tag__in']) && empty($q['cat']) ) {
    1882                         $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
    1883                         $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' ";
    1884                         $include_tags = "'" . implode("', '", $q['tag__in']) . "'";
    1885                         $whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_tags) ";
    18861892                        $reqtag = term_exists( $q['tag__in'][0], 'post_tag' );
    18871893                        if ( !empty($reqtag) )
    18881894                                $q['tag_id'] = $reqtag['term_id'];
    18891895                }
    18901896
    18911897                if ( !empty($q['tag_slug__in']) && empty($q['cat']) ) {
    1892                         $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) INNER JOIN $wpdb->terms ON ($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id) ";
    1893                         $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' ";
    1894                         $include_tags = "'" . implode("', '", $q['tag_slug__in']) . "'";
    1895                         $whichcat .= " AND $wpdb->terms.slug IN ($include_tags) ";
     1898                        $tax_query[] = array(
     1899                                'taxonomy' => 'post_tag',
     1900                                'terms' => $q['tag_slug__in'],
     1901                                'operator' => 'IN',
     1902                                'field' => 'slug'
     1903                        );
     1904
    18961905                        $reqtag = get_term_by( 'slug', $q['tag_slug__in'][0], 'post_tag' );
    18971906                        if ( !empty($reqtag) )
    18981907                                $q['tag_id'] = $reqtag->term_id;
    18991908                }
    19001909
    19011910                if ( !empty($q['tag__not_in']) ) {
    1902                         $tag_string = "'" . implode("', '", $q['tag__not_in']) . "'";
    1903                         $whichcat .= " AND $wpdb->posts.ID NOT IN ( 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 = 'post_tag' AND tt.term_id IN ($tag_string) )";
     1911                        $tax_query[] = array(
     1912                                'taxonomy' => 'post_tag',
     1913                                'terms' => $q['tag__not_in'],
     1914                                'operator' => 'NOT IN',
     1915                                'field' => 'term_id'
     1916                        );
    19041917                }
    19051918
     1919                if ( !empty( $tax_query ) ) {
     1920                        $tax_query_sql = _wp_tax_sql( $tax_query );
     1921
     1922                        $where .= " AND $wpdb->posts.ID IN( " . implode( ', ', $wpdb->get_col( $tax_query_sql ) ) . ")";
     1923                }
     1924
    19061925                // Tag and slug intersections.
    19071926                $intersections = array('category__and' => 'category', 'tag__and' => 'post_tag', 'tag_slug__and' => 'post_tag', 'tag__in' => 'post_tag', 'tag_slug__in' => 'post_tag');
    19081927                $tagin = array('tag__in', 'tag_slug__in'); // These are used to make some exceptions below
     
    19781997                        }
    19791998                }
    19801999
     2000                if ( !empty($q['meta_key']) ) {
     2001                        $groupby = "{$wpdb->posts}.ID";
     2002                }
     2003
    19812004                // Author/user stuff
    19822005
    19832006                if ( empty($q['author']) || ($q['author'] == '0') ) {