Support

Account

Forum Replies Created

  • Just a quick post as I was looking for something similar (I think). Basically renaming fields leaves a lot of “stray” data.

    This is a limitation of the structure I believe – the name is used like a key/index so any change is basically the same as changing a db key. Typically, in non-WP applications, once a key is set, thats pretty much it – I couldn’t imagine one every really changing it. There is also exists the concept of field keys (the field_xxxxxxx values you see in places) – why they aren’t used instead I’m not entirely sure. I feel like certain levels of compromise were made to work with WP instead of against it.

    Anyway – one tactic I have been using more recently so I don’t up with lots of garbage data is working across a few environments (which you should be doing regardless!).

    My setup looks like:

    Dev: vagrant machine – WP + ACFPro.
    Anything goes, I change as much as needed, and when I feel like I have accumulated too much “stray” data from ACF I export the ACF json data, destroy the machine, and re-import it.

    Staging: hosted machine – WP + ACFPro.
    Code + ACF exports are sync’ed up from dev and data is synced down from Production. This is to test how new code changes/ACFPro fields work with the current set of data in Production. I never manipulated ACFPro directly in here through the interface.

    Production: hosted machine – WP + ACFPro.
    Code + ACF exports are sync’ed up from dev after being validated in staging. I never manipulated ACFPro directly in here through the interface.

    I find this minimizes my renames + stray data. As I find the most common time I rename is during development of a new feature while still nutting out what I need or want. I can confidently can nuts in dev, renaming, changing new fields/features because all the stray data is destroyed at a moments notice.

    The biggest catch is changing a name that has already been synced to production. In this case, I unfortunately have to wear that.

  • 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

  • Cool I will try it out in the next few hours and leave an update here to confirm either way for future readers. Thanks for help, I will touch base shortly

  • I just read through the code, looks really good. The example shows post<->post, but I would imagine it could be applied to any custom type (being that they all “inherit” from post anyway, in that strange lovely way WP does things).

    One follow up question – with different types (like Movie + Genre), would you add the Relationship ACF to both the movie and the genre for the above snippet to work correctly?

    As a sidenote, and in hindsight, I realise genre is really a poor example (ie could be taxonomy, but just an example 🙂 )

  • Hello @elliot – did this end up getting implemented?
    Our use case is our content authors need to be able to select a whole country to be “the center”. Searching for a country doesn’t appear to work (requires an actual address), so panning and zooming would work as an alternative.

Viewing 5 posts - 1 through 5 (of 5 total)