Support

Account

Home Forums ACF PRO acf_add_local_field not updating on save when auto-adding fields

Solved

acf_add_local_field not updating on save when auto-adding fields

  • Hello

    I am writing a plugin that uses ACF. I have a custom post type (‘locations’), and I need a series of fields for each location post to display on an individual location post. In other words, when you edit Location 1, there are text, repeater, and image fields for Location 2 and similar text, repeater, and image fields for Location 3. When you edit Location 2, there are text, repeater, and image fields for Location 1 and text, repeater, and image fields Location 3. Each post will also have ‘default’ fields that are not relevant to the other location posts (‘Room Number’, etc.)

    I am able to get all of the fields to display. I add the default fields with acf_add_local_field_group via add_action('acf/init', ...):

    
    // Note: Plugin in is written using classes, I just have regular functions here.
    
    function Add_ACF_Location_Fields() {
        acf_add_local_field_group(
            array(
                'key' => 'group_1234',
                'title' => 'Location Settings',
                'fields' => array(
                    array (
                        'key' => 'field_1',
                        'label' => 'Room',
                        'name' => 'location_compartment_value',
                        'type' => 'text',
                    ),
                ),
                'location' => array (
                    array (
                        array (
                            'param' => 'post_type',
                            'operator' => '==',
                            'value' => 'locations',
                        ),
                    ),
                ),
            )
        );
    }

    Then, in another function, I add in fields with acf_add_local_field through a separate add_action('acf/init', ...):

    
    function Location_Specific_Fields() {
        // Get the post ID for post being edited
        $post_id = isset( $_GET['post'] ) ? $_GET['post'] : 0;
        
        // Blank array to hold location field arrays
        $fields = [];
    
        // Get all Locations
        $args = array(
            'post_type' => 'locations',
            'posts_per_page' => '800',
            'order' => 'menu_order',
            'order' => 'ASC'
        );
        $locs = new WP_Query($args);
    
        // Create fields for each location
        if( $locs->have_posts() ) :
            while( $locs->have_posts() ) : $locs->the_post();
                $cur_id = strval( get_the_id() );
    
                // Do not add fields for current post
                if( $cur_id === $post_id ) {
                    continue;
                }
    
                // Unique ID using ids of current post and target post
                $field_end_string = $post_id . $cur_id;
    
                // Showing just a text field here for sample purposes, but there 
                // are other fields that use the same logic.
                // *KEYS ARE UNIQUE from field to field but do not change*
                $fields[] = array (
                    'key' => 'field_foo_' . $field_end_string,
                    'label' => 'Foo',
                    'name' => 'foo_' . $field_end_string,
                    'type' => 'text',
                    'parent' => 'group_1234',
                );
    
            endwhile;
        endif;
    
        // Iterate through $fields array, add each child array as local field.
        foreach ($fields as $field) {
            acf_add_local_field($field);
        }
    }

    As I said, this will display all of the fields in the edit screen. Fields will save values on initial post creation (Add New).

    Once the post is published, the values of the fields added in Location_Specific_Fields() no longer update when their content is changed. However, the default fields added in Add_ACF_Location_Fields() do update.

    Is there a reason that the acf_add_local_field fields will not save on update?

  • Hi @iamhexcoder

    That’s because, at some point when ACF saves the data, the $_GET['post'] global variable is not available. Could you please try to get the ID like this:

    if( isset( $_GET['post'] ) ){
        $post_id = $_GET['post'];
    } elseif ( isset( $_POST['post_ID'] ) ){
        $post_id = $_POST['post_ID'];
    } else {
        $post_id = '0';
    }

    I hope this helps 🙂

  • Ermergerd, you’re a lifesaver @james!

    Thanks

  • @james

    This is now working and all of the fields are saving correctly, however now none of the fields added with acf_add_local_field are showing up for get_fields(). Any ideas as to why?

  • Hi @iamhexcoder

    That’s because The $_GET['post'] and $_POST['post_ID'] variables are not available on the front end. As a workaround, you need to check if the current page is the backend or front end and use the right hook like this:

    if( !is_admin() ){
        add_action('wp', 'Location_Specific_Fields');
    } else {
        add_action('acf/init', 'Location_Specific_Fields');
    }

    You also need to correctly set the post ID like this:

    if( !is_admin() ){
        
        global $post;
        $post_id = $post->ID;
        
    } else {
        
        if( isset( $_GET['post'] ) ){
            $post_id = $_GET['post'];
        } elseif ( isset( $_POST['post_ID'] ) ){
            $post_id = $_POST['post_ID'];
        } else {
            $post_id = '0';
        }
        
    }

    I hope this helps 🙂

  • Thanks @james

    Sorry for the double post, thought it might be a separate enough issue to warrant it’s own post.

    This works great! Thanks so much.

    One more question, if you don’t mind. Let’s say that there end up being 100-200 locations posts. Is this a crazy thing to do? Will the query really drag things out, or will there end up being so many fields that things will get really gunked up?

    Thanks so much, I appreciate all of your help!

    Cheers
    Shaun

  • Hi @iamhexcoder

    Actually, I don’t really understand why you want to generate the fields based on the posts. Could you please explain it to me again? I think if you have a lot of posts in the future, it will make the backend looks messy. If you still want to do it, don’t forget to update your server’s max_vars variable so all of the values can be saved. This page should give you more idea about it: https://www.advancedcustomfields.com/resources/limit-number-fields/.

    Thanks 🙂

  • Each post is a physical location, and the client needs to create directions between each of the locations. So there needs to be a set of direction from location 1 to locations 2 and 3, from location 2 to 1 and 3, etc.

    Things will be a bit messy, but it’s the data that is needed!

    Thanks again for all of your help!!

    Cheers
    Shaun

  • Hi @iamhexcoder

    If they need to add directions from one location to the rest of the available locations, then I think your solution is the best. In this case, maybe grouping the locations would make it looks better.

    Anyway, I’m glad the issue is sorted now 🙂

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

You must be logged in to reply to this topic.