You may have already solved this months ago, but I here’s my 2 cents as I thought this was an interesting question.
I don’t think the standard WP search query can be used to search for posts with either (post type A) or (post type B and category C). But you could pass a custom where clause to the query with posts_where
filter to handle this kind of case.
I think something like this should work,
add_filter( 'posts_where' , 'my_posts_where', 10, 2 );
function my_posts_where( $where, $query ) {
if ( is_admin() || ! is_search() || ! is_main_query() ) {
return $where;
}
// check that requred $_GET parameters are set
if ( ! empty( $_GET['post_type'] ) || 'bwps' !== $_GET['post_type'] ) {
return $where;
}
if ( empty( $_GET['s'] ) ) {
return $where;
}
// return custom where clause
global $wpdb;
$sql = "
AND (
{$wpdb->posts}.post_title LIKE '%%%s%%' OR
{$wpdb->posts}.post_name LIKE '%%%s%%'
)
AND
{$wpdb->posts}.post_status="publish"
AND
(
(
{$wpdb->posts}.post_type="bwps"
) OR
(
{$wpdb->posts}.post_type="page"
AND
{$wpdb->posts}.ID IN (
SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->term_relationships} AS tr ON (p.ID = tr.object_id)
INNER JOIN {$wpdb->term_taxonomy} AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
INNER JOIN {$wpdb->terms} AS t ON (t.term_id = tt.term_id)
WHERE
p.post_status="publish"
AND t.term_id = %d
AND tt.taxonomy = 'category'
)
)
)
";
$search_phrase="%" . $_GET['s'] . '%';
$term_id = 1;
return $wpdb->prepare(
$sql,
$search_phrase,
$search_phrase,
$term_id
);
}