Hi,
just wanted to share something, in case someone runs into the same problem. I needed a way to include the content of several acf fields into my normal WP search. I came up with the following solution:
function advanced_custom_search( $where, &$wp_query ) {
global $wpdb;
if ( empty( $where )){
return $where;
}
// get search expression
$terms = $wp_query->query_vars[ 's' ];
// explode search expression to get search terms
$exploded = explode( ' ', $terms );
if( $exploded === FALSE || count( $exploded ) == 0 )
$exploded = array( 0 => $terms );
// reset search in order to rebuilt it as we whish
$where = '';
// get searcheable_acf, a list of advanced custom fields you want to search content in
$list_searcheable_acf = list_searcheable_acf();
foreach( $exploded as $tag ) :
$where .= "
AND (
(".$wpdb->prefix."posts.post_title LIKE '%$tag%')
OR (".$wpdb->prefix."posts.post_content LIKE '%$tag%')
OR EXISTS (
SELECT * FROM ".$wpdb->prefix."postmeta
WHERE post_id = ".$wpdb->prefix."posts.ID
AND (";
foreach ($list_searcheable_acf as $searcheable_acf) :
if ($searcheable_acf == $list_searcheable_acf[0]):
$where .= " (meta_key LIKE '%" . $searcheable_acf . "%' AND meta_value LIKE '%$tag%') ";
else :
$where .= " OR (meta_key LIKE '%" . $searcheable_acf . "%' AND meta_value LIKE '%$tag%') ";
endif;
endforeach;
$where .= ")
)
OR EXISTS (
SELECT * FROM ".$wpdb->prefix."comments
WHERE comment_post_ID = ".$wpdb->prefix."posts.ID
AND comment_content LIKE '%$tag%'
)
OR EXISTS (
SELECT * FROM ".$wpdb->prefix."terms
INNER JOIN ".$wpdb->prefix."term_taxonomy
ON ".$wpdb->prefix."term_taxonomy.term_id = ".$wpdb->prefix."terms.term_id
INNER JOIN ".$wpdb->prefix."term_relationships
ON ".$wpdb->prefix."term_relationships.term_taxonomy_id = ".$wpdb->prefix."term_taxonomy.term_taxonomy_id
WHERE (
taxonomy = 'post_tag'
OR taxonomy = 'category'
OR taxonomy = 'myCustomTax'
)
AND object_id = ".$wpdb->prefix."posts.ID
AND ".$wpdb->prefix."terms.name LIKE '%$tag%'
)
)";
endforeach;
return $where;
}
add_filter( 'posts_search', 'advanced_custom_search', 500, 2 );
function list_searcheable_acf(){
$list_searcheable_acf = array('my_field','my_second_field','my_third_field'); // add acf field_names that you want to search through
return $list_searcheable_acf;
}
This works like a charm for me and I do not need an additional plugin like relevanssi. Hope this is usefull for someone!
Hi @sixtyseven
Thank you for the tip! It’s great to see people sharing what they’ve learned! π
I’m not sure why you wouldn’t want to use a search-enhancing plugin like relevanssi or searchWP? They provide quite a bit more than just the ability to search meta etc. such as fuzzy matching and stopwords to name a few.
I’m always using a search-plugin for any site that utilise search.
Hi @sixtyseven,
First of all, thanks a lot for the tip.
Second : does your method work with repeaters ?
Thanks
@marvinlerouge: The enhanced database query searchs for post meta keys, that have the searchphrase as a value. As far as I can see, this would work with repeater fields as well:
$where .= " (meta_key LIKE '%" . $searcheable_acf . "%' AND meta_value LIKE '%$tag%') ";
let’s assume you have a repeater named ‘my_field’. In the Database, you will find entries like my_field_0_repeaterfieldname, my_field_1_repeaterfieldname, etc. So if you add either ‘my_field’ or ‘repeaterfieldname’ to the $list_searcheable_acf array, the above query will resolve i.e. to:
$where .= " (meta_key LIKE '%myfield%' AND meta_value LIKE '%$searchphrase%') ";
But as I stated before, I am by no means a real coder π
@sixtyseven : One big problem with this way is that, if you have numerous fields, the query can becomme reaaaallly complex. So i took it another way :
Pros :
Cons :
function save_searchable_content_meta($post_id, $post, $update) {
$fields = get_fields($post->ID);
if (array_key_exists("searchable_content", $fields)) {
unset($fields["searchable_content"]);
array_unshift($fields, $post->post_title, $post->post_content);
$str = sanitize_text_field(array_to_str($fields));
update_field("searchable_content", $str, $post_id);
}
}
add_action('save_post', 'save_searchable_content_meta', 10, 3);
If someone is looking for a solution to this problem is to recommend the plugin:
https://wordpress.org/plugins/acf-better-search/
This plugin adds to default WordPress search engine the ability to search by content from selected fields of Advanced Custom Fields plugin.
Everything works automatically, no need to add any additional code.
Does your code work only with ACF Pro or with the free version as well?
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
The most recent ACF Chat Friday featured a live demo of how to register CPTs directly in the plugin, one of our most requested features. Check out the summary below for a replay of the demo, and donβt forget to register for the next session! https://t.co/k2KQ3WWBAz
— Advanced Custom Fields (@wp_acf) March 9, 2023
© 2023 Advanced Custom Fields.
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.