• On my page I have some content which is only visible for certain user roles.
    I show the protected content to the user roles (‘member’ and ‘premium-members’) like this:

    $user                = wp_get_current_user();
    $allowed_all         = array( 'member', 'board' );
    $allowed_pemium_only = array( 'premium-members' );
    
    if ( array_intersect( $allowed_all, $user->roles ) ) { 
      echo 'Only visible to members and premium-members';
    } 
    
    if ( in_array( 'premium-member', $user->roles[0] ) ) {
      echo 'Only visible to premium members';
    } 

    When I search for a certain protected content (for example content that is only visible for premium-members), the content itself does not show up but the pages on which the particular content is found do even if I’m just a member or not logged in at all. So this indicates that on these particular pages the content I searched for could be found but is hidden.

    So my question is: Is there a filter or anything that can be used to strip out the search results that are hidden to certain user roles?

    Many thanks in advance for any help.

    • This topic was modified 4 years, 7 months ago by Chris.
Viewing 5 replies - 1 through 5 (of 5 total)
  • Plugin Author Mikko Saari

    (@msaari)

    The relevanssi_post_ok filter hook is what you need. It has two parameters, first a boolean value and second a post ID. Create a function on the hook that will return true if the current user is allowed to see the post specified by the post ID and false if not.

    Thread Starter Chris

    (@moargh)

    Hi Mikko,

    Many thanks for getting back to me so quickly and for your hint.

    I made progress but there’s one thing that I don’t figure out …
    So this is my current filter hook:

    add_filter( 'relevanssi_post_ok', 'rlv_allowed_user', 11, 2 );
    
    function rlv_allowed_user( $show, $post_id ) {
    
    	$user                = wp_get_current_user();
    	$allowed_all         = array( 'member', 'board' );
    	$allowed_pemium_only = array( 'premium-member' );
    
    	if ( in_array( 'acf/restricted', $block_names ) ) { 
    
    		// Do not show to non-premium users
    		if ( !( in_array( 'premium-member', $user->roles[0] ) ) ) {
    			$show = false;
    		}
    
    	}
    
    	return $show;
    
    }

    It says that if a user does not have the role “premium-member” no search results will be displayed. So that’s obviously not what I want. ??

    What I need is another a condition to check if the found result is limited to only be viewed by premium users. But I don’t know how to do that. It’s not that whole posts would not be visible to non-premium users but it’s just some snippets in these posts that are wrapped in if ( !( in_array( 'premium-member', $user->roles[0] ) ) ) {.

    Do you have another hint for me?
    Thanks a lot for your effort!

    Plugin Author Mikko Saari

    (@msaari)

    Ah, this approach doesn’t work for partial posts, this only applies to blocking or showing full posts. Blocking post parts is a much, much harder problem. Sorry, I didn’t understand that initially.

    The thing is – when Relevanssi indexes a post, the post is broken into individual words, which are stored in the index. When Relevanssi sees a word in the index, there’s no way to tell where in the post the word came from and no way to tell it’s from limited content that can’t be shown to the user.

    One approach could be to use relevanssi_match.

    add_filter( 'relevanssi_match', 'rlv_block_post_parts', 10, 3 );
    function rlv_block_post_parts( $match, $dontneedthis, $term ) {
        if ( $term is a restricted term ) {
            $user = wp_get_current_user();
            if ( ! in_array( 'premium-member', $user->roles[0], true ) ) {
                $match->weight = 0;
            }
        }
        return $match;
    }

    So if the current search term is in a restricted part of the post and the user is not a premium member, set the match weight to 0.

    But of course here checking if the $term only appears in a Gutenberg block that is restricted content is not easy, and also may simple be too heavy, since it would need to be done many, many times during each search. I’m afraid this is a problem where there is no easy or even reasonable solutions.

    Thread Starter Chris

    (@moargh)

    Thanks a lot for outlining this.

    I just read a bit through the relevanssi_match hook (https://www.relevanssi.com/knowledge-base/relevanssi-match/ and https://www.relevanssi.com/knowledge-base/using-customfield_detail/) and I was wondering if it would be possible when the restricted content would be in a certain custom field (ACF field), for example premium-user-content?

    add_filter('relevanssi_match', 'cfdetail');
    
    function cfdetail($match) {
    	global $customfield_data;
    	$customfield_data[$match->doc] = $match->customfield_detail;
    	return $match;
    }
    
    add_filter('relevanssi_match', 'rlv_cf_boost');
    
    function rlv_cf_boost( $match ) {
    
    	$user   = wp_get_current_user();
    	$detail = json_decode( $match->customfield_detail );
    	
    	if (!empty($detail)) {
    		if (isset($detail['premium-user-content'])) {
    
    			if ( ! in_array( 'premium-member', $user->roles[0], true ) ) {
    				$match->weight = 0;
    			}
        
    		}
    
    	}
    
    	return $match;
    	
    }

    Would that work with Relevanssi premium?
    I am very thankful for your time!

    • This reply was modified 4 years, 7 months ago by Chris.
    Plugin Author Mikko Saari

    (@msaari)

    Yes, that would make things much easier. That doesn’t necessarily require Premium because you can always look inside the custom field in the relevanssi_match filter function, but using the customfield_detail in Premium is better for performance than individually checking the custom field for every match.

    The cfdetail() function you have there does nothing and is unnecessary.

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘Show/Hide protected content based on user roles’ is closed to new replies.