Support

Account

Home Forums ACF PRO Showing reverse relationships within admin Reply To: Showing reverse relationships within admin

  • Ok so yep it seems like you need a relationship field in both. I’m not totally comfortable with storing the relationship twice – I feel like thats a sleeper-bug waiting to happen.

    ie:
    – Movie A stores thats it is GenreA, GenreB, and
    – GenreA stores (separately) that is has Movie A
    – GenreB stores (separately) that is has Movie A

    So, as a compromise, for each relation, I nominate one as the relationship owner and only it can edit the relationship. And for the non-relationship owner I have added the following meta box which will list all possible relations.

    
    // Helper to grab all possible post types that could contain relationships
    if (! function_exists('get_content_post_types')) {
        function get_content_post_types() {
            return array_merge(
                ['page', 'post'],
                array_values(get_post_types([ '_builtin' => false ]))
            );
        }
    }
    
    // Create a query that finds our parent id in the serialised array
    if (! function_exists('acf_find_parents')) {
        function acf_find_parents($id, $fields) {
            return new \WP_Query([
                'post_type' => get_content_post_types(),
                'meta_query' => [
                    'relation' => 'OR',
                    array_map(function($field) use ($id) {
                        return [
                            'key'       => $field,
                            'value'     => '"' .$id. '"',
                            'compare'   => 'LIKE'
                        ];
                    }, $fields),
                ]
            ]);
        }
    }
    

    And then the usage would be something like:

    
    // Inside the genre page
    // This would find all times that this post has existed in anothers relation
    acf_find_parents($post->ID, ['music', 'movies', 'books']);
    

    An example of formatting this nicely would be:

    
    // Using laravels collect methods
    add_action('add_meta_boxes', function() {
        add_meta_box('genre_relationships', 'Relationships', function($post) {
            collect(acf_find_parents($post->ID, ['music', 'movies'])->posts)
                ->groupBy('post_type')
                ->each(function($type, $key) {
                    echo "<h3>{$key}</h3>";
                    $type->each(function($related) {
                        echo "<div>{$related->post_title}</div>";
                    });
                });
        });
    });
    

    This would spit out:

    music
    song G
    song F
    movies
    movie A
    movie C

    Again, its a bit of a compromise, but I would prefer this over duplicating the data.

    Disclaimer: The query probably should extend to join against the post table to make the post_type is actually a acf field