I couldn't find a solution to look for multiple keywords that can be mixed in either post title, description AND/OR one or several metas, so I made my own addition to the search function.
All you need is to add the following code in function.php, and whenever you use the 's' argument in a standard WP_Query() function and want it to search in one or several meta fields as well, you simply add a 's_meta_keys'
argument that is an array of the meta(s) key(s) you want to search in:
/************************************************************************\
|** **|
|** Allow WP_Query() search function to look for multiple keywords **|
|** in metas in addition to post_title and post_content **|
|** **|
|** By rAthus @ Arkanite **|
|** Created: 2020-08-18 **|
|** Updated: 2020-08-19 **|
|** **|
|** Just use the usual 's' argument and add a 's_meta_keys' argument **|
|** containing an array of the meta(s) key you want to search in :) **|
|** **|
|** Example : **|
|** **|
|** $args = array( **|
|** 'numberposts' => -1, **|
|** 'post_type' => 'post', **|
|** 's' => $MY_SEARCH_STRING, **|
|** 's_meta_keys' => array('META_KEY_1','META_KEY_2'); **|
|** 'orderby' => 'date', **|
|** 'order' => 'DESC', **|
|** ); **|
|** $posts = new WP_Query($args); **|
|** **|
\************************************************************************/
add_action('pre_get_posts', 'my_search_query'); // add the special search fonction on each get_posts query (this includes WP_Query())
function my_search_query($query) {
if ($query->is_search() and $query->query_vars and $query->query_vars['s'] and $query->query_vars['s_meta_keys']) { // if we are searching using the 's' argument and added a 's_meta_keys' argument
global $wpdb;
$search = $query->query_vars['s']; // get the search string
$ids = array(); // initiate array of martching post ids per searched keyword
foreach (explode(' ',$search) as $term) { // explode keywords and look for matching results for each
$term = trim($term); // remove unnecessary spaces
if (!empty($term)) { // check the the keyword is not empty
$query_posts = $wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_status='publish' AND ((post_title LIKE '%%%s%%') OR (post_content LIKE '%%%s%%'))", $term, $term); // search in title and content like the normal function does
$ids_posts = [];
$results = $wpdb->get_results($query_posts);
if ($wpdb->last_error)
die($wpdb->last_error);
foreach ($results as $result)
$ids_posts[] = $result->ID; // gather matching post ids
$query_meta = [];
foreach($query->query_vars['s_meta_keys'] as $meta_key) // now construct a search query the search in each desired meta key
$query_meta[] = $wpdb->prepare("meta_key='%s' AND meta_value LIKE '%%%s%%'", $meta_key, $term);
$query_metas = $wpdb->prepare("SELECT * FROM {$wpdb->postmeta} WHERE ((".implode(') OR (',$query_meta)."))");
$ids_metas = [];
$results = $wpdb->get_results($query_metas);
if ($wpdb->last_error)
die($wpdb->last_error);
foreach ($results as $result)
$ids_metas[] = $result->post_id; // gather matching post ids
$merged = array_merge($ids_posts,$ids_metas); // merge the title, content and meta ids resulting from both queries
$unique = array_unique($merged); // remove duplicates
if (!$unique)
$unique = array(0); // if no result, add a "0" id otherwise all posts wil lbe returned
$ids[] = $unique; // add array of matching ids into the main array
}
}
if (count($ids)>1)
$intersected = call_user_func_array('array_intersect',$ids); // if several keywords keep only ids that are found in all keywords' matching arrays
else
$intersected = $ids[0]; // otherwise keep the single matching ids array
$unique = array_unique($intersected); // remove duplicates
if (!$unique)
$unique = array(0); // if no result, add a "0" id otherwise all posts wil lbe returned
unset($query->query_vars['s']); // unset normal search query
$query->set('post__in',$unique); // add a filter by post id instead
}
}
Example use:
$search= "kewords to search";
$args = array(
'numberposts' => -1,
'post_type' => 'post',
's' => $search,
's_meta_keys' => array('short_desc','tags');
'orderby' => 'date',
'order' => 'DESC',
);
$posts = new WP_Query($args);
This example will look for the keywords "kewords to search" in post titles, descriptions, and meta keys 'short_desc' and 'tags'.
Keywords can be found in one or several of the fileds, in any order, it will return any post that has all the keywords in any of the designated fields.
You can obiously force the search in a list of meta keys you include in the fonction and get rid of the extra agruments if you want ALL search queries to include these meta keys :)
Hope that will help anyone who face the same issue I did!