Retrieving Comments With WP_Comment_Query In WordPress

Ever since WordPress implemented custom post types a whiles back, the use of WP_Query to retrieve posts based on custom criteria has become standard practice. Listing comments has not become so widespread for some reason, despite the availability of the WP_Comment_Query class.

WP_Comment_Query allows theme and plugin authors to retireve post comments using a standardized interface. The days of ugly direct database queries are gone. We can now use modular and readable arguments to do our bidding.

Why Should We List Comments?

You might be thinking: why? The programmer in me would answer: because we can! This seems a little silly, but there is a deeper meaning hidden there. A framework is only any good if it is flexible and modular. A modular framework should allow wasy and standardized access to its information. Being able to retrieve comments according to your custom criteria is a part of this mindset.

The pragmatist in me looks to specific use-cases to answer the question. Using WP_Comment_Query you can build a page where users can browse your site comments according to date, popularity and custom featured comments.

If you’re building user profiles you may want to show a particular user’s comments, or comments related to a user’s favorited articles.

How WP_Comment_Query Works

A comment query is usually used in conjunction with a loop that lists the comments that are retrieved. A full implementation of a query and loop would look something like this:


// Arguments for the query
$args = array();

// The comment query
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );

// The comment loop
if ( !empty( $comments ) ) {
    foreach ( $comments as $comment ) {
        echo '<p>' . $comment->comment_content . '</p>';
    }
} else {
    echo 'No comments found.';
}

As you can see it isn’t too complicated. The only things we need to be aware of are the arguments we can use that are passed to the query() method on row 6.

Restricting Comments By Post

The most obvious way of restricting comments to a certain post is to use the post_id parameter. By supplying a post’s ID you can make sure only comments related to that post appear.

You could also list comments based on multiple posts. This could be useful if you want to show comments for two very closely related posts. In this case supply an array of post IDs to the post__in parameter.


$related_posts = array( 12, 833, 229, 38 );
$args = array(
    'post__in' => $related_posts
);
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );

There are a bunch of post-related properties you can use, here’s a shortlist:

  • post_id: Retrieves comments for a specific ID
  • post__in: Retrieves comments for an array of posts
  • post__not_in: Retrieves comments for all posts except those in the supplied array
  • post_status: Retrieves comments for posts with the given status
  • post_type: Retrieves comments for the given post type
  • post_name: Post name to retrieve comments for
  • post_parent: Retrive comments for posts with the given parent

You can choose to mix an match these parameters of course. You could retrieve comments for all posts which have a specific parent but are not in a given set:


$unwanted = array( 3, 6, 10 );
$args = array(
    'post__not_in' => $unwanted,
    'post_parent' => 223
);
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );

Restricting Comments By Author

Similarly to post restrictions you can use the user_id parameter to list a specific user’s comments. You can also use author__in and author__not_in to provide inclusion/exlcusion arrays.

Another great method of listing comments is to use author email addresses. Many comments will be submitted by non-registered users, in which case grabbing them by email is easy:


$email = array( 'awesomecommenter@email.com' );
$args = array(
    'author_email' => $email
);
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );

To recap let’s go through all the user parameters again:

  • user_id: Retrieves comments by a specific user
  • author__in: Retrieves comments by a set of users
  • author__not_in: Retrieves all comments except from the given users
  • author_email: Retrieves comments by user with the given email

Other Simple Comment Restrictions

There are a bunch of comment-based restrictions you can add, from dates to comment types and searches. Here’s a full list with some examples below:

  • comment__in: Retrieves comments with the given IDs
  • comment__not_in: Retrieves all comments except ones with the given IDs
  • include_unapproved: Retrieved comments will include unapproved ones from the given users (ID or email)
  • karma: Karma score to retrieve comments for
  • search: Retrieve comments which match the given search string
  • status: Retrieve comments with the given status (accepts: hold, approve, all or custom status)
  • type: The comment type to return ( comment, pings or custom type )
  • type__in: Retrieves comments from the given types
  • type__not_in: Retrieves comments excluding the given types

Using these parameters we could list a custom comment type which contains the term “kazoo”.


$args = array(
    'type' => 'review',
    'search' => 'kazoo'
);
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );

Date Based Queries

