0

My posts_results filter is causing memory errors and I can't figure out why. Here's the full snippet:

/*-----------------------------------------------------------------------------------*/
/* Filter posts after they are returned */
/*-----------------------------------------------------------------------------------*/
function my_posts_results_filter( $posts ) {

    $filtered_posts = array();

    //printr($posts);

    foreach ( $posts as $post ) {

        $post_type = get_post_type();
        if ( $post_type != 'post' ) {
            $filtered_posts[] = $post;
            continue;
        }

        //Who can see this?
        $whosee = get_field('who_can_view',$post->ID);
        $post_meta = get_post_meta($post->ID);

        //printr($post_meta);

        //What is this user's role?
        $user_id = get_current_user_id();
        $user_info = get_userdata($user_id);
        $user_role = $user_info->roles[0];
        if ( $user_role == 'subscriber' || $user_role == 'author' || $user_role == 'contributor' || $user_role == 'editor' ) $user_role = 'member';

        if ( $whosee != "" ) {
            if ( $user_role == $whosee || $user_role == 'administrator' ) {
                $filtered_posts[] = $post;
            }
        }

    }

    return $filtered_posts ;
}

if ( !is_admin() ) {
    add_filter( 'posts_results', 'my_posts_results_filter' );
}

Any thoughts would be great.

Thanks, Jay

2
  • Well, you are using functions unnecessarily, for one-- get_field and get_post_meta for example. But exactly what are you trying to accomplish, in words? Looking at the code, my gut tells me that this is not the way to go.
    – s_ha_dum
    May 18, 2015 at 15:19
  • You're absolutely right, @s_ha_dum, it wasn't the way to go. I had actually used pre_get_posts later on and forgot to disable this filter (stupid and sloppy on my part). This code was making WAY too many requests to the database. I've now turned it off and have used pre_get_posts to filter posts out prior to making the queries. Thanks for taking the time to comment.
    – jay
    May 18, 2015 at 15:27

1 Answer 1

0

Sorry folks - for those curious, I had already solved this later on in my functions.php file and forgot to turn this filter off (silly). Here's the better solution if anyone cares to comment or improve. Basically, I'm filtering out content based on user role (I have a custom user role as well) so that posts aren't shown to users who aren't allowed to see them. This has to include sidebar widget (post archive listings, for example) and all other place where you might see a post title or link:

/*-----------------------------------------------------------------------------------*/
/* Filter out users who shouldn't see content */
/*-----------------------------------------------------------------------------------*/
function filter_users($query){

    if ( !is_admin() ) {

            if( is_page() ) { return; }

            $user_id    = get_current_user_id();
            $user_info  = get_userdata($user_id);
            $user_role  = $user_info->roles[0];
            $user_role  = ( $user_role == 'subscriber' || $user_role == 'author' || $user_role == 'contributor' || $user_role == 'editor' )  ? 'member' : $user_role;

            if ( $user_role == 'member' ) {

                //wordpress needs a value to compare or it won't work
                $query->set('meta_query', array(
                                            array(
                                                'meta_key'=>'who_can_view',
                                                'meta_value'=>'foobar',
                                                'compare' => 'NOT EXISTS',
                                            )   
                                          )
                            );

                add_filter( 'posts_join' , 'custom_posts_join' );
                add_filter( 'posts_where','custom_where' );

            }

    }

}
add_filter('pre_get_posts','filter_users');

function custom_posts_join($join){

    global $wpdb;

    $join .= " LEFT JOIN $wpdb->postmeta as meta_1 ON $wpdb->posts.ID = meta_1.post_id";

    return $join;
}

//Needed because WordPress craps the bed setting meta_query objects in pre_get_posts
function custom_where( $where = '' ){

    global $wpdb;

    $where .= " AND ( meta_1.meta_key = 'who_can_view' AND meta_1.meta_value = 'member' )";

    remove_filter( 'posts_where', 'custom_where' );

    return $where;

} // custom_where

Cheers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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