WordPress.org

Make WordPress Core

Changeset 30084


Ignore:
Timestamp:
10/29/14 02:21:10 (30 hours ago)
Author:
boonebgorges
Message:

Support multiple 'status' values in WP_Comment_Query.

This change required turning the SQL concatenation into the generation of an
array, for greater flexibility.

Props karpstrucking, ebinnion.
Fixes #29612.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/comment.php

    r30026 r30084  
    303303            'post_status' => '', 
    304304            'post_type' => '', 
    305             'status' => '', 
     305            'status' => 'all', 
    306306            'type' => '', 
    307307            'user_id' => '', 
     
    344344        } 
    345345 
     346        $where = array(); 
     347 
    346348        // Assemble clauses related to 'comment_approved'. 
    347349        $approved_clauses = array(); 
    348         $status = $this->query_vars['status']; 
    349         if ( 'hold' == $status ) { 
    350             $approved_clauses[] = "comment_approved = '0'"; 
    351         } elseif ( 'approve' == $status ) { 
    352             $approved_clauses[] = "comment_approved = '1'"; 
    353         } elseif ( ! empty( $status ) && 'all' != $status ) { 
    354             $approved_clauses[] = $wpdb->prepare( "comment_approved = %s", $status ); 
    355         } else { 
    356             $approved_clauses[] = "( comment_approved = '0' OR comment_approved = '1' )"; 
     350 
     351        // 'status' accepts an array or a comma-separated string. 
     352        $status_clauses = array(); 
     353        $statuses = $this->query_vars['status']; 
     354        if ( ! is_array( $statuses ) ) { 
     355            $statuses = preg_split( '/[\s,]+/', $statuses ); 
     356        } 
     357 
     358        // Remove empty statuses. 
     359        $statuses = array_filter( $statuses ); 
     360 
     361        // 'any' overrides other statuses. 
     362        if ( ! in_array( 'any', $statuses ) ) { 
     363            foreach ( $statuses as $status ) { 
     364                switch ( $status ) { 
     365                    case 'hold' : 
     366                        $status_clauses[] = "comment_approved = '0'"; 
     367                        break; 
     368 
     369                    case 'approve' : 
     370                        $status_clauses[] = "comment_approved = '1'"; 
     371                        break; 
     372 
     373                    case 'all' : 
     374                        $status_clauses[] = "( comment_approved = '0' OR comment_approved = '1' )"; 
     375                        break; 
     376 
     377                    default : 
     378                        $status_clauses[] = $wpdb->prepare( "comment_approved = %s", $status ); 
     379                        break; 
     380                } 
     381            } 
     382 
     383            if ( ! empty( $status_clauses ) ) { 
     384                $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )'; 
     385            } 
    357386        } 
    358387 
     
    380409 
    381410        // Collapse comment_approved clauses into a single OR-separated clause. 
    382         if ( 1 === count( $approved_clauses ) ) { 
    383             $approved = $approved_clauses[0]; 
    384         } else { 
    385             $approved = '( ' . implode( ' OR ', $approved_clauses ) . ' )'; 
     411        if ( ! empty( $approved_clauses ) ) { 
     412            if ( 1 === count( $approved_clauses ) ) { 
     413                $where[] = $approved_clauses[0]; 
     414            } else { 
     415                $where[] = '( ' . implode( ' OR ', $approved_clauses ) . ' )'; 
     416            } 
    386417        } 
    387418 
     
    458489 
    459490        $join = ''; 
    460         $where = $approved; 
    461491 
    462492        $post_id = absint( $this->query_vars['post_id'] ); 
    463493        if ( ! empty( $post_id ) ) { 
    464             $where .= $wpdb->prepare( ' AND comment_post_ID = %d', $post_id ); 
     494            $where[] = $wpdb->prepare( 'comment_post_ID = %d', $post_id ); 
    465495        } 
    466496 
    467497        // Parse comment IDs for an IN clause. 
    468498        if ( ! empty( $this->query_vars['comment__in'] ) ) { 
    469             $where .= ' AND comment_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__in'] ) ) . ' )'; 
     499            $where[] = 'comment_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__in'] ) ) . ' )'; 
    470500        } 
    471501 
    472502        // Parse comment IDs for a NOT IN clause. 
    473503        if ( ! empty( $this->query_vars['comment__not_in'] ) ) { 
    474             $where .= ' AND comment_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )'; 
     504            $where[] = 'comment_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )'; 
    475505        } 
    476506 
    477507        // Parse comment post IDs for an IN clause. 
    478508        if ( ! empty( $this->query_vars['post__in'] ) ) { 
    479             $where .= ' AND comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )'; 
     509            $where[] = 'comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )'; 
    480510        } 
    481511 
    482512        // Parse comment post IDs for a NOT IN clause. 
    483513        if ( ! empty( $this->query_vars['post__not_in'] ) ) { 
    484             $where .= ' AND comment_post_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__not_in'] ) ) . ' )'; 
     514            $where[] = 'comment_post_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__not_in'] ) ) . ' )'; 
    485515        } 
    486516 
    487517        if ( '' !== $this->query_vars['author_email'] ) { 
    488             $where .= $wpdb->prepare( ' AND comment_author_email = %s', $this->query_vars['author_email'] ); 
     518            $where[] = $wpdb->prepare( 'comment_author_email = %s', $this->query_vars['author_email'] ); 
    489519        } 
    490520 
    491521        if ( '' !== $this->query_vars['karma'] ) { 
    492             $where .= $wpdb->prepare( ' AND comment_karma = %d', $this->query_vars['karma'] ); 
     522            $where[] = $wpdb->prepare( 'comment_karma = %d', $this->query_vars['karma'] ); 
    493523        } 
    494524 
    495525        if ( 'comment' == $this->query_vars['type'] ) { 
    496             $where .= " AND comment_type = ''"; 
     526            $where[] = "comment_type = ''"; 
    497527        } elseif( 'pings' == $this->query_vars['type'] ) { 
    498             $where .= ' AND comment_type IN ("pingback", "trackback")'; 
     528            $where[] = 'comment_type IN ("pingback", "trackback")'; 
    499529        } elseif ( ! empty( $this->query_vars['type'] ) ) { 
    500             $where .= $wpdb->prepare( ' AND comment_type = %s', $this->query_vars['type'] ); 
     530            $where[] = $wpdb->prepare( 'comment_type = %s', $this->query_vars['type'] ); 
    501531        } 
    502532 
    503533        if ( '' !== $this->query_vars['parent'] ) { 
    504             $where .= $wpdb->prepare( ' AND comment_parent = %d', $this->query_vars['parent'] ); 
     534            $where[] = $wpdb->prepare( 'comment_parent = %d', $this->query_vars['parent'] ); 
    505535        } 
    506536 
    507537        if ( is_array( $this->query_vars['user_id'] ) ) { 
    508             $where .= ' AND user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')'; 
     538            $where[] = 'user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')'; 
    509539        } elseif ( '' !== $this->query_vars['user_id'] ) { 
    510             $where .= $wpdb->prepare( ' AND user_id = %d', $this->query_vars['user_id'] ); 
     540            $where[] = $wpdb->prepare( 'user_id = %d', $this->query_vars['user_id'] ); 
    511541        } 
    512542 
    513543        if ( '' !== $this->query_vars['search'] ) { 
    514             $where .= $this->get_search_sql( 
     544            $search_sql = $this->get_search_sql( 
    515545                $this->query_vars['search'], 
    516546                array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' ) 
    517547            ); 
     548 
     549            // Strip leading 'AND'. 
     550            $where[] = preg_replace( '/^\s*AND\s*/', '', $search_sql ); 
    518551        } 
    519552 
     
    526559            $join_posts_table = true; 
    527560            foreach ( $post_fields as $field_name => $field_value ) { 
    528                 $where .= $wpdb->prepare( " AND {$wpdb->posts}.{$field_name} = %s", $field_value ); 
     561                $where[] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} = %s", $field_value ); 
    529562            } 
    530563        } 
     
    532565        // Comment author IDs for an IN clause. 
    533566        if ( ! empty( $this->query_vars['author__in'] ) ) { 
    534             $where .= ' AND user_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__in'] ) ) . ' )'; 
     567            $where[] = 'user_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__in'] ) ) . ' )'; 
    535568        } 
    536569 
    537570        // Comment author IDs for a NOT IN clause. 
    538571        if ( ! empty( $this->query_vars['author__not_in'] ) ) { 
    539             $where .= ' AND user_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__not_in'] ) ) . ' )'; 
     572            $where[] = 'user_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__not_in'] ) ) . ' )'; 
    540573        } 
    541574 
     
    543576        if ( ! empty( $this->query_vars['post_author__in'] ) ) { 
    544577            $join_posts_table = true; 
    545             $where .= ' AND post_author IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__in'] ) ) . ' )'; 
     578            $where[] = 'post_author IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__in'] ) ) . ' )'; 
    546579        } 
    547580 
     
    549582        if ( ! empty( $this->query_vars['post_author__not_in'] ) ) { 
    550583            $join_posts_table = true; 
    551             $where .= ' AND post_author NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__not_in'] ) ) . ' )'; 
     584            $where[] = 'post_author NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__not_in'] ) ) . ' )'; 
    552585        } 
    553586 
     
    559592            $clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this ); 
    560593            $join .= $clauses['join']; 
    561             $where .= $clauses['where']; 
     594 
     595            // Strip leading 'AND'. 
     596            $where[] = preg_replace( '/^\s*AND\s*/', '', $clauses['where'] ); 
    562597 
    563598            if ( ! $this->query_vars['count'] ) { 
     
    569604        if ( ! empty( $date_query ) && is_array( $date_query ) ) { 
    570605            $date_query_object = new WP_Date_Query( $date_query, 'comment_date' ); 
    571             $where .= $date_query_object->get_sql(); 
    572         } 
     606            $where[] = preg_replace( '/^\s*AND\s*/', '', $date_query_object->get_sql() ); 
     607        } 
     608 
     609        $where = implode( ' AND ', $where ); 
    573610 
    574611        $pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits', 'groupby' ); 
     
    591628        $groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : ''; 
    592629 
     630        if ( $where ) { 
     631            $where = 'WHERE ' . $where; 
     632        } 
     633 
    593634        if ( $groupby ) { 
    594635            $groupby = 'GROUP BY ' . $groupby; 
     
    599640        } 
    600641 
    601         $this->request = "SELECT $fields FROM $wpdb->comments $join WHERE $where $groupby $orderby $limits"; 
     642        $this->request = "SELECT $fields FROM $wpdb->comments $join $where $groupby $orderby $limits"; 
    602643 
    603644        if ( $this->query_vars['count'] ) { 
  • trunk/tests/phpunit/tests/comment/query.php

    r30026 r30084  
    7474 
    7575        $this->assertEqualSets( array( $c1, $c3 ), $found ); 
     76    } 
     77 
     78    public function test_status_default_to_all() { 
     79        $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); 
     80        $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => 'foo' ) ); 
     81        $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '0' ) ); 
     82 
     83        $q = new WP_Comment_Query(); 
     84        $found = $q->query( array( 
     85            'fields' => 'ids', 
     86        ) ); 
     87 
     88        $this->assertEqualSets( array( $c1, $c3 ), $found ); 
     89    } 
     90 
     91    /** 
     92     * @ticket 29612 
     93     */ 
     94    public function test_status_comma_any() { 
     95        $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); 
     96        $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => 'foo' ) ); 
     97        $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '0' ) ); 
     98 
     99        $q = new WP_Comment_Query(); 
     100        $found = $q->query( array( 
     101            'status' => 'any', 
     102            'fields' => 'ids', 
     103        ) ); 
     104 
     105        $this->assertEqualSets( array( $c1, $c2, $c3 ), $found ); 
     106    } 
     107 
     108    /** 
     109     * @ticket 29612 
     110     */ 
     111    public function test_status_comma_separated() { 
     112        $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); 
     113        $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => 'foo' ) ); 
     114        $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '0' ) ); 
     115 
     116        $q = new WP_Comment_Query(); 
     117        $found = $q->query( array( 
     118            'status' => 'approve,foo,bar', 
     119            'fields' => 'ids', 
     120        ) ); 
     121 
     122        $this->assertEqualSets( array( $c1, $c2 ), $found ); 
     123    } 
     124 
     125    /** 
     126     * @ticket 29612 
     127     */ 
     128    public function test_status_array() { 
     129        $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); 
     130        $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => 'foo' ) ); 
     131        $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '0' ) ); 
     132 
     133        $q = new WP_Comment_Query(); 
     134        $found = $q->query( array( 
     135            'status' => array( 'approve', 'foo', 'bar', ), 
     136            'fields' => 'ids', 
     137        ) ); 
     138 
     139        $this->assertEqualSets( array( $c1, $c2 ), $found ); 
    76140    } 
    77141 
Note: See TracChangeset for help on using the changeset viewer.