Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /************************************************************************\
- |** **|
- |** 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', 'akn_meta_search_query'); // add the special search fonction on each get_posts query (this includes WP_Query())
- function akn_meta_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 matching 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 will be 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 only matching ids array
- $unique = array_unique($intersected); // remove duplicates
- if (!$unique)
- $unique = array(0); // if no result, add a "0" id otherwise all posts will be returned
- unset($query->query_vars['s']); // unset normal search query
- $query->set('post__in',$unique); // add a filter by post id instead
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement