最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

pre_get_posts and search query for admin

programmeradmin2浏览0评论

I'm going round in circles with trying to include several custom fields in my search results. The custom fields are managed via ACF.

At first I want this for the admin. /wp-admin/edit.php?post_type=location.

I can't see why this wont work. I have tried variations of it and different orders. I've also gone through the posts_search filter route with arrays but just can't get this to work.

Any help appreciated.

add_filter('pre_get_posts', __NAMESPACE__ . '\\search_custom_fields');

function search_custom_fields($query)
{
if ($query->is_search && $query->is_main_query()) {
    // this works.
    echo "search_custom_fields:   " . $query->is_main_query() . " " . $query->is_search;
    echo "Setting meta_query in search_custom_fields. ";

    $search_word = get_query_var('s');

    $meta_query = array(
        'relation' => 'OR',
        array(
            'key'     => 'loc_refid',
            'value'   => get_search_query(),
            'compare' => 'LIKE',
        ), array(
            'key'     => 'location_postcode_preview',
            'value'   => get_search_query(),
            'compare' => 'LIKE',
        ),
    );

    // if i uncomment this no results appear?!
    // $query->set('meta_query', $meta_query);

    // these work have an affect on the results
    $query->set('orderby', 'date');  
    $query->set('order', 'ASC');

}

return $query;

}

print_r($query) gives me -

 [query_vars]=>
        [meta_query] => Array
                (
                    [key] => loc_refid
                    [value] => MN0068
                    [compare] => LIKE
                )

 [meta_query] =>  
 [date_query] => 
 [post_count] => 0
 ...

thanks in advance.

I'm going round in circles with trying to include several custom fields in my search results. The custom fields are managed via ACF.

At first I want this for the admin. /wp-admin/edit.php?post_type=location.

I can't see why this wont work. I have tried variations of it and different orders. I've also gone through the posts_search filter route with arrays but just can't get this to work.

Any help appreciated.

add_filter('pre_get_posts', __NAMESPACE__ . '\\search_custom_fields');

function search_custom_fields($query)
{
if ($query->is_search && $query->is_main_query()) {
    // this works.
    echo "search_custom_fields:   " . $query->is_main_query() . " " . $query->is_search;
    echo "Setting meta_query in search_custom_fields. ";

    $search_word = get_query_var('s');

    $meta_query = array(
        'relation' => 'OR',
        array(
            'key'     => 'loc_refid',
            'value'   => get_search_query(),
            'compare' => 'LIKE',
        ), array(
            'key'     => 'location_postcode_preview',
            'value'   => get_search_query(),
            'compare' => 'LIKE',
        ),
    );

    // if i uncomment this no results appear?!
    // $query->set('meta_query', $meta_query);

    // these work have an affect on the results
    $query->set('orderby', 'date');  
    $query->set('order', 'ASC');

}

return $query;

}

print_r($query) gives me -

 [query_vars]=>
        [meta_query] => Array
                (
                    [key] => loc_refid
                    [value] => MN0068
                    [compare] => LIKE
                )

 [meta_query] =>  
 [date_query] => 
 [post_count] => 0
 ...

thanks in advance.

Share Improve this question edited May 24, 2020 at 12:08 v3nt asked May 23, 2020 at 20:00 v3ntv3nt 1,6897 gold badges36 silver badges54 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 2

Have you tried it with add_action instead of add_filter ?

add_action('pre_get_posts', 'search_custom_fields');

Is public set to true for your post_type?

And for use on in admin, try:

