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-entry"><span 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="says">says:</span>', 'textdomain' ), get_comment_author_link() ); ?>
</div><!-- ment-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><!-- ment-meta -->
<div class="comment-text"><?php comment_text(); ?></div><!-- ment-text -->
<?php
// Display comment moderation text
if ( $comment->comment_approved == '0' ) { ?>
<em class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.', 'textdomain' ); ?></em><br/><?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><!-- ment-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.
}
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-entry"><span 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="says">says:</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' ); ?></em><br/><?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.
}
Share
Improve this question
edited Feb 5, 2022 at 13:57
Teymur Abbasov
asked Feb 4, 2022 at 18:00
Teymur AbbasovTeymur Abbasov
618 bronze badges
5
|
1 Answer
Reset to default 2You 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.
pre_get_comments
filter? – Tom J Nowell ♦ Commented Feb 4, 2022 at 18:53pre_get_comments
? You could easily filter the comment query to only fetch comments authored by you or the post author if you aren't the author. I also assume for anybody else reading that logged out users will see no comments at all? – Tom J Nowell ♦ Commented Feb 4, 2022 at 18:59