You can use the get_terms
hook to find all categories and restrict access to them by ID or slug, if the current user is not an admin, or in this specific case if the user doesn't have the role assigned by you.
add_filter('get_terms', 'restrict_categories');
function restrict_categories($categories) {
$onPostPage = (strpos($_SERVER['PHP_SELF'], 'post.php') || strpos($_SERVER['PHP_SELF'], 'post-new.php')); // check if we are in the new/edit post page
// if (is_admin() && $onPostPage && !current_user_can('level_10')) { // check for user capabilities - level_10 is admin
if (is_admin() && $onPostPage && themename_check_user_role( 'category_restricted' )) { // check for user role
$size = count($categories);
for ($i = 0; $i < $size; $i++) {
// if ($categories[$i]->slug != 'category_slug')
if ($categories[$i]->term_id != '1') // then restrict the categories by ID
unset($categories[$i]);
}
}
return $categories;
}
Credits for the code goes to: wptricks. I just remembered that I read about this a while ago.
Later edit:
You can try to pass a role to the current_user_can()
function but it's not guaranteed to work correctly, instead you can use the function below to check for user roles.
/**
* Checks if a particular user has a role.
* Returns true if a match was found.
*
* @param string $role Role name.
* @param int $user_id (Optional) The ID of a user. Defaults to the current user.
* @return bool
*/
function themename_check_user_role( $role, $user_id = null ) {
if ( is_numeric( $user_id ) )
$user = get_userdata( $user_id );
else
$user = wp_get_current_user();
if ( empty( $user ) )
return false;
return in_array( $role, (array) $user->roles );
}
// example use for the current user
if ( themename_check_user_role( 'customer' )
_e( "You've got access!", 'themename' );
else
_e( "Sorry, you don't have access!", 'themename' );
And as a side note, it is a good idea to include your add_role
function on theme/plugin activation.