This is not how pre_get_posts
works.
The pre_get_posts action gives developers access to the $query object
by reference (any changes you make to $query are made directly to the
original object – no return value is necessary).https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts
What you are doing is simply wrong. You don’t “return” another query via pre_get_posts
, you alter the existing query. I don’t know what is so complex you can’t do it via an appropriate set of filters but if you must have some custom SQL then:
function project_modify_default_search( $query ) {
if( $query->is_search && $query->is_main_query() && ! isset( $_REQUEST['search'] ) ) {
//I'm in my search.php - confirmed
//Reset default $query - not to execute at all
//Do my custom complex query and pass the query as a $wp_query object
//so that I can use the default search.php template
global $wpdb;
$searchQ = sanitize_text_field( get_query_var( 's' ) );
// Sample "complex" query
$complex_query = "SELECT SQL_CALC_FOUND_ROWS {$wpdb->posts}.ID FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_title LIKE '$searchQ%' LIMIT 10";
// Use `get_col` to return a simple array of IDs
$custom_search_query = $wpdb->get_col( $complex_query );
// Pass those IDs to the main query
$query->set('post__in',$custom_search_query);
// can't kill the default search here or it can break some functions.
// $query->set('s',NULL);
// So we do this:
add_action( 'posts_search', '__return_empty_string' );
} //endif
}
add_action( 'pre_get_posts', 'project_modify_default_search' );
Again, pretty sure this is the wrong way to generate a complicated query, especially given that you have at least one extra query relative to modifying the main query via a set of filters– posts_where
, posts_join
, etc.