I’m trying to setup a custom WP_Comment_Query
which is ordered by a meta key. (It might be worth mentioning that these comments are being retrieved with AJAX.)
It all works fine, until I add in pagination into the query args.
$orderby = 'top-comments';
$args = array(
'post_id' => $post_id,
'type' => 'comment',
'status' => 'approve',
'hierarchical' => true
);
if ( $orderby == 'top-comments' ) {
$args['meta_key'] = 'comment_rating';
$args['orderby'] = 'meta_value_num';
$args['order'] = 'ASC';
}
// $comments_query = new WP_Comment_Query;
// $comments = $comments_query->query($args);
// Works fine up until I add the pagination args
$number = 5;
$paged = 1;
$args['number'] = $number;
$args['paged'] = $paged;
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query($args);
// Gets the 5 latest comments, then orders those by meta_key
The results without the pagination args works perfect, and orders the comments exactly how I want it.
However, once the number argument is set, it will retrieve the newest 5 comments, and then order them by meta_key => 'comment_rating'
.
The behaviour I expect is WP_Comment_Query first applying the orderby, and then returning the top 5 results.
What am I doing wrong?
2 Answers
The goal was to paginate comments, showing comments with the highest comment_rating
meta value first.
Thanks to the answer of cjbj and the comments by Milo and birgire I figured out the rather unintuitive solution to the issue.
By using number
and offset
I was able to make the results in the proper order, but pagination was strange, and each 5 posts were seemingly “flipped” on every page.
Here is my workaround, resulting in a list of comments, starting with the highest rated first, and the lowest rated last.
$orderby = 'top-comments';
$args = array(
'post_id' => $post_id,
'type' => 'comment',
'status' => 'approve',
'hierarchical' => true
);
if ( $orderby == 'top-comments' ) {
$args['meta_key'] = 'comment_rating';
$args['orderby'] = 'meta_value_num';
$args['order'] = 'ASC';
}
// 5 Comments per page
$comments_per_page = $number = 5;
// Get the comment count to calculate the offset
$comment_count = wp_count_comments($post_id)->approved;
// Currently page 1 (set with AJAX in my case)
$page = 1;
// Rather unintuitively, we start with the total amount of comments and subtract
// from that number
// This is nessacary so that comments are displayed in the right order
// (highest rated at the top, lowest rated at the bottom)
// Calculate offset
$offset = $comments_count - ($comments_per_page * $page);
// Calculate offset for last page (to prevent comments being shown twice)
if ( $offset < 0 ) {
// Calculate remaining amount of comments (always less than 5)
$comments_last_page = $comments_count % $comments_per_page;
// New offset calculated from the amount of remaining comments
$offset = $offset + $comments_per_page - $comments_last_page;
// Set how many comments the last page shows
$number = $comments_last_page;
}
// Then we pass the $number and the $offset to our query args
$args['number'] = $number;
$args['offset'] = $offset;
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query($args);
// Result: 5 comments, starting with the highest rating at the top, and the
// lowest rated at the bottom