1

I use the pre_get_posts hook to change the search results because I have a filter form.

This hook gives me access to an already made $query object.

This line does not work:

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

Although var_dump($my_posts_ids) echoes something like:

array(3) {
  [0]=>
  int(11)
  [1]=>
  int(10)
  [2]=>
  int(6)
}

How should I make this work?

What page in the documentation talks about this feature of the set method?

I did some searches and I could not find the specific thing.

Update 1

This is the way I hook into pre_get_posts:

add_action('pre_get_posts', 'sbro_filter_by_year'); // the hook
function sbro_filter_by_year($query)
{
    $district_query = null;

    $gc = !is_admin() && is_search() && $query->is_main_query() && !empty($_GET);

    if ($gc && isset($_GET['anul_nasterii']) && !empty($_GET['anul_nasterii'])) {
        $filtru_an_nastere = absint($_GET['anul_nasterii']);
        $gradinite = get_gradinite();
        $gradi_ids = get_shown_gradinite($gradinite, $filtru_an_nastere);
        alter_query_to_show_gradinite($gradi_ids, $query);
    }

    if ($gc && isset($_GET['district']) && !empty($_GET['district']) && $_GET['district'] !== 'toate') {
        $district_query = array(
            'key' => 'district',
            'value' => sanitize_text_field($_GET['district'])
        );
    }

    $queries = array();

    if (!is_null($district_query)) {
        $queries[] = $district_query;
    }

    if (!empty($queries)) {
        $query->set('meta_query', $queries);
    }

    return $query;
}

Update 2

This is where I want to use post__in:

function alter_query_to_show_gradinite($gradi_ids, $query)
{
    if (count($gradi_ids) > 0) {
        // var_dump($gradi_ids); 
        // var_dump(array(321, 123423, 1134241242));

        // the $gradi_ids is good here

        // See: https://wordpress.stackexchange.com/questions/386961/how-to-use-query-set-with-post-in?noredirect=1#comment561435_386961
        $query->set('post__in', $gradi_ids);
    }
}

Update 3 (full code)

I have worked on the code and solved a big bug that corrupted the DB.

The code works well except, when there are no IDs put in post__in parameter it shows all the posts in the gradinita custom post type. How can I make it show nothing when there is no matching post?

This is all I think is relevant code:

/**
 * Returns the ID's of all the gradinite.
 *
 * @return Array
 */
function get_gradinite()
{
    $q_gradinite = new WP_Query(array('post_type' => 'gradinita'));
    $gradinite = array();

    while ($q_gradinite->have_posts()) {
        $q_gradinite->the_post();
        $gradinite[] = get_the_ID($q_gradinite->post->ID);
    }

    wp_reset_postdata();

    return $gradinite;
}

function get_shown_gradinite($gradinite, $filtru_an_nastere)
{
    $gradi_ids = array();
    foreach ($gradinite as $gradi) {

        $q_copii = new WP_Query(array('post_type' => 'copil'));
        $children = array();

        while ($q_copii->have_posts()) {
            $q_copii->the_post();
            if (get_field('gradinita', $q_copii->post->ID)->ID === $gradi) {
                $children[] = get_the_ID($q_copii->post->ID);
            }
        }

        wp_reset_postdata();

        $show_gradi = false;
        foreach ($children as $child) {
            $o = date_parse_from_format('d/m/Y', get_field('data_nasterii', $child));
            if ($o['year'] == $filtru_an_nastere) {
                $show_gradi = true;
                break;
            }
        }

        if ($show_gradi) {
            $gradi_ids[] = $gradi;
        }
    }
    return $gradi_ids;
}


function alter_query_to_show_gradinite($gradi_ids, $query)
{
    // the $gradi_ids is good here
    $query->set('post__in', $gradi_ids); // this does not work
}

add_action('pre_get_posts', 'sbro_filter_by_year'); // the hook
function sbro_filter_by_year($query)
{
    $district_query = null;

    $gc = !is_admin() && is_search() && $query->is_main_query() && !empty($_GET);

    if ($gc) {
        if (isset($_GET['anul_nasterii']) && !empty($_GET['anul_nasterii'])) {
            $filtru_an_nastere = absint($_GET['anul_nasterii']);
            $gradinite = get_gradinite();
            $gradi_ids = get_shown_gradinite($gradinite, $filtru_an_nastere);
            alter_query_to_show_gradinite($gradi_ids, $query);
        }

        if (isset($_GET['district']) && !empty($_GET['district']) && $_GET['district'] !== 'toate') {
            $district_query = array(
                'key' => 'district',
                'value' => sanitize_text_field($_GET['district'])
            );
        }

        $queries = array();

        if (!is_null($district_query)) {
            $queries[] = $district_query;
        }

        if (!empty($queries)) {
            $query->set('meta_query', $queries);
        }

        $query->set('post_type', 'gradinita');
    }

    return $query;
}

Thanks.

5
  • 6
    Your pre_get_posts filter code is incomplete, it's going to be very difficult if not impossible to diagnose what's happening without more information. Please update your question with the relevant code
    – Tom J Nowell
    Apr 21, 2021 at 13:57
  • Thank you for the comment. I will post more details tomorrow. Apr 21, 2021 at 18:08
  • @TomJNowell I have updated the question. Thank you for the feedback. Apr 22, 2021 at 9:18
  • I've read your updated code but I cannot see where you used $query->set('post__in', $my_post_ids);
    – Tom J Nowell
    Apr 22, 2021 at 10:54
  • @TomJNowell I did another update. If you need any more pieces of code please let me know. Apr 22, 2021 at 12:17

0

Your Answer

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

Browse other questions tagged or ask your own question.