pre_get_posts Remove posts based on meta value with ‘post__not_in’

Try this version:

// Get all posts with the access level of 'Member'
function members_get_member_posts() {

    $post_ids = wp_cache_get( 'wpse61487_members_posts' );
    if ( false === $post_ids ) {

        $post_ids = array();
        $args=array(
            'post_type' => 'any',
            'meta_key' => '_members_access_role',
            'meta_value' => 'member',
            'post_status' => array('publish','private')
        );

        $protected_posts = get_posts($args);
        if($protected_posts) {
            $post_ids = wp_list_pluck( $protected_posts, 'ID' );
        }

        wp_cache_set( 'wpse61487_members_posts', $post_ids );
     }

     // return an array of paid post IDs
     return $post_ids;
}

// Hide all posts from users who are not logged-in or are not administrators or members
function members_hide_member_posts($query) {

    if( !$query->is_main_query() )
        return;

    $current_user = wp_get_current_user();
    if(empty($current_user) || ($current_user->roles[0] != 'member' && $current_user->roles[0] != 'administrator') && (false === $query->query_vars['suppress_filters'])) {
        $protected_posts = members_get_member_posts();
        if( !empty( $protected_posts ) )
            $query->set('post__not_in', $protected_posts);
    }
}
add_action('pre_get_posts', 'members_hide_member_posts');

Leave a Comment