Normally the code below works for my purpose.
I need to check if a post is in a certain category, check against user role and only allow user to see the page if the roles match
function bbrew_check_wholesaler(){
if( is_user_logged_in() ){
if(!check_is_role('myrole'){
wp_redirect($page_to_redirct_to);
exit;
}
}
else{
wp_redirect($page_to_redirct_to);
exit;
}
}
The helper function is
function check_is_role($role){
$current_user = wp_get_current_user();
$user_roles = $current_user->roles;
$user_role = $user_roles[0];
if($user_role == $role){
return true;
}else{
return false;
}
die;
}
Both the wp_loaded and init hooks do not have the global $post loaded either
Assuming you are in the front end, you can use template_redirect
hook to achieve what you want:
function bbrew_check_wholesaler() {
global $post;
/**
* If we are viewing a single post page that has the specified category "foobar"
* and the user does not have the specified role "myrole" then redirect the user
* away from this page.
*/
if ( is_single() && has_category('foobar', $post) && ! check_is_role('myrole') ) {
wp_safe_redirect(home_url('away-from-post'));
exit;
}
}
add_action( 'template_redirect', 'bbrew_check_wholesaler' );
Note: in the above example we can forgoe the use of is_user_logged_in()
as the subsequent call to wp_get_current_user()
will return an empty WP_User
object if the user is logged out.
I would adjust your check_is_role()
function to the following:
function check_is_role($role){
$current_user = wp_get_current_user();
if ( in_array($role, $current_user->roles )
return true;
} else {
return false;
}
}
…as the specified role you are checking for could exist anywhere within the array return on the roles
property and only at index 0.
You can further extend the above callback function with,
has_category()
has_tag()
has_term()
…in order to determine whether the post object has the specified term or terms required.