最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

filters - Why anything done on comments_array hook gets reset?

programmeradmin1浏览0评论

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.

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.

Share Improve this question asked Oct 15, 2020 at 11:57 Michał KuczekMichał Kuczek 1233 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 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);
    }
}

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.

发布评论

评论列表(0)

  1. 暂无评论