Make WordPress Core

Ticket #29612: 29612.patch

File 29612.patch, 12.6 KB (added by boonebgorges, 11 years ago)
  • src/wp-includes/comment.php

    diff --git src/wp-includes/comment.php src/wp-includes/comment.php
    index f374675..5d4076e 100644
    class WP_Comment_Query { 
    293293                        'post_parent' => '',
    294294                        'post_status' => '',
    295295                        'post_type' => '',
    296                         'status' => '',
     296                        'status' => 'all',
    297297                        'type' => '',
    298298                        'user_id' => '',
    299299                        'search' => '',
    class WP_Comment_Query { 
    334334                        return $cache;
    335335                }
    336336
     337                $where = array();
     338
    337339                // Assemble clauses related to 'comment_approved'.
    338340                $approved_clauses = array();
    339                 $status = $this->query_vars['status'];
    340                 if ( 'hold' == $status ) {
    341                         $approved_clauses[] = "comment_approved = '0'";
    342                 } elseif ( 'approve' == $status ) {
    343                         $approved_clauses[] = "comment_approved = '1'";
    344                 } elseif ( ! empty( $status ) && 'all' != $status ) {
    345                         $approved_clauses[] = $wpdb->prepare( "comment_approved = %s", $status );
    346                 } else {
    347                         $approved_clauses[] = "( comment_approved = '0' OR comment_approved = '1' )";
     341
     342                // 'status' accepts an array or a comma-separated string.
     343                $status_clauses = array();
     344                $statuses = $this->query_vars['status'];
     345                if ( ! is_array( $statuses ) ) {
     346                        $statuses = preg_split( '/[\s,]+/', $statuses );
     347                }
     348
     349                // Remove empty statuses.
     350                $statuses = array_filter( $statuses );
     351
     352                // 'any' overrides other statuses.
     353                if ( ! in_array( 'any', $statuses ) ) {
     354                        foreach ( $statuses as $status ) {
     355                                switch ( $status ) {
     356                                        case 'hold' :
     357                                                $status_clauses[] = "comment_approved = '0'";
     358                                                break;
     359
     360                                        case 'approve' :
     361                                                $status_clauses[] = "comment_approved = '1'";
     362                                                break;
     363
     364                                        case 'all' :
     365                                                $status_clauses[] = "( comment_approved = '0' OR comment_approved = '1' )";
     366                                                break;
     367
     368                                        default :
     369                                                $status_clauses[] = $wpdb->prepare( "comment_approved = %s", $status );
     370                                                break;
     371                                }
     372                        }
     373
     374                        if ( ! empty( $status_clauses ) ) {
     375                                $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )';
     376                        }
    348377                }
    349378
    350379                // User IDs or emails whose unapproved comments are included, regardless of $status.
    class WP_Comment_Query { 
    370399                }
    371400
    372401                // Collapse comment_approved clauses into a single OR-separated clause.
    373                 if ( 1 === count( $approved_clauses ) ) {
    374                         $approved = $approved_clauses[0];
    375                 } else {
    376                         $approved = '( ' . implode( ' OR ', $approved_clauses ) . ' )';
     402                if ( ! empty( $approved_clauses ) ) {
     403                        if ( 1 === count( $approved_clauses ) ) {
     404                                $where[] = $approved_clauses[0];
     405                        } else {
     406                                $where[] = '( ' . implode( ' OR ', $approved_clauses ) . ' )';
     407                        }
    377408                }
    378409
    379410                $order = ( 'ASC' == strtoupper( $this->query_vars['order'] ) ) ? 'ASC' : 'DESC';
    class WP_Comment_Query { 
    445476                }
    446477
    447478                $join = '';
    448                 $where = $approved;
    449479
    450480                $post_id = absint( $this->query_vars['post_id'] );
    451481                if ( ! empty( $post_id ) ) {
    452                         $where .= $wpdb->prepare( ' AND comment_post_ID = %d', $post_id );
     482                        $where[] = $wpdb->prepare( 'comment_post_ID = %d', $post_id );
    453483                }
    454484
    455485                // Parse comment IDs for an IN clause.
    456486                if ( ! empty( $this->query_vars['comment__in'] ) ) {
    457                         $where .= ' AND comment_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__in'] ) ) . ' )';
     487                        $where[] = 'comment_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__in'] ) ) . ' )';
    458488                }
    459489
    460490                // Parse comment IDs for a NOT IN clause.
    461491                if ( ! empty( $this->query_vars['comment__not_in'] ) ) {
    462                         $where .= ' AND comment_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )';
     492                        $where[] = 'comment_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )';
    463493                }
    464494
    465495                // Parse comment post IDs for an IN clause.
    466496                if ( ! empty( $this->query_vars['post__in'] ) ) {
    467                         $where .= ' AND comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )';
     497                        $where[] = 'comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )';
    468498                }
    469499
    470500                // Parse comment post IDs for a NOT IN clause.
    471501                if ( ! empty( $this->query_vars['post__not_in'] ) ) {
    472                         $where .= ' AND comment_post_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__not_in'] ) ) . ' )';
     502                        $where[] = 'comment_post_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__not_in'] ) ) . ' )';
    473503                }
    474504
    475505                if ( '' !== $this->query_vars['author_email'] ) {
    476                         $where .= $wpdb->prepare( ' AND comment_author_email = %s', $this->query_vars['author_email'] );
     506                        $where[] = $wpdb->prepare( 'comment_author_email = %s', $this->query_vars['author_email'] );
    477507                }
    478508
    479509                if ( '' !== $this->query_vars['karma'] ) {
    480                         $where .= $wpdb->prepare( ' AND comment_karma = %d', $this->query_vars['karma'] );
     510                        $where[] = $wpdb->prepare( 'comment_karma = %d', $this->query_vars['karma'] );
    481511                }
    482512
    483513                if ( 'comment' == $this->query_vars['type'] ) {
    484                         $where .= " AND comment_type = ''";
     514                        $where[] = "comment_type = ''";
    485515                } elseif( 'pings' == $this->query_vars['type'] ) {
    486                         $where .= ' AND comment_type IN ("pingback", "trackback")';
     516                        $where[] = 'comment_type IN ("pingback", "trackback")';
    487517                } elseif ( ! empty( $this->query_vars['type'] ) ) {
    488                         $where .= $wpdb->prepare( ' AND comment_type = %s', $this->query_vars['type'] );
     518                        $where[] = $wpdb->prepare( 'comment_type = %s', $this->query_vars['type'] );
    489519                }
    490520
    491521                if ( '' !== $this->query_vars['parent'] ) {
    492                         $where .= $wpdb->prepare( ' AND comment_parent = %d', $this->query_vars['parent'] );
     522                        $where[] = $wpdb->prepare( 'comment_parent = %d', $this->query_vars['parent'] );
    493523                }
    494524
    495525                if ( is_array( $this->query_vars['user_id'] ) ) {
    496                         $where .= ' AND user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')';
     526                        $where[] = 'user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')';
    497527                } elseif ( '' !== $this->query_vars['user_id'] ) {
    498                         $where .= $wpdb->prepare( ' AND user_id = %d', $this->query_vars['user_id'] );
     528                        $where[] = $wpdb->prepare( 'user_id = %d', $this->query_vars['user_id'] );
    499529                }
    500530
    501531                if ( '' !== $this->query_vars['search'] ) {
    502                         $where .= $this->get_search_sql(
     532                        $search_sql = $this->get_search_sql(
    503533                                $this->query_vars['search'],
    504534                                array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' )
    505535                        );
     536
     537                        // Strip leading 'AND'.
     538                        $where[] = preg_replace( '/^\s*AND\s*/', '', $search_sql );
    506539                }
    507540
    508541                // If any post-related query vars are passed, join the posts table.
    class WP_Comment_Query { 
    513546                if ( ! empty( $post_fields ) ) {
    514547                        $join_posts_table = true;
    515548                        foreach ( $post_fields as $field_name => $field_value ) {
    516                                 $where .= $wpdb->prepare( " AND {$wpdb->posts}.{$field_name} = %s", $field_value );
     549                                $where[] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} = %s", $field_value );
    517550                        }
    518551                }
    519552
    520553                // Comment author IDs for an IN clause.
    521554                if ( ! empty( $this->query_vars['author__in'] ) ) {
    522                         $where .= ' AND user_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__in'] ) ) . ' )';
     555                        $where[] = 'user_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__in'] ) ) . ' )';
    523556                }
    524557
    525558                // Comment author IDs for a NOT IN clause.
    526559                if ( ! empty( $this->query_vars['author__not_in'] ) ) {
    527                         $where .= ' AND user_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__not_in'] ) ) . ' )';
     560                        $where[] = 'user_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__not_in'] ) ) . ' )';
    528561                }
    529562
    530563                // Post author IDs for an IN clause.
    531564                if ( ! empty( $this->query_vars['post_author__in'] ) ) {
    532565                        $join_posts_table = true;
    533                         $where .= ' AND post_author IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__in'] ) ) . ' )';
     566                        $where[] = 'post_author IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__in'] ) ) . ' )';
    534567                }
    535568
    536569                // Post author IDs for a NOT IN clause.
    537570                if ( ! empty( $this->query_vars['post_author__not_in'] ) ) {
    538571                        $join_posts_table = true;
    539                         $where .= ' AND post_author NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__not_in'] ) ) . ' )';
     572                        $where[] = 'post_author NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__not_in'] ) ) . ' )';
    540573                }
    541574
    542575                if ( $join_posts_table ) {
    class WP_Comment_Query { 
    546579                if ( ! empty( $this->meta_query->queries ) ) {
    547580                        $clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this );
    548581                        $join .= $clauses['join'];
    549                         $where .= $clauses['where'];
     582
     583                        // Strip leading 'AND'.
     584                        $where[] = preg_replace( '/^\s*AND\s*/', '', $clauses['where'] );
     585
    550586                        $groupby = "{$wpdb->comments}.comment_ID";
    551587                }
    552588
    553589                $date_query = $this->query_vars['date_query'];
    554590                if ( ! empty( $date_query ) && is_array( $date_query ) ) {
    555591                        $date_query_object = new WP_Date_Query( $date_query, 'comment_date' );
    556                         $where .= $date_query_object->get_sql();
     592                        // Strip leading 'AND'.
     593                        $where[] = preg_replace( '/^\s*AND\s*/', '', $date_query_object->get_sql() );
    557594                }
    558595
     596                $where = implode( ' AND ', $where );
     597
    559598                $pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits', 'groupby' );
    560599                /**
    561600                 * Filter the comment query clauses.
    class WP_Comment_Query { 
    575614                $limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
    576615                $groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';
    577616
     617                if ( $where ) {
     618                        $where = 'WHERE ' . $where;
     619                }
     620
    578621                if ( $groupby ) {
    579622                        $groupby = 'GROUP BY ' . $groupby;
    580623                }
    581                 $query = "SELECT $fields FROM $wpdb->comments $join WHERE $where $groupby ORDER BY $orderby $order $limits";
     624
     625                $query = "SELECT $fields FROM $wpdb->comments $join $where $groupby ORDER BY $orderby $order $limits";
    582626
    583627                if ( $this->query_vars['count'] ) {
    584628                        return $wpdb->get_var( $query );
  • tests/phpunit/tests/comment/query.php

    diff --git tests/phpunit/tests/comment/query.php tests/phpunit/tests/comment/query.php
    index 61f39ac..be9136b 100644
    class Tests_Comment_Query extends WP_UnitTestCase { 
    7575                $this->assertEqualSets( array( $c1, $c3 ), $found );
    7676        }
    7777
     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 );
     140        }
     141
    78142        function test_get_comments_for_post() {
    79143                $post_id = $this->factory->post->create();
    80144                $this->factory->comment->create_post_comments( $post_id, 10 );