1

Whatever I tried so far didn't work. So I started looking everywhere for a few days now, trying to figure out how to order comments by the title of the post they are made into. (I tried a meta_value also, but it seems I didn't do it right). I read the wp codex. Here is what I am trying to make sort comments by post title, but there is no title or post_title parameter for the orderby of comments. Any help will be appreciated.

<?php $args = array(
    'status' => 'approve',
    'post_status' => 'publish',
    'post_type' => 'post',
    'orderby' => 'title',
    'order' => 'DESC'
);

$comments_query = new WP_Comment_Query; ?>
1
  • Do you think this is possible?
    – prosti
    Commented Feb 9, 2017 at 0:35

1 Answer 1

1

The WP_Comment_Query class supports ordering by:

'comment_agent',
'comment_approved', 
'comment_author',
'comment_author_email', 
'comment_author_IP',
'comment_author_url', 
'comment_content', 
'comment_date',
'comment_date_gmt', 
'comment_ID', 
'comment_karma',
'comment_parent', 
'comment_post_ID', 
'comment_type',
'user_id', 
'comment__in', 
'meta_value', 
'meta_value_num',

There's a way to adjust it via filters so we can support ordering by the post title:

$args = [
    'status'       => 'approve',
    'post_status'  => 'publish',
    'post_type'    => 'post',
    'orderby'      => '_post_title', // <-- Our custom orderby value
    'order'        => 'DESC'
];

$comment_query = new WP_Comment_Query( $args ); 

A simple demo plugin to support the _post_title ordering could be in PHP 7:

/**
 * Adjust orderby comments clause
 */

add_filter( 'comments_clauses', function( $clauses, \WP_Comment_Query $cq ) use ( &$wpdb )
{   
    $qv      = $cq->query_vars;
    $orderby = $qv['orderby'] ?? '';
    $order   = $qv['order'] ?? 'ASC';

    if( 
           '_post_title' === $orderby 
        && in_array( strtoupper( $order ), [ 'ASC', 'DESC' ], true ) 
    )
        $clauses[ 'orderby' ] = " {$wpdb->posts}.post_title {$order},
            {$wpdb->comments}.comment_ID {$order} "; 


    return $clauses;
}, 10, 2 );

and then to make sure the posts table is joined to the comment table, we can set the post type parameter to 'post' if it's missing:

/**
 * Make usre we have the posts table joined by making sure the post_type isn't empty.
 */

add_action( 'pre_get_comments', function( \WP_Comment_Query $cq )
{
    $qv      = &$cq->query_vars;
    $orderby = $qv['orderby'] ?? '';

    if( '_post_title' === $orderby && empty( $qv['post_type'] ) )
        $qv['post_type'] = 'post';

} );

Note that this kind of query:

SELECT  wp_comments.comment_ID 
    FROM wp_comments JOIN wp_posts ON wp_posts.ID = wp_comments.comment_post_ID     
    WHERE ( comment_approved = '1' ) 
        AND  wp_posts.post_status IN ('publish') 
        AND  wp_posts.post_type IN ('post')  
    ORDER BY  wp_posts.post_title DESC, wp_comments.comment_ID DESC  

is not efficient as it uses temporary and filesort.

Hope you can adjust it further to your needs.

3
  • First of all I want to greatly thank you for taking the time to give an answer! Sadly, the server uses PHP 5.6 and it gives me a status of 500 (Internal Server Error)
    – the.matrix
    Commented Feb 9, 2017 at 22:54
  • I used the null coalescing operator ?? from PHP 7+ to make it simpler. You can easily rewrite it with e.g. $orderby = isset( $qv['orderby'] ) ? $qv['orderby'] : ''; @the.matrix
    – birgire
    Commented Feb 10, 2017 at 8:37
  • you're welcome, glad to hear it helped @the.matrix
    – birgire
    Commented Feb 10, 2017 at 10:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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