Unfortunately when you are doing a custom query in WordPress by default you can’t search by the “s” parameter and a meta_query. A common technique was to just do two queries and merge them. That works, but it is not efficient.
User Satbir Kira over at StackOverflow posted this great solution. Simply add this function to your functions.php file and replace the “s” parameter in your custom query with a “_meta_or_title” parameter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
add_action( 'pre_get_posts', function( $q ) { if( $title = $q->get( '_meta_or_title' ) ) { add_filter( 'get_meta_sql', function( $sql ) use ( $title ) { global $wpdb; // Only run once: static $nr = 0; if( 0 != $nr++ ) return $sql; // Modified WHERE $sql['where'] = sprintf( " AND ( %s OR %s ) ", $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title), mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) ) ); return $sql; }); } }); |
Here is what an example query might look like.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
$search_value = 'Search Me'; $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1; $args = array( 'post_type' => 'contacts', 'paged' => $paged, '_meta_or_title' => $search_value, 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'office', 'value' => $search_value, 'compare' => 'LIKE' ), array( 'key' => 'title', 'value' => $search_value, 'compare' => 'LIKE' ), array( 'key' => 'email', 'value' => $search_value, 'compare' => 'LIKE' ) ) ); //$results = new WP_Query( $args ); //need pagination? $results = get_posts( $args ); //simple listing? |