WP_Comment_Query supports date based restrictions using WP_Date_Query which is used in regular post queries as well. This class allows you do add flexible date restrictions to any query easily, here’s an example:


$args = array(
    'type' => 'review',
    'date_query' => array(
        array(
            'after'     => 'January 1st, 2014',
            'before'    => array(
                'year'  => 2014,
                'month' => 7,
                'day'   => 01,
            ),
        ),
    ),
);

$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );

The date query is an array of arrays containing information that describes a date interval. This one is pretty self explanatory and shows how you can supply a date as text, or as an array. In the end, this query will return all comments posted in the first half of 2014.

You can use the WP_Date_Query class to grab posts from a single date, from a range or combine it with other parameters to get comments posted a week ago and modified within the past 2 days.

Regretfully this class doesn’t have very good documentation on its own. You can find a bunch of examples in the date parameters for WP_Query.

Meta Queries

Meta queries are powerful parameters that allow you to constrict results based on the data in the comment_meta table. This is extremely useful for custom implementations where comments are used for reviews for example.


$args = array(
    'type' => 'review',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => 'design',
            'value' => '4',
            'type' => 'numeric',
            'compare' => '>='
        ),
        array(
            'key' => 'features',
            'value' => '4',
            'type' => 'numeric',
            'compare' => '>='
        )
    )
);
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );

This example shows how you can query for reviews which rated the product and features 4 or better. As you can see, multiple meta queries were added. The relation parameter dictates how the query takes these into account. An AND type relation makes sure both are true, an OR type relation makes sure at least one is true.

This is followed by two arrays which define the meta key, it’s value, and how we are comparing it. The value may also be an array if you are using a proper comparison operator (IN,NOT IN,BETWEEN,NOT BETWEEN,EXISTSorNOT EXISTS).

The type can also be important, especially in distinguishing between text and numbers. The following are available: NUMERIC, BINARY, CHAR, DATE, DATETIME, DECIMAL, SIGNED, TIME, UNSIGNED.

Ordering And Returning Data

There are a couple of parameters that help us organize returned results, limit their number and determine exactly what data is returned for our comments. Here’s a quick list with all of them:

  • count: Set to true to return a comment count or false to return an array of comments
  • fields: Set to ids to return comment ID only or false to grab everything
  • number: Sets the number of comments to return
  • offset: Use an offset when grabbing comments from the database
  • orderby: The database column to order the comments by
  • order: Sets the direction of ordering – ASC or DESC

Using the parameters above we could limit our results to the second three reviews ordered by the meta_value for the rating:


$args = array(
    'type' => 'review',
    'meta_key' => 'rating',
    'orderby' => 'meta_value',
    'offset' => 3
);
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );

Problems With WP_Comment_Query

As a quick aside I thought I’d mention an issue with this class: inconsistency. You may frequently hear that the WordPress codebase is a mess. This is a bit of an exageration but the state of WP_Comment_Query is a good example of the truth in it.

This class was made to look like WP_Query but it really isn’t. When you list posts you use a loop with function like have_posts() and the_post(). With WP_Comment_Query you use a regular loop. It would be better if we could use the same format with have_comments() and the_comment().

Parameters are also all over the place. The documentation doesn’t list all of them and there are tons of duplicate parameters as well. Take a look at the source code for the full list.

You can get authors with post_author__in or author__in. The include_unapproved property is completely misleading, status does not have a status__in type parameter and the parent parameter really should be called comment_parent to fall in line with WP_Query. Not to mention that WP_Query itself should be named WP_Post_Query to maximize modularity.

Conclusion

Criticisms aside, WP_Comment_Query is a great class for grabbing comments according to your own needs. It makes listing comments a lot easier, especially if you have some custom functionality in there.

I strongly recommend familiarizing yourself with the date and meta queries, these are the same in the regular WP_Query as well so you can re-use your knowledge there.

If you have a particularly awesome implementation of your comments that uses WP_Comment_Query let us know in the comments below!

Daniel Pataki

Hallo, my name is Daniel :) I build plugins, themes and apps - then proceed to write or talk about them. When not coding or writing you'll find me playing board games or running with my dog. Drop me a line on Twitter or visit my personal website.