Skip to content
Advertisement

ACF Repeater field returns string containing the count of repeater

When I use get_field('repeater_name') it returns a string that contains the a number which is the count of the repeater while it should return array of sub-fields, this issue have been reported repeatedly before but none of them provided a stable fix to this, the only way is to edit the post and hit the update button and it will re-generate the repeater fields, but in my case, I have 19k posts and it’s not possible to edit each post.

Also have_rows('repeater_name') returns false as expected and the real field data (get_post_meta($post_id, "field_{$field_key}", true) returns NULL

I would appreciate any help or any automated script that regenerates the repeater field keys and populate the values of all posts.

This issue is reported previously in here, here and here and none came with a real fix.

EDIT: I spotted the problem, the problem is in wp_postmeta table, the wrong field keys are stored:

wp_postmeta table

| meta_key                | meta_value    | 
| -------------           |:-------------:|
| _repeater_name          | field_XXXXXXX |
| _repeater_0_subfield    | field_ABCDEFG |
| _repeater_0_subfield2   | field_HIJKLMN |

The same field keys should match in wp_posts table, but they don’t (maybe due to data migration or whatever reason):

| post_excerpt   | post_name     | post_type | 
| ---------------| ------------- |-----------|
| repeater_name  | field_YYYYYYY | acf-field |
| subfield       | field_BBBBBBB | acf-field |
| subfield2      | field_CCCCCCC | acf-field |

I think if there’s a way to sync field keys in the database, that will fix the problem

Advertisement

Answer

I made a solution for this, might not be the exact solution for this problem but it worked out for me, first i somehow reverted my fields to a version which around 60% of fields worked well, and for the rest i wrote this backward compatibility:

function dw_build_repeater($name, $keys = [], $post = null) {
    $post = get_post($post);

    $repeater = get_field($name, $post->ID);

    if (! $repeater || is_array($repeater) || ! is_numeric($repeater)) {
        return;

    }

    $arr = [];

    for ($i = 0; $i < (int) $repeater; $i++) {

        foreach ($keys as $key) {
            $arr[$i][$key] = get_post_meta($post->ID, $name . "_" . $i . "_{$key}");
        }
    }

    update_field($name, $arr, $post->ID);

    return $arr;
}

so whenever i want to call a repeater i simply do this:

if (have_rows('repeater_name') || dw_build_repeater('repeater_name', ['subfield1', 'subfield2', 'subfield3']) {
     while (have_rows('repeater_name')) {
          the_row();
          // And the rest
     }

}

I haven’t tested it with nested repeaters but i suppose it might not be working with nested repeaters.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement