WordPress.org

Make WordPress Core

Ticket #12891: 12891.diff

File 12891.diff, 7.1 KB (added by scribu, 5 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') ) {