Advertisement
rAthus

[WordPress] WP_Query() search multiple keywords in post title description and metas (ACF, etc)

Aug 18th, 2020 (edited)
2,187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.55 KB | None | 0 0
  1. /************************************************************************\
  2. |**                                                                    **|
  3. |**  Allow WP_Query() search function to look for multiple keywords    **|
  4. |**  in metas in addition to post_title and post_content               **|
  5. |**                                                                    **|
  6. |**  By rAthus @ Arkanite                                              **|
  7. |**  Created: 2020-08-18                                               **|
  8. |**  Updated: 2020-08-19                                               **|
  9. |**                                                                    **|
  10. |**  Just use the usual 's' argument and add a 's_meta_keys' argument  **|
  11. |**  containing an array of the meta(s) key you want to search in :)   **|
  12. |**                                                                    **|
  13. |**  Example :                                                         **|
  14. |**                                                                    **|
  15. |**  $args = array(                                                    **|
  16. |**      'numberposts'  => -1,                                         **|
  17. |**      'post_type' => 'post',                                        **|
  18. |**      's' => $MY_SEARCH_STRING,                                     **|
  19. |**      's_meta_keys' => array('META_KEY_1','META_KEY_2');            **|
  20. |**      'orderby' => 'date',                                          **|
  21. |**      'order'   => 'DESC',                                          **|
  22. |**  );                                                                **|
  23. |**  $posts = new WP_Query($args);                                     **|
  24. |**                                                                    **|
  25. \************************************************************************/
  26. add_action('pre_get_posts', 'akn_meta_search_query'); // add the special search fonction on each get_posts query (this includes WP_Query())
  27. function akn_meta_search_query($query) {
  28.     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
  29.         global $wpdb;
  30.         $search = $query->query_vars['s']; // get the search string
  31.         $ids = array(); // initiate array of matching post ids per searched keyword
  32.         foreach (explode(' ',$search) as $term) { // explode keywords and look for matching results for each
  33.             $term = trim($term); // remove unnecessary spaces
  34.             if (!empty($term)) { // check the the keyword is not empty
  35.                 $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
  36.                 $ids_posts = [];
  37.                 $results = $wpdb->get_results($query_posts);
  38.                 if ($wpdb->last_error)
  39.                     die($wpdb->last_error);
  40.                 foreach ($results as $result)
  41.                     $ids_posts[] = $result->ID; // gather matching post ids
  42.                 $query_meta = [];
  43.                 foreach($query->query_vars['s_meta_keys'] as $meta_key) // now construct a search query the search in each desired meta key
  44.                     $query_meta[] = $wpdb->prepare("meta_key='%s' AND meta_value LIKE '%%%s%%'", $meta_key, $term);
  45.                 $query_metas = $wpdb->prepare("SELECT * FROM {$wpdb->postmeta} WHERE ((".implode(') OR (',$query_meta)."))");
  46.                 $ids_metas = [];
  47.                 $results = $wpdb->get_results($query_metas);
  48.                 if ($wpdb->last_error)
  49.                     die($wpdb->last_error);
  50.                 foreach ($results as $result)
  51.                     $ids_metas[] = $result->post_id; // gather matching post ids
  52.                 $merged = array_merge($ids_posts,$ids_metas); // merge the title, content and meta ids resulting from both queries
  53.                 $unique = array_unique($merged); // remove duplicates
  54.                 if (!$unique)
  55.                     $unique = array(0); // if no result, add a "0" id otherwise all posts will be returned
  56.                 $ids[] = $unique; // add array of matching ids into the main array
  57.             }
  58.         }
  59.         if (count($ids)>1)
  60.             $intersected = call_user_func_array('array_intersect',$ids); // if several keywords keep only ids that are found in all keywords' matching arrays
  61.         else
  62.             $intersected = $ids[0]; // otherwise keep the only matching ids array
  63.         $unique = array_unique($intersected); // remove duplicates
  64.         if (!$unique)
  65.             $unique = array(0); // if no result, add a "0" id otherwise all posts will be returned
  66.         unset($query->query_vars['s']); // unset normal search query
  67.         $query->set('post__in',$unique); // add a filter by post id instead
  68.     }
  69. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement