Is it possible to filter comments in a post so a user can only see the comments they have written?

Assuming your comment authors are intended to be registered users, the easiest way is probably to use a pre_get_comments action hook to modify the WP_Comment_Query object‘s user_id query var such that the query only returns comments from the current user:

function wpse262203_restrict_comment_views( $comments_query ) {
  // Don't interfere with comment results in the dashboard
  if( is_admin() )
    return;

  $current_user = wp_get_current_user(); // Get the current user

  if( $current_user instanceof WP_User && is_user_logged_in() ) {
    // The visitor is logged in as a WordPress user...

    // If they're an administrator, don't filter the comments
    if( in_array( 'administrator', $current_user->roles ) )
      return;

    // Otherwise, restrict queried comments to those authored by this user.
    $comments_query->query_vars[ 'user_id' ] = $current_user->ID;
  }
  else {
    // The visitor isn't logged in - make sure no comments are queried.
    $comments_query->query_vars[ 'comment__in' ] = array(0);
  }
}

add_action( 'pre_get_comments', 'wpse262203_restrict_comment_views' );

You can also use current_user_can() instead of/in addition to checking for user roles to tailor who comments are filtered for.

While you can also support anonymous commenting by using wp_get_current_commenter() in conjunction with the author_email WP_Comment_Query argument, this isn’t terribly reliable or secure. Anonymous commenter ID data is stored in cookies, meaning the user can clear it or the cookies could expire – in which case the user would be unable to view their comments until they post another. The credentials are also fairly easily spoofed – crafty visitors could potentially gain access to comments from other users.


EDIT – Why this wasn’t working, previously

After further investigation, my earlier attempts to use WP_Comment_Query::set() to change query variables was failing because as it turns out, WP_Comment_Query does not actually have a set() method, unlike it’s WP_Query counterpart (see ticket #39120). It does however have a __call() “Magic Method”, which was intercepting the call to the non-existent set() method and returning false, thus preventing the error which PHP would have normally thrown and confusing me to no end.

Leave a Comment