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, privacy policy and cookie policy

Browse other questions tagged or ask your own question.