content restriction - Hiding posts from non logged in users

admin2025-01-07  5

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?

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?

Share Improve this question asked Apr 28, 2016 at 19:45 Enok82Enok82 311 silver badge2 bronze badges 7
  • 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 Commented Apr 28, 2016 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 Commented Apr 28, 2016 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 Commented Apr 29, 2016 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 Commented Apr 29, 2016 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 Commented May 6, 2016 at 9:46
 |  Show 2 more comments

2 Answers 2

Reset to default 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.

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.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736263816a919.html

最新回复(0)