0

I, recently posted 2 questions (First, Second) with no answer. I found my solution for both of them. But now it's time to fine-tune things. If I can fine-tune here, I could answer both the questions. Why to fine-tune? Because the procedural raw PHP coding is less prior to WordPress' way.

<?php
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' ) );
        $complex_query = "SELECT SQL_CALC_FOUND_ROWS {$wpdb->posts}.ID ...";
        return $custom_search_query = $wpdb->get_results( $complex_query, ARRAY_N );

    } //endif
}
add_action( 'pre_get_posts', 'project_modify_default_search' );

But actually I'm failing with the code above in two cases:

  • I can't reset default query
  • I can't return my custom query so that I can grab that the default search.php works flawlessly

But the query is working, I checked that other way.

Question is:
How can I reset the usual $query on the search page to initiate my custom $wpdb query there?

  • You want both the default search and your custom one? – s_ha_dum May 19 '15 at 15:04
  • No. I want my custom one over the default one. As I'm not modifying the default one, but querying a new, so I need to shut the default one off, and pass the new one to that page in a way that, in search.php with if( have_posts() ) simply can have it like default query. – Mayeenul Islam May 20 '15 at 3:20
2

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.

|improve this answer|||||
  • It's working just fine. But if nothing is found, instead of returning false it's returning all the posts. How can I stop them? I even tried if( $custom_search_query ) $query->set('post__in',$custom_search_query);, but not working – Mayeenul Islam Jun 21 '15 at 4:38
  • @MayeenulIslam when $complex_query return nothing, the 'post__in' query variable is ignored because empty. The 's' query does nothing because of add_action( 'posts_search', '__return_empty_string' ). It means the query runs with no constraints thus it returns all posts. My suggestion is to replace the whole request that WP_Query performs by using 'posts_request' filter hook. – gmazzap Jun 21 '15 at 13:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.