How to make comments private for commentor and post author

I am trying to make comments private. I mean comment must be visible for post author and comment author. I create custom comment section better-comment.php. I have used pre_get_comments but I can not make work. Please help

?php
// My custom comments output html
function better_comments( $comment, $args, $depth ) {

    // Get correct tag used for the comments
    if ( 'div' === $args['style'] ) {
        $tag       = 'div';
        $add_below = 'comment';
    } else {
        $tag       = 'li';
        $add_below = 'div-comment';
    } ?

    ?php echo $tag; ? ?php comment_class( empty( $args['has_children'] ) ? '' : 'parent' ); ? id=comment-?php comment_ID() ?

    ?php
    // Switch between different comment types
    switch ( $comment-comment_type ) :
        case 'pingback' :
        case 'trackback' : ?
        div class=pingback-entryspan class=pingback-heading?php esc_html_e( 'Pingback:', 'textdomain' ); ?/span ?php comment_author_link(); ?/div
    ?php
        break;
        default :

        if ( 'div' != $args['style'] ) { ?
            div id=div-comment-?php comment_ID() ? class=comment-body
        ?php } ?
            div class=comment-author vcard
                ?php
                // Display avatar unless size is set to 0
                if ( $args['avatar_size'] != 0 ) {
                    $avatar_size = ! empty( $args['avatar_size'] ) ? $args['avatar_size'] : 70; // set default avatar size
                        echo get_avatar( $comment, $avatar_size );
                }
                // Display author name
                printf( __( 'cite class=fn%s/cite span class=sayssays:/span', 'textdomain' ), get_comment_author_link() ); ?
            /div!-- .comment-author --
            div class=comment-details
                div class=comment-meta commentmetadata
                    a href=?php echo htmlspecialchars( get_comment_link( $comment-comment_ID ) ); ??php
                        /* translators: 1: date, 2: time */
                        printf(
                            __( '%1$s at %2$s', 'textdomain' ),
                            get_comment_date(),
                            get_comment_time()
                        ); ?
                    /a?php
                    edit_comment_link( __( '(Edit)', 'textdomain' ), '  ', '' ); ?
                /div!-- .comment-meta --
                div class=comment-text?php comment_text(); ?/div!-- .comment-text --
                ?php
                // Display comment moderation text
                if ( $comment-comment_approved == '0' ) { ?
                    em class=comment-awaiting-moderation?php _e( 'Your comment is awaiting moderation.', 'textdomain' ); ?/embr/?php
                } ?
                div class=reply?php
                // Display comment reply link
                comment_reply_link( array_merge( $args, array(
                    'add_below' = $add_below,
                    'depth'     = $depth,
                    'max_depth' = $args['max_depth']
                ) ) ); ?
                /div
            /div!-- .comment-details --
    ?php
        if ( 'div' != $args['style'] ) { ?
            /div
        ?php }
    // IMPORTANT: Note that we do NOT close the opening tag, WordPress does this for us
        break;
    endswitch; // End comment_type check.
}

Topic wp-comment-query comments-template private comment-form comments Wordpress

Category Web


You can use the pre_get_comments filter to modify the parameters of the comment query before it fetches the comments. Specifically the author_in parameter.

I tried to write an example, though I haven't tested it, but it would be similar to this:

add_action( 'pre_get_comments', 'author_and_self_comment_filter' );

function author_and_self_filter( \WP_Comment_Query $query ) : void {
    // We need to do some checks first and return early if
    // this filter doesn't apply, e.g. if you're the post
    // author etc

    // don't break the admin UI
    if ( is_admin() ) {
        return;
    }

    // only filter if we're grabbing the comments for a post
    if ( $query->query_vars['post_id'] === 0 ) {
        return;
    }

    // only logged in users should see comments
    if ( ! is_user_logged_in() ) {
        // we need to return 0 results so I'm asking for a
        // comment type that doesn't exist so there are no
        //results, there's probably a better way to do this:
        $query->query_vars['type'] = 'banana';
        return;
    }

    // this is already filtered to specific people! Skip!
    if ( ! empty( $query->query_vars['author__in'] ) ) {
        return;
    }

    // Admins + super admins see everything!
    if ( current_user_can( 'manage_options' ) || is_super_admin() ) {
        return;
    }

    // get my ID
    $my_user_id = get_current_user_id();

    // get the post author ID
    $post_id = $query->query_vars['post_id'];
    $p = get_post( $post_id );
    $post_author_id = $p->post_author;

    // If I'm the post author then I can see everything
    if ( $my_user_id === $post_author_id ) {
        return;
    }

    // now we need to set the `author_in` to an array with 2
    // values, the authors user ID and the current users ID
    $authors = [];
    $authors[] = $my_user_id; // My user ID
    $authors[] = $post_author_id; // Author ID
    $query->query_vars['author_in'] = $authors;
}

There's a series of checks to figure out if we need to do this or not, and then at the end we restrict comments to just the author and current user.

Note that comment counters will never be accurate if you do this and may be highly unreliable, there is no fix for this without undoing the restriction so all comments are visible to all users.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.