Question

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.

Était-ce utile?

La solution 2

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;
    });

}

Autres conseils

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.
Licencié sous: CC-BY-SA avec attribution
Non affilié à wordpress.stackexchange
scroll top