0

I have marked the option - " Users must be registered and logged in to comment " in Admin panel Setting -> Discussion section but i want only subscriber role user can comment not other roles type user.

Thanks,

1
  • Maybe this kind of approach can help?
    – birgire
    Commented Jul 13, 2016 at 9:36

3 Answers 3

0

I suggest adding a snippet to the theme file where the comments form is loaded that checks to make sure there is a logged in user and then, if that user a Subscriber, then show the comments form to them. The examples below use the Twenty Sixteen theme:

In comments.php:

// First, get the current user and check their role
$user = wp_get_current_user();
if ( in_array( 'subscriber', (array) $user->roles ) ) {
    // The current user has the subscriber role, show the form
    comment_form( array(
        'title_reply_before' => '<h2 id="reply-title" class="comment-reply-title">',
        'title_reply_after'  => '</h2>',
    ) );
}

This way, only those users with the subscriber role will see the comments form.

6
  • 1
    Sorry, but this show/hide the comment form for the frontend. That doesn't mean that only subscribers can comment. Maybe this one combined with @pallavi's answer could do the job.
    – cybmeta
    Commented Jul 13, 2016 at 11:08
  • @cybmeta While is true that my code does not disable commenting for the other roles, one cannot comment without access to the form. Without the form, commenting is not possible, and since this is doable via a theme php file rather than the functions file, it is less invasive. You could combine the two answers, yes, but that's just more code that might not be necessary. It depends, really, on how the OP wishes to proceed. Commented Jul 13, 2016 at 11:28
  • Sorry but you are wrong. Anyone can send data from the frontend with or without a form, even more, anyone can inject a form into your page. Remember that frontend can be totally manipulated without your control. You need to block it server-side; when comment data is received you need to check the role of the commenter, that is the only true way.
    – cybmeta
    Commented Jul 13, 2016 at 11:42
  • @cybmeta I would hope that there would be security in place to prevent things like basic injection and unauthorized requests would be dropped. And you don't want to JUST check the role on comment receipt because that's code being fired that doesn't need to be. Yes, it's good as a just-in-case, but if every comment is being moderated for role on submit, that's a bunch of work your back-end doesn't need to do. Again, it's up to the OP and his preference on approaches. He didn't ask for the most secure method, he just asked how. Commented Jul 13, 2016 at 11:57
  • I think you don't fully understand what I mean. It is not a security issue, it is just how internet and web applications works and you need to be aware about it. You need to check requests server-side. Again, your code hide a form but it doesn't mean that only "subscribers" are allowed to comment. Sorry but from my point of view it is not a good solution. If you want we can continue the discussion in chat room and I will explain it deeply.
    – cybmeta
    Commented Jul 13, 2016 at 12:03
1

It looks like the first time the core calls wp_get_current_user() is within the WP::init() method.

To better understand the context, we see that it's right after the after_setup_theme hook and just before the init hook src:

do_action( 'after_setup_theme' );

// Set up current user.
$GLOBALS['wp']->init();

do_action( 'init' );

where WP::init() is defined as src:

public function init() {
    wp_get_current_user();
}

The wp_get_current_user() is a wrapper for _wp_get_current_user() that contains calls to wp_set_current_user() in various ways, e.g. with wp_set_current_user(0) for logged-out users.

Here's one suggestion, hook into the set_current_user action within the wp_set_current_user():

/**
 * Comments only open for users with the 'subscriber' role
 */
add_action( 'set_current_user', function() use ( &$current_user )
{
   if(     $current_user instanceof \WP_User 
        && $current_user->exists() 
        && in_array( 'subscriber', (array) $current_user->roles, true ) 
    )
        return;

    add_filter( 'comments_open', '__return_false' );

} );

If the current user has the subscriber role then do nothing. For all other users or visitors the comments are forced closed.

I might be too cautious checking for the \WP_User object instance, but I keep it anyway, as it's possible to mess with the $current_user, as with many other things in WordPress ;-)

The reason for using $current_user here, instead of calling wp_get_current_user(), is to avoid a possible infinite loop, but there are ways to handle that if needed. It's also tempting to play with the determine_current_user filter.

For visitors (not logged in) the wp_get_current_user() will return a \WP_User object with ID as 0 and roles as an empty array. That's because of the wp_set_current_user(0) calls mentioned earlier.

Here $current_user->exists() is a wrapper for ! empty( $current_user->ID).

I agree with @TammyShipps regarding the array casting of the roles, but as noted by @cybmeta, only hiding the comment form will not stop other users from being able to comment.

Another approach is a little rewrite of my recent answer here:

/**
 * Comments only open for users with the 'subscriber' role
 */
add_action( 'init', function()
{
    $u = wp_get_current_user();

    if( $u->exists() && in_array( 'subscriber', (array) $u->roles, true ) )
        return;

    add_filter( 'comments_open', '__return_false' );
} );

Both of these methods should stop direct POST requests to the wp-comments-post.php file, because of the comments_open() check there. I haven't checked but I think it will also work with xml-rpc.

We might also try the pre_comment_on_post hook to stop the comment handling by e.g. throwing an \WP_Error.

0

The below code check if user is not subscriber then comment form will not display. Comment form only show when user is login and and user role is subscriber.

  add_filter( 'init', 'manage_comment');

    function manage_comment()
    {
     global $current_user;

     $user_roles = $current_user->roles;
     $user_role = array_shift($user_roles);
    if ($user_role!='subscriber')
    { 
     add_filter( 'comments_open', '__return_false' );
    } 
    }
1
  • Why??? Simply dumping code is bad, all code should be accompanied by some kind of explanation what the code does and how it works. For newbies, this is pretty useless Commented Jul 13, 2016 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.