Support

Account

Home Forums Bug Reports Problems manually updating a repeater field via code on a newly inserted post

Solved

Problems manually updating a repeater field via code on a newly inserted post

  • I’m writing a script to convert a lot of data into WP posts with acf fields. Part of the field group I’ve setup is based on a repeater field.

    I’m programmatically inserting a new post, then calling “update_field” to update the various fields. All the fields are updating correctly EXCEPT for the repeater field.

    After some experimentation I’ve discovered that the exact same code does work IF a post already exists and you’ve already added a row to the repeater field.

    I’ve stepped through the code and think I’ve determined that the problem occurs at the point when ACF gets the field definition for the repeater field.

    If the repeater has been previously saved manually through the admin interface, the call to acf_maybe_get_field() in api-template.php line 1509 returns the correct definition of the repeater field complete with subfields, and then the code goes on to use this definition to update the repeater field correctly.

    If the repeater HAS NOT been previously saved manually, the call to acf_maybe_get_field() returns null, and the code goes on to call acf_get_valid_field() on line 1515, which seems to return an incomplete definition of the repeater field. The code then goes on to incorrectly save the repeater data (it ends up with the array of repeater data serialized into a single field in the db)

    Obviously there’s loads going on behind the scenes that I don’t know about, and I couldn’t isolate the problem any better.

    Has anyone encountered this before and got a workaround? Unforunately there’s too much data to go in and work around things manually!

  • Might be worth mentioning that the repeater field also includes a clone field, unsure if this could be related

  • Ok I appear to have solved my own problem! This always happens to me…

    The solution was to use the field key (field_57b49219ff949) rather than the human readable field name.

    Odd that the human readable name works in most situations but not others.

  • The field name will work on posts on in situations where a value for a field already exists in the database, and it will usually work with fields that are simple text content like text, textarea, single select fields, radio and some others.

    The problem comes in with special types of fields like repeaters, flex fields, checkboxes, relationship, and many others fields that store values in complicated ways other than simple text values or include multiple database entries. For these ACF needs the field key to know how to store the value. It gets the field key by looking in the database for the meta key "_{$field_name}". Since this entry does not exist for posts that do not already have a value, ACF does not know what to do with the value so assumes it is a simple text value.

    In the case of a repeater the value is probably serialized by WP. Then when ACF tries to retrieve the value later if doesn’t know what to do with the value because it’s not in the correct format so it just ignores it, possibly triggering a PHP error in the process.

  • I’m having the same issue on a multisite instance, in which I have a child theme (which in no way modifies the core ACF functionality) which takes its ACF field definitions from the parent theme.

    1. On the child theme/multi-sites the get_field(‘handle’) returns an int (the number of items in repeater).

    2. If I try get_field(‘machine_name’), it returns NULL on the child site (and works perfectly with the parent theme).

    3. I have duplicated the EXACT same post_meta on the child, to the same effect. In fact if I migrate the DB info from child -> prod, it still works fine.

    4. This bug was introduced during the last wordpress update to 4.6.

    5. The only way I’ve been able to patch this bug is by reverting to wordpress 4.5.x

    6. In the call to get_field ‘acf_maybe_get_field’ returns no results for child, but proper results from parent.

    7. I setup a new twentysixteen theme (non multi-site) instance and was NOT able to reproduce this bug. (I will try setting up a multisite (subdomain) instance to see if it is reproducible there, but I have the feeling that it isn’t related to parent/child, other than the fact that 9 instances (multi-sites) running the parent theme are totally fine, but the 3 child themes are all exhibiting this bug).

    8. Let me know if I should open up my own bug report, but this IS the same bug in which acf calls a repeater and “ACF does not know what to do with the value so assumes it is a simple text value.”

  • Ok, I too fixed my own problem, but the bug is traced to something in the ACF documention (https://www.advancedcustomfields.com/resources/register-fields-via-php/ see “Add within an action“)

    So the issue is that if you are registering your ACF fields via php (which is very good for multi-sites with shared ACF fields), there is a case (and a darn rare one), in which get_field is being called before the action has ran its course, which leads the acf local fields array to only be partially populated. Therefore acf_get_local_field($key) returns false, and instead of returning the complex object, it just returns the value at the key index in the DB, which for a repeater, returns the number of items in said repeater.

    TL;DR;

    If you are enqueuing your ACF fields in an action (and exhibiting this bug), don’t add them to ‘acf/init’, add them to regular ‘init’, and then the local_field array is populated before any instance of get_field is called.

    ACF peeps? Can you please fix child theme calls to get_field, in which the parent theme is registering acf fields (on ‘acf/init’) or change your documentation to tell people to call their php includes of acf fields at wordpress’s ‘init’?

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

You must be logged in to reply to this topic.