$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>wp query - 'posts_where' filter not applying 'WP_Query' in `wp_ajax`|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

wp query - 'posts_where' filter not applying 'WP_Query' in `wp_ajax`

matteradmin8PV0评论

I have a function which adds a posts_join and a posts_where to searches in WP_Query. It works fine on a normal, php rendered search page. However i'm also using it for a ajax product search and the additional posts_join and a posts_where don't seem to apply.

Here's the join and where:

function search_by_meta_join($join) {
    global $wpdb;

    if (is_search()) {
        $join .= " LEFT JOIN {$wpdb->postmeta} pm_ean ON {$wpdb->posts}.ID = pm_ean.post_id AND (pm_ean.meta_key = 'ean') ";
        $join .= " LEFT JOIN {$wpdb->postmeta} pm_code ON {$wpdb->posts}.ID = pm_code.post_id AND (pm_code.meta_key = 'product_code') ";
    }

    return $join;
}
add_filter('posts_join', 'search_by_meta_join');

function search_by_meta_where($where) {
    global $wpdb;

    if (is_search()) {
        $where = preg_replace(
            "/\(\s*{$wpdb->posts}.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "({$wpdb->posts}.post_title LIKE $1) OR (pm_ean.meta_value LIKE $1) OR (pm_code.meta_value LIKE $1) ", $where
        );
    }

    return $where;
}
add_filter('posts_where', 'search_by_meta_where');

And here's my ajax function:

    $args = array(
      'posts_per_page' => 12,
      'post_type' => 'product',
//      'offset' => filter_var($_GET['offset'], FILTER_SANITIZE_NUMBER_INT),
//      'post_status' => 'publish',
//      'order' => 'ASC',
//      'orderby' => 'title',
    );

    // Search query
    if (isset($_GET['searchQuery']) && $_GET['searchQuery'] != '') {
        $args['s'] = filter_var($_GET['searchQuery'], FILTER_SANITIZE_STRING);
    }

    // Category filter
//    if (isset($_GET['category']) && $_GET['category'] !== 0) {
//        $args['tax_query'][] = [
//            'taxonomy' => 'product-category',
//            'field' => 'term_id',
//            'terms' => filter_var($_GET['category'], FILTER_SANITIZE_NUMBER_INT),
//        ];
//    }

    $loop = new WP_Query($args);
    $products = array();

As I say it works on a normal search page like so:

global $query_string;

wp_parse_str($query_string, $search_query);

$search = new WP_Query($search_query);

Am I missing something for the ajax function to use it?

I have a function which adds a posts_join and a posts_where to searches in WP_Query. It works fine on a normal, php rendered search page. However i'm also using it for a ajax product search and the additional posts_join and a posts_where don't seem to apply.

Here's the join and where:

function search_by_meta_join($join) {
    global $wpdb;

    if (is_search()) {
        $join .= " LEFT JOIN {$wpdb->postmeta} pm_ean ON {$wpdb->posts}.ID = pm_ean.post_id AND (pm_ean.meta_key = 'ean') ";
        $join .= " LEFT JOIN {$wpdb->postmeta} pm_code ON {$wpdb->posts}.ID = pm_code.post_id AND (pm_code.meta_key = 'product_code') ";
    }

    return $join;
}
add_filter('posts_join', 'search_by_meta_join');

function search_by_meta_where($where) {
    global $wpdb;

    if (is_search()) {
        $where = preg_replace(
            "/\(\s*{$wpdb->posts}.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "({$wpdb->posts}.post_title LIKE $1) OR (pm_ean.meta_value LIKE $1) OR (pm_code.meta_value LIKE $1) ", $where
        );
    }

    return $where;
}
add_filter('posts_where', 'search_by_meta_where');

And here's my ajax function:

    $args = array(
      'posts_per_page' => 12,
      'post_type' => 'product',
//      'offset' => filter_var($_GET['offset'], FILTER_SANITIZE_NUMBER_INT),
//      'post_status' => 'publish',
//      'order' => 'ASC',
//      'orderby' => 'title',
    );

    // Search query
    if (isset($_GET['searchQuery']) && $_GET['searchQuery'] != '') {
        $args['s'] = filter_var($_GET['searchQuery'], FILTER_SANITIZE_STRING);
    }

    // Category filter
//    if (isset($_GET['category']) && $_GET['category'] !== 0) {
//        $args['tax_query'][] = [
//            'taxonomy' => 'product-category',
//            'field' => 'term_id',
//            'terms' => filter_var($_GET['category'], FILTER_SANITIZE_NUMBER_INT),
//        ];
//    }

    $loop = new WP_Query($args);
    $products = array();

As I say it works on a normal search page like so:

global $query_string;

wp_parse_str($query_string, $search_query);

$search = new WP_Query($search_query);

Am I missing something for the ajax function to use it?

Share Improve this question asked Mar 1, 2019 at 11:02 Jam3snJam3sn 1256 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 4

is_search() is only true if the main query is for the search results. When you create your own query with new WP_Query, you're not using the main query. Additionally, AJAX requests do not even have a main query, so functions like is_search(), is_archive() etc. do not work.

If you want to check if a specific query is a search, you should use the is_search() method of the query, like this:

$query->is_search();

The posts_join and posts_where filters are applied to all queries, but the callbacks to those filters receive the current query object as an argument, and you can use this to check for any search queries so that you can apply your filter:

function search_by_meta_join( $join, $query ) { // <-- Note the additional argument.
    global $wpdb;

    if ( $query->is_search() ) { // <-- Note that we are checking the current query, not the main query.
    }

    return $join;
}
add_filter('posts_join', 'search_by_meta_join', 10, 2 ); // <-- Note the '2' which indicates we're accepting 2 arguments.

function search_by_meta_where( $where, $query ) { // <-- Note the additional argument.
    global $wpdb;

    if ( $query->is_search() ) { // <-- Note that we are checking the current query, not the main query.

    }

    return $where;
}
add_filter( 'posts_where', 'search_by_meta_where', 10, 2 );// <-- Note the '2' which indicates we're accepting 2 arguments.

The same principle applies whenever you're filtering pre_get_posts as well. You should always use the query object that's passed to the filter to check these things, otherwise your changes will apply to all queries on the search page, including menus, widgets, and secondary queries, not just the specific search query.

If you use ajax, is_search() return false. You have to define a global variable or a constant for use in your filters.

Post a comment

comment list (0)

  1. No comments so far