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 badges2 Answers
Reset to default 2Have 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;
});
}