Two-Way ACF Relationship Field
Keeps a relationship field in sync on both sides, so linking post A to post B also links B back to A, and removing the link removes it from both.
Opens WPIDE on
Code
// Name of the relationship field used on both sides.
$wpide_acf_two_way_field = 'related_items';
add_filter( 'acf/update_value/name=' . $wpide_acf_two_way_field, function ( $value, $post_id, $field ) {
static $running = false;
if ( $running || ! is_numeric( $post_id ) || ! function_exists( 'update_field' ) ) {
return $value;
}
$running = true;
$post_id = (int) $post_id;
$new = array_filter( array_map( 'intval', (array) $value ) );
$old = array_filter( array_map( 'intval', (array) get_post_meta( $post_id, $field['name'], true ) ) );
// Add this post to newly linked posts.
foreach ( array_diff( $new, $old ) as $target ) {
$links = array_filter( array_map( 'intval', (array) get_post_meta( $target, $field['name'], true ) ) );
if ( ! in_array( $post_id, $links, true ) ) {
$links[] = $post_id;
update_field( $field['key'], array_values( array_filter( $links ) ), $target );
}
}
// Remove this post from posts that were unlinked.
foreach ( array_diff( $old, $new ) as $target ) {
$links = array_filter( array_map( 'intval', (array) get_post_meta( $target, $field['name'], true ) ) );
update_field( $field['key'], array_values( array_diff( $links, array( $post_id ) ) ), $target );
}
$running = false;
return $value;
}, 10, 3 );
Notes
Use the same relationship field on both post types (for example related_items). Existing links are updated the next time each post is saved.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.