Is it possible to limit the categories so that user in a list of groups does not see these posts at all? Not even in a list of posts?
I'm using the answer from here:
Only show category to certain user levels without plugin
My Code:
###########
// restrikcija posameznih kategorij za grupo ki je subscriber
// source:
add_filter('template_include', 'restict_by_category');
function check_user() {
$user = wp_get_current_user();
$restricted_groups = array( 'company1', 'company2', 'company3', 'subscriber' ); // categories subscribers cannot see
if ( ! $user->ID || array_intersect( $restricted_groups, $user->roles ) ) {
// user is not logged or is a subscriber
return false;
}
return true;
}
function restict_by_category( $template ) {
if ( ! is_main_query() ) {
return $template; // only affect main query.
}
$allow = true;
$private_categories = array( 'podjetje', 'personal', 'nekategorizirano', 'razno', 'sola-2' ); // categories subscribers cannot see
if ( is_single() ) {
$cats = wp_get_object_terms( get_queried_object()->ID, 'category', array('fields' => 'slugs') ); // get the categories associated to the required post
if ( array_intersect( $private_categories, $cats ) ) {
// post has a reserved category, let's check user
$allow = check_user();
}
} elseif ( is_tax('category', $private_categories) ) {
// the archive for one of private categories is required, let's check user
$allow = check_user();
}
// if allowed include the required template, otherwise include the 'not-allowed' one
return $allow ? $template : get_home_url(); //get_template_directory() . '/not-allowed.php';
}
###########
The problem is that user still sees post in a list of posts, but when clicked upon it's content is empty (which is OK, but even better would be that it doesnt sees posts at all).
And also if I have a master category with lots of sub-categorys, is it possible to also limit all these child categories?
Is it possible to limit the categories so that user in a list of groups does not see these posts at all? Not even in a list of posts?
I'm using the answer from here:
Only show category to certain user levels without plugin
My Code:
###########
// restrikcija posameznih kategorij za grupo ki je subscriber
// source: https://wordpress.stackexchange/questions/113500/only-show-category-to-certain-user-levels-without-plugin
add_filter('template_include', 'restict_by_category');
function check_user() {
$user = wp_get_current_user();
$restricted_groups = array( 'company1', 'company2', 'company3', 'subscriber' ); // categories subscribers cannot see
if ( ! $user->ID || array_intersect( $restricted_groups, $user->roles ) ) {
// user is not logged or is a subscriber
return false;
}
return true;
}
function restict_by_category( $template ) {
if ( ! is_main_query() ) {
return $template; // only affect main query.
}
$allow = true;
$private_categories = array( 'podjetje', 'personal', 'nekategorizirano', 'razno', 'sola-2' ); // categories subscribers cannot see
if ( is_single() ) {
$cats = wp_get_object_terms( get_queried_object()->ID, 'category', array('fields' => 'slugs') ); // get the categories associated to the required post
if ( array_intersect( $private_categories, $cats ) ) {
// post has a reserved category, let's check user
$allow = check_user();
}
} elseif ( is_tax('category', $private_categories) ) {
// the archive for one of private categories is required, let's check user
$allow = check_user();
}
// if allowed include the required template, otherwise include the 'not-allowed' one
return $allow ? $template : get_home_url(); //get_template_directory() . '/not-allowed.php';
}
###########
The problem is that user still sees post in a list of posts, but when clicked upon it's content is empty (which is OK, but even better would be that it doesnt sees posts at all).
And also if I have a master category with lots of sub-categorys, is it possible to also limit all these child categories?
Problem with your code is that you don't modify queries at all in any way, so all queries on your site still get these posts - so they are visible on lists. And later, you use template_include
filter which allows you to redirect single post view and single category archive if it shouldn't be visible for given user... Also redirecting to home page in such case isn't best - it may confuse users...
So how to hide these posts properly, so users won't see them at all?
You should use pre_get_posts
filter. This way you can check if current user can see these posts and hide them, if he shouldn't.
function check_user() {
if ( ! get_current_user_id() ) { // this way you won't get notices when user is not logged in
return false;
}
$user = wp_get_current_user();
$restricted_groups = array('company1', 'company2', 'company3', 'subscriber'); // categories subscribers cannot see
if ( array_intersect( $restricted_groups, $user->roles ) ) {
// user is a subscriber or restricted user
return false;
}
return true;
}
function restrict_users_categories( $query ) {
if ( ! is_admin() ) {
if ( ! check_user() ) {
// change 1, 2, 3 to IDs of your excluded categories
$cats_excluded = array_merge( array(1, 2, 3), (array)$query->get( 'category__not_in' ) ); // don't ignore any other excluded categories
$query->set( 'category__not_in', $cats_excluded );
}
}
}
add_action( 'pre_get_posts', 'restrict_users_categories' );
Also... There is something a little bit odd in your check_user
function... If you want to check if user has one of these roles 'company1', 'company2', and so on, then it's OK.
But if you want to restrict only subscribers, then it should be:
function check_user() {
if ( ! get_current_user_id() ) { // this way you won't get notices when user is not logged in
return false;
}
$user = wp_get_current_user();
if ( in_array( 'subscriber', $user->roles ) ) {
// user is a subscriber
return false;
}
return true;
}
You need to hide those categories in your WP_Query
calls. using the pre_get_posts
hook will allow you to hide posts in those categories wherever you want. In the function below I'm hiding them everywhere except for admin pages unless your user_check()
function returns true. Modify as you like.
add_action( 'pre_get_posts', 'hide_private_cats', 10);
function hide_private_cats($query) {
if (is_admin() || check_user()) { // If this is an admin page or your user check passes, do nothing
return;
} else {
$query->set('category__not_in', array( 3, 8, 10 )); // don't show posts that are in the categories specified (only takes IDs)
}
}