3

I wish to hide certain posts for anyone that is not logged in. I tried the Restrict Content (RC) plugin but that did only hide the content of posts, i wish to omit the post completely.

Using RC as a foundation i tried the following:

function hideFromUnknownUsers($postObject) {
    $rcUserLevel = get_post_meta ( $postObject->ID, 'rcUserLevel', true );

    if(have_posts())
    {
        if (!(
                !current_user_can ( 'read' ) &&
                (
                    $rcUserLevel == 'Administrator' ||
                    $rcUserLevel == 'Editor' ||
                    $rcUserLevel == 'Author' ||
                    $rcUserLevel == 'Contributor' ||
                    $rcUserLevel == 'Subscriber'
                )
            )) {
            the_post();
        }
    }
}

add_action ( 'the_post', 'hideFromUnknownUsers' );

This has a systematic downside. The last post can not be ignored. I can however live with that for now. Another problem is that this also causes an infinite loop, repeating the same posts over and over again. I found that this is because the have_posts() does not only tell us that the end of the last post has been reached but has the side effect that the post counter is also reset preventing my main loop from reaching its end. Making a have_posts() that are non invasive proved difficult since i could not figure out how to reach the $wp_query->current_postand $wp_query->post_count from the plugin.

One solution would be having the above logic directly in the themes PHP files but that would have to be repeated everywhere i intend to access a post making it cumbersome and prone to errors.

Is there any other way to hide certain posts from unknown users?

  • why would this have to be repeated everywhere if you try to describe it with PHP logic ? is_user_logged_in() worked fine for me – Fafanellu Apr 28 '16 at 20:11
  • I would have to repeat the logic in all pages where i access posts, right? The function is_user_logged_in sounds great for replacing the RC parts. Where did you use it? – Enok82 Apr 28 '16 at 20:40
  • Welcome to the WordPress Development community, @Enok82! Questions regarding 3rd-party products are considered off-topic as they require very intimate knowledge of the product in order to answer objectively - they tend to be best addressed in the product's official support channels. Please review the "How to Ask" page in our help center for more details on what makes a question a good fit for our community. I've provided a basic approach below to accomplish your desired outcome without 3rd party products. – bosco Apr 29 '16 at 3:12
  • here is a link that might be useful for you : developer.wordpress.org/reference/functions/is_user_logged_in for the repeating of the logic, it depends on what you plan to do, actually it depends on what you call "certain posts". – Fafanellu Apr 29 '16 at 7:56
  • Thank you for the welcoming, unfortunately a bad cold and holidays has kept med from these (word)pressing matters. I figured that any deep knowledge about RC was needed since the only thing used of that is the content of the metabox it attaches to the post, which i figured would be quite visible for anyone qualified to solve my problem. I only mentioned it to give proper credits. – Enok82 May 6 '16 at 9:46
1

Fiddling with user roles would probably be the most robust solution, however a quick and dirty approach would be to set post meta-data to mark posts that should be hidden, then add a meta-query to post queries by using a pre_get_posts hook in order to restrict results to non-hidden posts for non-logged-in users.

The following will limit all posts queried for logged-out visitors to those which either do not have associated hide_from_guests meta-data, or have that metadata set to 'false':

function wpse225120_hide_posts_from_guests( $query ) {
  // If the user's logged in, exit the function now.
  if( is_user_logged_in() )
    return;

  // Get the current metadata query so we can alter it instead of overwriting it
  $meta_query = $query->get( 'meta_query' );

  // Create a meta-query filtering out hidden posts
  $hidden_meta_query = array(
    'relation' => 'OR',
    array(
      'key'     => 'hide_from_guests',
      'value'   => 'false'
    ),
    array(
      'key'     => 'hide_from_guests',
      'compare' => 'NOT_EXISTS'
    ) 
  );

  // If there's not already a meta-query, supply the one for hidden posts and exit
  if( ! is_array( $meta_query ) || empty( $meta_query ) ) {
    $query->set( 'meta_query', $hidden_meta_query );
    return;
  }

  // If there is an existing meta-query, modify it to support our new hidden posts
  // meta-query as a top-level 'AND' condition, if need be
  if( isset( $meta_query[ 'relation' ] ) && 'OR' === $meta_query[ 'relation' ] )
    $meta_query = array(
      'relation'  => 'AND',
      $meta_query
    );
  }

  // Add the hidden posts meta-query and overwrite $query's old meta-query
  $meta_query[] = $hidden_meta_query;
  $query->set( 'meta_query', $meta_query );
}
add_action( 'pre_get_posts', 'wpse225120_hide_posts_from_guests' );

Note that globally altering every query like this is generally considered to be a bad practice. If at all possible, use is_main_query() and other conditional tags to limit query modifications to just the relevant queries in order to prevent unexpected behaviors and performance impact.

The 'hide_from_guests' post meta-data can be set on individual posts by using the custom fields interface, post metadata functions, or implementing a custom metabox and attaching it to relevant post types, among other ways.

  • this looks great, i'll try it out. Do you have any source of information that i might read about the user roles related to this matter and not just the common levels of permissions? – Enok82 May 6 '16 at 9:55
0

Use this code on your child theme’s functions.php file..

//Hide for non-logged-in users (public visitors)
 function bp_logged_out_page_template_redirect() { if( ! is_user_logged_in() && is_page( 'members' )|| is_page( 'activity' ) || bp_is_user() ) { wp_redirect( home_url( '/register/' ) ); exit(); } } 
add_action( 'template_redirect', 'bp_logged_out_page_template_redirect' );

The above snippet will do:

IF the user is not logged-in.. AND the page name is ‘members’ OR ‘activity’ OR bp-profile-page.. THEN it will redirect to REGISTER page.

Ref : https://vvcares.com/w/wordpress-hide-pages-for-non-logged-in-users/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.