How to bulk edit ACF Repeater fields
ACF Repeater is a special field type that stores multiple rows of data — for example a list of video URLs, a set of specifications, or any repeating group of subfields. Each row is a separate entry and ACF stores them as a structured array in the database, not a simple string.
This means that editing a Repeater subfield directly in BEAR (by adding it as a meta column) will technically save the value, but ACF will not recognize it as a valid repeater row — so the data will not appear on the front-end. To make it work correctly you need a custom hook that intercepts the save and writes the data through the ACF API.
—
How ACF Repeater fields look in BEAR
When you add subfields of a Repeater to BEAR via the Meta Fields tab, they appear with keys like:
my_repeater_0_my_subfield
my_repeater_1_my_subfield
my_repeater_2_my_subfield
The number in the middle is the row index (starting from 0). So my_repeater_0_my_subfield is row 1, my_repeater_1_my_subfield is row 2, and so on.
Do not add the Repeater field itself (e.g. my_repeater) to BEAR — only the individual subfields.
—
The hook
Add the following code to your active theme’s functions.php file. Adjust the field key names to match your own ACF setup.
add_filter('woobe_before_update_product_field', function($value, $product_id, $field_key) {
// Define your repeater field name and subfield name
$repeater_name = 'my_repeater'; // your ACF Repeater field key
$subfield_name = 'my_subfield'; // your subfield key inside the Repeater
// List all subfield keys you added to BEAR (one per repeater row)
$handled_keys = array(
$repeater_name . '_0_' . $subfield_name,
$repeater_name . '_1_' . $subfield_name,
$repeater_name . '_2_' . $subfield_name,
$repeater_name . '_3_' . $subfield_name,
$repeater_name . '_4_' . $subfield_name,
$repeater_name . '_5_' . $subfield_name,
);
if (!in_array($field_key, $handled_keys)) {
return $value; // not our field, skip
}
// Extract row index from field key, e.g. "my_repeater_2_my_subfield" → 2
preg_match_all('/\d+/', $field_key, $matches);
$row_index = isset($matches[0][0]) ? intval($matches[0][0]) : null;
if ($row_index === null) {
return $value;
}
// Load current repeater data
$repeater = get_field($repeater_name, $product_id);
if ($repeater != null AND is_array($repeater)) {
// Repeater exists - update or delete the row
$rows = $repeater;
// Make sure the row exists in the array
if (!isset($rows[$row_index])) {
$rows[$row_index] = array($subfield_name => null);
}
if ($value == '' || $value == null) {
// Empty value - remove the row
unset($rows[$row_index]);
} else {
// Set the new value for this row
$rows[$row_index] = array($subfield_name => $value);
}
} else {
// Repeater is empty - create from scratch
$rows = array();
$rows[$row_index] = array($subfield_name => $value);
}
// Save the updated repeater back via ACF API
update_field($repeater_name, $rows, $product_id);
return $value;
}, 12, 3);
—
Important rules
- Fill rows in order. Always fill row 0 first, then row 1, then row 2, and so on. If you skip a row (e.g. fill row 2 before row 1), the array structure will be incorrect and ACF will not read it properly.
- To delete a row — clear the value in the last filled row first, then work backwards. This way the sequence stays clean.
- Do not add the Repeater field itself to BEAR — only the individual subfields (the ones with numbers in their keys). The Repeater count is managed automatically by the hook.
- To add more rows — just add more entries to the
$handled_keysarray in the code, following the same pattern.
—
How to find your field keys
The easiest way is to look at the database. Go to any product that already has some data in your Repeater, open BEAR → Meta Fields tab, click Get keys from product by ID, enter that product ID and press Get. You will see all meta keys for that product — look for keys following the pattern repeater_N_subfield.
Alternatively, inspect the ACF field group settings — the field key is shown there for each field.
—
Note on multiple subfields per row
The example above assumes one subfield per row. If your Repeater has multiple subfields per row (e.g. a URL and a title), extend the row array accordingly:
$rows[$row_index] = array(
'my_subfield_url' => $url_value,
'my_subfield_title' => $title_value,
);
In this case you would need a separate hook condition for each subfield key, building the full row from the current values before saving.
Ref: https://pluginus.net/support/topic/acf-repeater-problem-view-on-front/
