Intercept Advanced Custom Fields (ACF) Relationship Field Searches
Advanced Custom Fields has the option of adding a search input to Relationship fields:
By default SearchWP will not intercept these searches, but using this snippet you can make that happen:
<?php | |
// Callback to have SearchWP intercept ACF Relationship field searches. | |
function my_searchwp_acf_relationship_field_search( $args, $field, $post_id ) { | |
if ( empty( $args['s'] ) || ! class_exists( 'SWP_Query' ) ) { | |
return $args; | |
} | |
// Assume that the SearchWP engine to use is the defined admin search engine | |
// from SearchWP's Advanced settings screen. | |
$searchwp_advanced_settings = searchwp_get_option( 'advanced' ); | |
$searchwp_admin_engine = ! empty( $searchwp_advanced_settings['admin_engine'] ) | |
? $searchwp_advanced_settings['admin_engine'] : 'default'; | |
$searchwp_args = array( | |
'engine' => $searchwp_admin_engine, // The SearchWP engine to use. | |
's' => $args['s'], // Pass along the search query. | |
'fields' => 'ids', // Return only post IDs. | |
); | |
if ( ! empty( $args['taxonomy' ] ) ) { | |
$tax_arg = explode( ':', $args['taxonomy'] ); | |
$searchwp_args['tax_query'] = array( | |
array( | |
'taxonomy' => $tax_arg[0], | |
'field' => 'slug', | |
'terms' => $tax_arg[1], | |
), | |
); | |
} | |
if ( ! empty( $args['post_type'] ) ) { | |
$searchwp_args['post_type'] = $args['post_type']; | |
} | |
// Tell SearchWP to NOT log this search. | |
add_filter( 'searchwp_log_search', '__return_false' ); | |
// Retrieve SearchWP results. | |
$results = new SWP_Query( $searchwp_args ); | |
// If there are no results, we need to force ACF to reflect that. | |
if ( empty( $results->posts ) ) { | |
$results->posts = array( 0 ); | |
} | |
// We're going to use SearchWP's results to handle the restrictions as outlined. | |
$args['s'] = ''; | |
$args['order'] = ''; | |
$args['orderby'] = 'post__in'; | |
$args['post__in'] = $results->posts; | |
return $args; | |
} | |
// Tell SearchWP to intercept all ACF Relationship field searches. | |
add_filter( | |
'acf/fields/relationship/query', | |
'my_searchwp_acf_relationship_field_search', | |
90, | |
3 | |
); | |
// Tell SearchWP to intercept a single ACF Relationship field search. | |
// add_filter( | |
// 'acf/fields/relationship/query/name=my_acf_relationship_field_name', | |
// 'my_searchwp_acf_relationship_field_search', | |
// 100, | |
// 3 | |
// ); |
There are a couple of things to note with this snippet:
You can control which Relationship field(s) utilize SearchWP for searches. Lines 58-63 use ACF’s hook to apply SearchWP’s results to all Relationship field searches.
If instead you want to pick and choose which Relationship fields you’d like SearchWP to work with, comment out lines 58-63 and uncomment lines 66-71 making sure to update my_acf_relationship_field_name
with the name of one of your Relationship fields. You can repeat the hook (updating the Relationship field name) for each additional field as well.
The second thing to note is that the my_searchwp_acf_relationship_field_search
callback (which is what actually modifies the ACF search results for this use case) uses the SearchWP engine that you have defined as the Admin search engine on the Advanced tab of the SearchWP settings screen.
If you’d like to override that you can provide the SearchWP engine name to use on line 16 of the snippet.
Once this hook is in place SearchWP will intercept the applicable Advanced Custom Fields Relationship Field searches, returning results from SearchWP itself.