1

I want to fetch a list of posts with the most recent comments. However I don't wish to simply get the latest comments and have duplicate posts, but I want to group the posts (by their ID). I tried the following (ff it is important: the code is in the widget() methode of a widget class):

function distinct() {
    return "DISTINCT";
}
add_filter('posts_distinct', 'distinct');

$args = array(
    'number' => 8
);
$query = new WP_Comment_Query;
$comments = $query->query($args);

The posts_distinct filter seemed like the correct way to achieve this, but it is not called and does not work. A different approach with posts_groupby doesn't work either:

add_filter('posts_groupby', 'groupby' );
function groupby($groupby) {
    global $wpdb;
    $groupby = "{$wpdb->posts}.ID";
    return $groupby;
}

How can I make WP_Comment_Query to return 8 distinguished posts?

I know that I could simply use a raw SQL query, but after a hour of fruitless googling I really wonder, how to solve this problem the WP way.

  • posts_distinct and posts_groupby are filters of the WP_Query class, because of that they aren't going to alter the WP_Comment_Query you do. WP_Comment_Query won't return you posts, WP_Query will do that. – Nicolai Oct 6 '15 at 12:18
0

Okay, I understood by now, that get_comments() is only for ... well comments. The following is not very elegant, but it does work at least.

$i = 0;
while (count($comments) < $number) {
    $comment = get_comments(
        apply_filters(
            'widget_comments_args', array(
                'number'      => 1,
                'status'      => 'approve',
                'post_status' => 'publish',
                'offset'      => $i
            )
        )
    );

    if (!isset($comment[0]))
        break;

    $comment = $comment[0]; // unwrap
    $comments[$comment->comment_post_ID] = $comment;

    $i++;
}

// Sort by date
// @ to avoid this bug: https://bugs.php.net/bug.php?id=50688
@usort($comments, function ($a, $b) {
    return get_the_date('U', $a->comment_post_ID) < get_the_date('U', $b->comment_post_ID);
});
0

What you want can be done a bit easier.

Run the WP_comments_Query in the background to get an array of post IDs with their comment dates. Then use that array in a normal WP_Query. If you want the comment as well, you can then use the get_comments function. Here's an example:

// For performance, limit the number of queried comments, 
// but make it be something big enough to account for "duplicate" posts.

$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( array(   'number' => '100'  ) );

if ( $comments ) {
    foreach ( $comments as $comment ) {

// You'll want to convert the dates from string to integer so you can sort them out later
$comment_utf = strtotime($comment->comment_date);

// Build an array of post IDs with the date of the last published comment
$latest_comments[$comment->comment_post_ID] = $comment_utf;
    }}

// Sort the array by date
arsort($latest_comments); foreach ($latest_comments as $key => $value) {    $posts_ordered[] = $key; }

// The nice thing is that WP_Query will remove duplicates by default
$args = array ( 'posts_per_page'         => '10',   'post__in'  => $posts_ordered, 'orderby' => 'post__in');
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
    while ( $query->have_posts() ) {
        $query->the_post();

// Do your stuff (add the template or whatever)

// If you want to add the comment itself, use this:
$comments = get_comments(array('number' => '1', 'post_id' => $post->ID));
foreach($comments as $comment) :
    echo $comment->comment_content;
endforeach;

// That's about it
    }}
wp_reset_postdata();

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.