2

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.

0

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);
    }
}
1
  • wow, Thanks! Do you maybe have a recommendation for someone (maybe you) who would like to mentor me in wp dev? I am willing to pay for 15min video mentoring a week. I am looking for someone, but people I asked so far say that they don't know how to explain/teach. (I also removed my bug report) – Michał Kuczek Oct 15 '20 at 17:58
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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