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,
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,
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.
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
.
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' );
}
}