This question is a follow up to a question I recently asked.
I’ve implemented what seemed to be the only solution, and it seems to work (YAY!). I just need to verify that:
- This is really the only way to modify the query to match with a match to the (
post_title OR post_content
OR any one of the other meta fields desired. - That this won’t mess with other queries not related to searches. The regex used below, I think, would generally only be used for search, but what chance is there of it matching some other functionality in the core or a plugin. I realize with plugins anything could happen, but I’m especially concerned about conflicts in the WP Core.
- I considered doing all the work in the
posts_where
filter, but thought it was best to rely on modifying$query
as much as possible and limit direct modification ofWHERE
. Is that a reasonable choice?
In any event, here is the function used to modify the WHERE
:
function st_posts_where( $where ){
if( !is_admin() ){
global $wpdb;
$ptn = "/(s*AND ((({$wpdb->prefix}posts.post_title LIKE '%.*%')s+ORs+(".
"{$wpdb->prefix}posts.post_content LIKE '%.*%')))s+)AND(.*)/";
$where = preg_replace( $ptn, "$1OR$2", $where );
}
return $where;
}
add_filter( 'posts_where' , 'st_posts_where' );
Additionally, here is the function that the original question was addressing, which is still being used alongside the above one.
function st_search_all( $query ) {
if( !is_admin() && $query->is_search ) {
$query->set( 'post_type', array( 'page', 'attachment' ) );
$query->set( 'post_status', 'inherit' );
$query->set( 'meta_query', array(
'relation' => 'OR',
array(
'key' => '_st_plaintext',
'value' => $query->get('s'),
'compare' => 'LIKE'
),
array(
'key' => 'Training Classes',
'value' => $query->get('s'),
'compare' => 'LIKE'
),
array(
'key' => 'External Content',
'value' => $query->get('s'),
'compare' => 'LIKE'
)
) );
}
return $query;
}
add_filter( 'pre_get_posts', 'st_search_all' );
All of this in combination results in the following query result which achieves the desired result:
AND (((dev_posts.post_title LIKE '%sbir%')
OR (dev_posts.post_content LIKE '%sbir%')))
OR dev_posts.post_type IN ('page', 'attachment')
AND (dev_posts.post_status = 'inherit')
AND (
(dev_postmeta.meta_key = '_st_plaintext'
AND CAST(dev_postmeta.meta_value AS CHAR) LIKE '%sbir%')
OR (mt1.meta_key = 'Training Classes'
AND CAST(mt1.meta_value AS CHAR) LIKE '%sbir%')
OR (mt2.meta_key = 'External Content'
AND CAST(mt2.meta_value AS CHAR) LIKE '%sbir%'))
You want to make sure you’re only messing with the main query and not subsequent queries called from a plugin or in a template on the search page. In other words…
should be
See http://codex.wordpress.org/Function_Reference/is_main_query