custom taxonomy - Limit categories and it's subcategories for specific group of users

admin2025-06-04  1

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?

Share Improve this question edited Jan 24, 2019 at 6:15 Kashif Rafique 2351 gold badge3 silver badges12 bronze badges asked Jan 23, 2019 at 16:43 KikiKiki 1033 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

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)
    }
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1748980363a315349.html

最新回复(0)