We had a request from one of our clients to be able to search in the admin area for a custom post type by another custom post type that are linked by an Advanced Custom Field (ACF) relationship.
This meant that the admin area search box would need to add a new search criteria for that new meta data. In this example, we have 2 custom post types - products and brands. Each product has a relationship Brand associated with it. We need to search the products for those brands.
add_action( 'pre_get_posts', 'acf_search_relationship' );
function acf_search_relationship( $q ) {
$s = $q->get('s');
$post_type = $q->get('post_type');
// Be very selective when running code at the pre_get_posts hook
if ( ! is_admin() || empty( $s ) || 'product' != $post_type ) {
return;
}
// get all brands that match the search parameter $s
$found_brands = get_posts( array(
'post_type' => 'brand',
'nopaging' => true,
'title' => $s,
'fields' => 'ids'
) );
// build a meta query to include all posts that contains
// the matching brands IDs in their custom fields
$meta_query = array('relation' => 'OR');
foreach ( $found_brands as $artist_id ) {
$meta_query[] = array(
'key' => 'brand', // name of custom field
'value' => '"'.intval($brand_id).'"',
'compare' => 'LIKE'
);
}
$q->set( 'meta_query', $meta_query );
$q->set( 's', '' ); // unset the original query parameter to avoid errors
}
This modifies the query before it get's the posts by setting a new meta query. It first searches for the Brands and grabs the IDs. Then it searches for Products that have the meta data that has those IDs.