Limiting search results by user role

5 Replies ·

  1. My client has an online training system with different roles that have access to different courses/lessons. All works very well.

    When searching, however, lower-level roles shouldn’t see results that are restricted to higher roles. For instance, Area Presidents have three extra courses that Consultants do not have access to. But if I log in as a Consultant, then do a search on a keyword like “principle,” the results show me all of the courses that have that in their title or content (instead of the excerpt, though, a result shows “Sorry, but you do not have permission to view this content”). I’d like them to NOT see those courses at all in the search results, though.

    I’ve tried the Relevanssi plugin, thinking it might help with this, but although I like its search function a lot, it does not help with this particular issue. I’m thinking this issue might be resolved with a function? But I’m wary about messing it all up.

    [In other info, I also have Nav Menu Roles plugin so that the Consultant users can’t even see the listing of courses at the Area President level on menus. The training site uses LearnDash and its array of add-ons.]

    Thank you for any help!

  2. Justin Tadlock

    We’ve covered this in a previous topic here in the forums. It’s probably worth a read through some of that discussion to understand what’s going on a bit.

    I’m just copying the following code from that topic and adding a check for whether we’re currently viewing the search results page. You’ll want to drop the code into your theme’s functions.php or a custom plugin file.

    Basically, the code checks:

    • If the user is logged in, it’ll only show posts that they’re allowed to see.
    • If the user is logged out, it’ll only show posts with no permissions set.
    add_action( 'pre_get_posts', 'my_pre_get_posts' );
    
    function my_pre_get_posts( $query ) {
    
        // Bail early if not a search query.
        if ( ! is_search() )
            return;
    
        if ( is_user_logged_in() ) {
    
            $user = new WP_User( get_current_user_id() );
    
            $meta_query = array(
                'relation' => 'OR',
                array(
                    'key'    => '_members_access_role',
                    'compare' => 'NOT EXISTS',
                ),
                array(
                    'key'    => '_members_access_role',
                    'value'   => $user->roles[0],
                    'compare' => '!='
                )
            );
        } else {
    
            $meta_query = array(
                array(
                    'key'    => '_members_access_role',
                    'compare' => 'NOT EXISTS'
                )
            );
        }
    
        $query->set( 'meta_query', $meta_query );
    }
    
  3. Justin Tadlock

    I do want to note that the code likely won’t work with any custom search plugins installed. Many of them will overwrite the page query. So, make sure you have Relevanssi or anything else disabled.

  4. LeahGrrl

    I think this is a more complex issue than I thought. The code above doesn’t limit the search results (I’ve placed it in the child theme functions.php file [Genesis is the parent]) to only what a user can see even when I disable Relevanssi. I suspect there’s another plugin, of the many installed, that’s interfering. Suppose I’d better start that arduous process of figuring out what it is. Thank you for your help, and I will keep trying….

  5. LeahGrrl

    Okay, I got some help from Relevanssi’s creator and I thought I’d pass it on to you for reference. (He was super responsive and helpful, like you are!)

    Here’s the code that works:

    add_filter( 'relevanssi_post_ok', 'rlv_members', 10, 2 );
    function rlv_members( $post_ok, $post_id ) {
        if ( ! members_can_current_user_view_post( $post_id ) ) {
            $post_ok = false;
        }
        return $post_ok;
    }
    

    Hope this could help someone else using Members and Relevanssi.