if ( is_admin() && $query->is_main_query() ) {
    if ( $query->is_search ) {
       //etc.

So turns out you can't actually add ACF / custom fields to the search query in this way. It seems to force and AND into the query.

I've used a mixture of sources to create the below which now works really well.

/* ADD META FIELD TO SEARCH QUERY */
// fields for Ajax search, admin and normal search
if (!isset($GLOBALS['current_screen']) && !is_customize_preview()):
    // DAMN AJAX! is_admin() is always true when using it ;-/
    add_meta_field_to_search_query('loc_refid');
        add_meta_field_to_search_query('location_postcode_preview');
    add_meta_field_to_search_query('location_region');
    add_meta_field_to_search_query('location_areas');

elseif (is_admin()):
    add_meta_field_to_search_query('loc_refid');
    add_meta_field_to_search_query('location_postcode');
    add_meta_field_to_search_query('location_postcode_preview');
    add_meta_field_to_search_query('location_region');
    add_meta_field_to_search_query('location_areas');
    add_meta_field_to_search_query('location_map_position' );
    add_meta_field_to_search_query('user_organisation');
    add_meta_field_to_search_query('user_position');
    add_meta_field_to_search_query('client_location');
    add_meta_field_to_search_query('user_email');
else:
    add_meta_field_to_search_query('loc_refid');           
    add_meta_field_to_search_query('location_postcode_preview');
    add_meta_field_to_search_query('location_region');
    add_meta_field_to_search_query('location_areas');

endif;

function add_meta_field_to_search_query($field, $condition = "LIKE")
{
    // echo "add_meta_field_to_search_query; field:$field";

    if (isset($GLOBALS['added_meta_field_to_search_query'])) {
        $GLOBALS['added_meta_field_to_search_query'][] = '\'' . $field . '\'';
        return;
    }

    $GLOBALS['added_meta_field_to_search_query']   = array();
    $GLOBALS['added_meta_field_to_search_query'][] = '\'' . $field . '\'';

    add_filter('posts_join', function ($join) {
        // echo "$s 'posts_join' <br />";
        global $wpdb;
        if (is_search()) {
            $join .= " LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id ";
        }
        return $join;
    });

    add_filter('posts_groupby', function ($groupby) {
        // echo "$s 'posts_groupby' <br />";
        global $wpdb;
        if (is_search()) {
            $groupby = "$wpdb->posts.ID";
        }
        return $groupby;
    });

    add_filter('posts_search', function ($search_sql) {
        global $wpdb;

        $search_terms = get_query_var('search_terms');

        if (!empty($search_terms)) {
            // echo "posts_search<br />";
            // print_r($search_terms);
            foreach ($search_terms as $search_term) {
                // echo "search_term: $search_term<br />";
                $old_or     = "OR ({$wpdb->posts}.post_content LIKE '{$wpdb->placeholder_escape()}{$search_term}{$wpdb->placeholder_escape()}')";
                $new_or     = $old_or . " OR ({$wpdb->postmeta}.meta_value LIKE '{$wpdb->placeholder_escape()}{$search_term}{$wpdb->placeholder_escape()}' AND {$wpdb->postmeta}.meta_key IN (" . implode(', ', $GLOBALS['added_meta_field_to_search_query']) . "))";
                $search_sql = str_replace($old_or, $new_or, $search_sql);
            }
        }

        $search_sql = str_replace(" ORDER BY ", " GROUP BY $wpdb->posts.ID ORDER BY ", $search_sql);

        return $search_sql;
    });

    // ajax seach only, basically same as above but checking for $GLOBALS['fd_search_term'] which holds the search string
    add_filter('posts_where', function ($search_sql) {
        global $wpdb;

        // print_r($wpdb);
        $search_terms = explode(' ', $GLOBALS['fd_search_term']);

        // if (!empty($search_terms) && !isset($GLOBALS['current_screen']) && !is_customize_preview() && !is_search()) {

        if ($GLOBALS['fd_search_term']) {
            // echo "AJAX posts_search<br />";
            // print_r($search_terms);
            foreach ($search_terms as $search_term) {
                // echo "search_term: $search_term<br />";
                $old_or     = "OR ({$wpdb->posts}.post_content LIKE '{$wpdb->placeholder_escape()}{$search_term}{$wpdb->placeholder_escape()}')";
                $new_or     = $old_or . " OR ({$wpdb->postmeta}.meta_value LIKE '{$wpdb->placeholder_escape()}{$search_term}{$wpdb->placeholder_escape()}' AND {$wpdb->postmeta}.meta_key IN (" . implode(', ', $GLOBALS['added_meta_field_to_search_query']) . "))";
                $search_sql = str_replace($old_or, $new_or, $search_sql);
            }
        }

        $search_sql = str_replace(" ORDER BY ", " GROUP BY $wpdb->posts.ID ORDER BY ", $search_sql);

        return $search_sql;
    });

}
发布评论

评论列表(0)

  1. 暂无评论