query – Restrict users to see only own comments and the post author’s replies

Question

I’ve chosen to use the default WP comments as private messages between readers/users and post authors, so that users are restricted to only seeing their own comments and the post author’s replies. After some research I ended up with two different functions, one using the comments_array filter and the other the pre_get_comments action.

The first (comments_array) works very well, exactly as expected. But the second (pre_get_comments) can’t filter post author comments/replies that are not related to the current user comments. However, I would prefer to use the `pre_get_comments’, assuming that from a performance point of view, especially when a post has a lot of comments, it must be faster. Am I right or wrong?

So, my question is what can be done to make the second function lead to the same result as the first?

Or, an idea that comes to mind, should I use both? Any suggestions?

The first function:

add_filter( 'comments_array', function( $comments ) {

    if( ! is_singular( 'advert' ) || empty( $comments ) 
        || ! is_main_query() || ! in_the_loop() ) { return $comments; }

    $current_user = wp_get_current_user();

    if( ! is_user_logged_in() // don't show comments for not logged in users
        || ! ( $current_user instanceof WP_User ) ) { return array( 0 ); }

    $author_id = (int) get_the_author_meta( 'ID' );

    // don't filter if administrator or post author
    if( in_array( 'administrator', $current_user->roles ) 
        || $current_user->ID === $author_id ) { return $comments; }

    $user_ids = array();

    foreach( $comments as $index => $comment ) {
        $user_ids[$comment->comment_ID] = (int) $comment->user_id; // get comment user IDs
        $parent_id = (int) $comment->comment_parent;               // get ID of parent comment

        if( ! ( $current_user->ID === (int) $comment->user_id      // if user is not the comment author
            || ( $parent_id > 0                                    // and not the author of parent comment
                && $current_user->ID === $user_ids[$parent_id] ) ) // HOW THIS WORKS??? I came to this intuitively.
        ) {
            unset( $comments[$index] ); // unset comment
        }
    }

    return $comments;
} );

The second function:

add_action( 'pre_get_comments', function( $query ) {

    if( is_admin() || ! is_singular( 'advert' ) 
        || ! is_main_query() || ! in_the_loop() ) { return; }

    $current_user = wp_get_current_user();

    // no comments are queried for not logged in users
    if( ! is_user_logged_in() || ! ( $current_user instanceof WP_User ) ) { 
        $query->query_vars['comment__in'] = array( 0 );
    }

    $author_id = (int) get_the_author_meta( 'ID' );

    // don't change anything if administrator or post author
    if( in_array( 'administrator', $current_user->roles ) 
        || $current_user->ID === $author_id ) { return; }

    $authors = array();
    $authors[] = $current_user->ID;
    $authors[] = $author_id;
    $query->query_vars['author__in'] = $authors;
} );

0
Iurie 2 months 2023-04-02T14:18:49-05:00 0 Answers 0 views 0

Leave an answer

Browse
Browse