How to add post_distinct filter to WP_Comment_Query?

WordPress Development Asked by Jonathan Gruber on August 17, 2020

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.

2 Answers

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() ) {

// 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;

// That's about it

Answered by Lucian Davidescu on August 17, 2020

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(
            'widget_comments_args', array(
                'number'      => 1,
                'status'      => 'approve',
                'post_status' => 'publish',
                'offset'      => $i

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

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


// Sort by date
// @ to avoid this bug:
@usort($comments, function ($a, $b) {
    return get_the_date('U', $a->comment_post_ID) < get_the_date('U', $b->comment_post_ID);

Answered by Jonathan Gruber on August 17, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP