I am pretty new to Wordpress and recently I found this problem which took me a lot of time to understand but I can't still figure out how to resolve it.
I am using the Wordpress basic search using the classic search.php.
I need to retrieve POSTS based on their post_title OR their custom field taxonomy, for example my case taxonomy is 'color', with ACF I added a new field called synonimes which is repeater field with inside N* text fields called synonim.
Basically I need to retrieve both posts with synonimes matching and post_title matching (basically the classic 's' => $value inside wordpress query args), using the hook pre_get_posts I only reached the point where I can filter the POSTS with a AND condition which is really wrong.
I don't know how to change this behavior and I gave up this way, I am now trying to merge the results I found with the primary Query in the hook.
I am now with this code here:
function filter_tax($query){
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
$args_new_query = array(
'post_type' => MAIN_POST,
'posts_per_page' => 12,
'post_parent' => 0,
);
$new_query = new WP_Query($args_new_query);
$search_keyword = sanitize_text_field(get_search_query());
$matching_posts = array();
if ($new_query->have_posts()) {
$taxonomy_name = 'color';
while ($new_query->have_posts()) : $new_query->the_post();
$post_id = get_the_ID();
$terms = wp_get_post_terms($post_id, $taxonomy_name);
foreach ($terms as $term) {
$synonim_values = get_field('synonimes', $taxonomy_name . '_' . $term->term_id);
if (is_array($synonim_values)) {
foreach ($synonim_values as $syn) {
if (strpos($syn['synonim'], $search_keyword) !== false) {
$matching_posts[] = get_post($post_id);
break 2;
}
}
}
}
endwhile;
wp_reset_postdata();
}
if (!empty($matching_posts)) {
/*$query->set('post__in', wp_list_pluck($matching_posts, 'ID'));*/
$query->posts = array_merge([], $matching_posts);
}
}
}
Unfortunately in my template I only can paginate basic search POSTS and my $matching_posts are lost and cannot be retrieved, It looks really simple but still it's taking me a lot of time.
I made an error by misunderstanding the inner functionality of POST__IN.
Initially I thought i could inject POSTS by their ID, but this is wrong because I was filtering POSTS by their ID.
So I came up with this:
$args_basic = [
'post_type' => $contentList,
'numberposts' => -1,
'post_parent' => 0,
's' => $_GET['s'],
];
$prev_search = get_posts($args_basic);
$prev_search_ids = array_map(fn($item) => $item->ID, $prev_search);
$query->set('post_type', $contentList);
if (!empty($matching_posts)) {
$ids_serach = array_merge($prev_search_ids, wp_list_pluck($matching_posts, 'ID'));
$query->set('post__in', $ids_serach);
$query->set('s', '');
}
This is the correct way to use POST__IN.
I am leaving here my question and answer in case you are in the same boat, don't waste time merging queryposts!, it will never work.