I am writing a plugin that will allow simple comment upvoting.
I am trying to sort comments by the number of upvotes. But anything I do on the comments_array Hook gets somehow reset. My question is where and how?
Here is my code:
add_filter( 'comments_array', 'biiird_order_comments_by_likes' );
function biiird_order_comments_by_likes( $array ) {
$arraya = $array;
usort($arraya, function($a, $b) {
$likes_a = get_comment_meta( $a->comment_ID, 'likes', true );
$likes_b = get_comment_meta( $b->comment_ID, 'likes', true );
return ($likes_a > $likes_b) ? -1 : 1;
});
foreach ( $arraya as $comment ) {
$comment->comment_content .= 'something';
}
var_dump($arraya);
var_dump($array);
return $arraya;
}
The var_dump($arraya) outputs a modified array in the proper order, but the comments show on a page as if the filter was not run.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
This is not a bug.
If you look at the comment starting at line 2100 of wp/wp-includes/comment-template.php in the wp_list_comments function, you’ll see that if the per_page argument is set and its value is different to that of the main wp_query, it’ll perform a separate comment query and display those, instead of the ones you have sorted.
To get around this you’ll need to create a custom walker and pass that to the wp_list_comments function and perform the sorting there:
wp_list_comments(['walker' => new MySortingCommentWalker()]);
Given that you are writing a plugin, you could use the wp_list_comments_args filter to ensure your custom walker is always used:
add_filter('wp_list_comments_args', function($args) {
$args['walker'] = new MySortingCommentWalker();
return $args;
});
You could extend the default Walker_Comment class, override the paged_walk method and sort the comments in there. Once sorted you can pass them to the parent method:
class MySortingCommentWalker extends Walker_Comment
{
public function paged_walk($elements, $max_depth, $page_num, $per_page, ...$args)
{
// Pass $elements to your sorting function here
return parent::paged_walk($elements, $max_depth, $page_num, $per_page, $args);
}
}
Method 2
I think I have found a bug in wordpress, the thing that is causing the problem is the 'per_page' argument passed in wp_list_comments(). If it is set, then changes made to comments_array hook get reset or omitted later in the wp core.
I am 90% sure it’s a bug and I have reported it on wordpress trac.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0