OK, so I’ve done some debugging and I know where your problem lies…
First of all in update
function:
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
if ( empty( $this->fields ) ) {
return $instance;
}
$instance = $this->save_fields( $new_instance, $old_instance );
return $instance;
}
You shouldn’t use $old_instance
as starting point. What if the list of fields is changed? Old values shouldn’t get copied to new instance. So you should use this instead:
public function update( $new_instance, $old_instance ) {
$instance = array();
if ( empty( $this->fields ) ) {
return $instance;
}
$instance = $this->save_fields( $new_instance, $old_instance );
return $instance;
}
But then there is one more problem in save_fields
function… Again, you start with $old_instance
as starting point:
public function save_fields( $new_instance, $old_instance, $parent_container = null ) {
// Vars
$instance = $old_instance;
$widget_fields = $this->fields;
if( isset( $parent_container ) ){
$widget_fields = $widget_fields[ $parent_container ]['sub_fields'];
}
// Loop fields and get values to save.
foreach ( $widget_fields as $key => $setting ) {
$setting_type = isset( $setting['type'] ) ? $setting['type'] : '';
// Format the value based on fields type.
switch ( $setting_type ) {
case 'group':
$group_instance = $this->save_fields( $new_instance, $old_instance, $key );
$instance = array_merge( $group_instance, $instance );
break;
So if given field is a group, then:
- You get its fields values using recursive call.
- In that call you:
- Initiate values with old_instance.
- Get fields from that group and set their values.
- Merge group values with instance values.
So there are few problems here:
- in 3. the values for group fields contains not only values for that group, because they were initiated with
old_instance
, - in 3. you overwrite new values from
group_instance
with old values frominstance
(which contains old values, because it is also initiated withold_instance
).
So how to fix that?
It’s a really simple fix, this time. All you need to do is to change:
$instance = $old_instance;
to:
$instance = array();
in both update
and save_fields
functions.
It works like a charm after that change.