Support

Account

Home Forums General Issues get_field() returns false until post is resaved, but i have 1000+ posts! Reply To: get_field() returns false until post is resaved, but i have 1000+ posts!

  • TLDR; You can’t trigger ACF to rebuild the field key references. You need to redo the migration so that the correct field key references are also moved.

    Long answer

    ACF doesn’t rebuild the metadata.

    Internally, ACF uses the field key. The field name is changeable and can be duplicated. The field name is only for our convenience.

    When displaying the fields for editing, ACF has the field key because it uses the field keys to display the fields for each post. It looks at the field key, gets the field object for that key, gets the field name from the field object and then uses get_post_meta() on that field name in combination with the current post ID to get the value of that field. This is why it can successfully get the values in the admin. It has both the post ID and the field key to work with.

    With more complex fields, like repeater sub fields ACF is recursing into the repeater and using additional information to generate the meta names that it uses to get the values.

    When you save a post in the admin the value/field you submit uses the field key, not the field name. Again, ACF already has the post ID and the field key. For each field submitted acf calls update_field($field_key, ). This causes ACF to get the field object and extract the name and then update both meta values.

    This has been asked here before and as far as I’m aware, no one has successfully created a way to rebuild all of the field key references for every post. To get ACF to add the correct field key reference you need to supply it with the field key, the post ID and then value for the field. If you are dealing with repeaters or other fields that have sub field you also need to provide the rows with “field key => value” pairs. And since the field key references either do not exist or are incorrect, you can’t use ACF to get the values in order to update them correctly. There is a viscous circle here which could potentially be overcome as long as you don’t have any repeaters, clones, flex fields or any other type of field that has sub fields. Thne you can loop over these groups and get the field in them, get each field name, get the value and then use ACF to update the field.

    
    $groups = acf_get_field_groups(array('post_id' => $post_id));
    foreach ($groups as $group) {
      $fields = acf_get_fields($group_key);
      foreach ($fields as $field) {
        $value = get_post_meta($post_id, $field['name'], true);
        update_field($field['key'], $value, $post_id); 
      }
    }
    

    But this falls apart as soon as you start dealing with sub fields. This would require building a recursive function on each field checking for field types that include sub fields. Each type of field would need to be handled independently. As to examples I will use a repeater vs a flex field. When you use get_post_meta() as above on a repeater field it returns a number that represents the number of rows in the repeater. When you get the value of a flex field it will return an array where each element of the array is the layout name used for that row. Based on this it would also need to check each sub field for it’s type and recurse again based on this, finally returning all of the values of all sub fields so that it can be correctly updated.

    And in the end, with a site with 1000+ posts, all this work would likely time out or exceed the max execution time do the the number of queries that WP would need to perform.