Pass IDs to pre_get_posts query in function

2020-05-06 17:48发布

问题:

I am trying to pass the post ids to the function's query->set and function will return the posts.

add_action( 'pre_get_posts', 'query_booked_posts' );

function query_booked_posts( $query ) {
    if ( $condition ) { //the condition

    if ( is_home() && $query->is_main_query() )
    $results = $wpdb->get_col($wpdb->prepare( "SELECT booked_id FROM $wpdb->userbooking WHERE userid = %d",$current_user_id));

    foreach($results as $result){
    $results_separated = $result.',';
    }
    $query->set ('post__in', array($results_separated)); // pass results (post ids) to post__in

    return $query;
    }

}    

After this, the function returns nothing.

If I do $query->set ('post__in', array(45,121));, the query will return the posts of id 45 and id 121, so the query works fine.

But I want to make $results_separated pass the post ids like 45,121,132 to the query, and then $query->set ('post__in', array($results_separated)); will work correctly. How can I make this happen?

pre_get_posts reference

回答1:

I guess you have actually a PHP problem. When you do array($results_separated) you're basically creating an array from a string that looks like this: "12,114,56,". By doing that, PHP is creating an array like this:

array(
    0 => "12,114,56,"
)

And obviously WordPress cannot find any posts with such ID! What you want is actually an array like this:

array(
    0 => "12",
    1 => "114",
    2 => "56"
)

And actually that's what get_col() returns, so you just need to pass $results to set() function:

$query->set ( 'post__in', $results );

EDIT: Actually I realised that your problem is when you call $wpdb->get_col(...), because it's interfering with the $query you will execute later on... Those variables are using some other global variables that probably get overriden, and that's why you're not getting any results...



回答2:

Except the extra array() over $results_separated, in my case I had to apply

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

at the top of my function (found it in, otherwise, queries inside would be executed for several times and not properly. Comments in the answer helped me to figure this out.