AdvancedCustomFields / acf

Advanced Custom Fields
http://advancedcustomfields.com/
823 stars 168 forks source link

Loss of Repeater Field Data when Rearranging Layouts in Flexible Content #879

Open Mytraas opened 9 months ago

Mytraas commented 9 months ago

Describe the bug When using a Flexible Content field in ACF, which contains layouts that include Repeater fields, there is an issue where changing the order of the layouts in the WordPress admin interface results in the loss of data from the Repeater field within those layouts.

To Reproduce Create a Flexible Content field in ACF and add layouts that contain Repeater fields. Populate data in the Repeater fields within the layouts. In the WordPress admin interface, rearrange the order of the layouts within the Flexible Content field. Save the changes. Notice that the data in the Repeater fields has been erased.

Expected behavior Expectations: We expect that rearranging the layouts within the Flexible Content field should not result in data loss within the Repeater fields.

Statement I wanted to provide an update regarding the configuration change I made in PHP. As recommended in the discussion thread found here: Thread Link, I adjusted the max_input_vars to 10000.

Unfortunately, despite making this adjustment, the issue of data loss when updating Flexible Content fields persists. The rows continue to disappear in the backend as mentioned in the thread.

Screenshots or Video https://github.com/AdvancedCustomFields/acf/assets/33683465/def1c566-4254-410a-b5ce-08cd6d600431

Version Information:

Additional informations I've dug around in the ACF Pro code. It seems that this only happens when ACF fields are added directly via PHP code. The problem lies in the update_value function in /pro/fields/class-acf-field-repeater.php

In fact, the variable $old_rows = acf_get_value( $post_id, $field ); is empty, because ACF fetches the value of the field being updated to perform operations ( row updated, row deleted ... ) with the new Layout index in LayoutContent, but this index doesn't yet exist in the database. ACF should fetch the values in the current LayoutContent index for the old values.

Temporary Fix What I did to correct this problem was to modify this code:

// Update any existing rows that were edited.
foreach ( $edited_rows as $key => $row ) {
     if ( array_key_exists( $key, $old_rows ) ) {
          $old_rows[ $key ] = $row;
     }
}

To:

// Update any existing rows that were edited.
foreach ( $edited_rows as $key => $row ) {
     //if ( array_key_exists( $key, $old_rows ) ) {
          $old_rows[ $key ] = $row;
     //}
}

Additional context Thank you for considering this bug report and working towards its resolution. If additional information is required, please feel free to request it.

Mytraas commented 9 months ago

This is the JSON file that represents my ACF Fields structure

object(ACF_Data)#1038 (4) {
  ["cid"]=>
  string(5) "acf-9"
  ["data"]=>
  array(1) {
    ["group_aee8ef13"]=>
    array(6) {
      ["key"]=>
      string(14) "group_aee8ef13"
      ["title"]=>
      string(14) "Product Layout"
      ["local"]=>
      string(3) "php"
      ["menu_order"]=>
      int(2)
      ["location"]=>
      array(2) {
        [0]=>
        array(1) {
          [0]=>
          array(3) {
            ["param"]=>
            string(9) "post_type"
            ["operator"]=>
            string(2) "=="
            ["value"]=>
            string(7) "product"
          }
        }
        [1]=>
        array(1) {
          [0]=>
          array(3) {
            ["param"]=>
            string(9) "post_type"
            ["operator"]=>
            string(2) "=="
            ["value"]=>
            string(4) "page"
          }
        }
      }
      ["style"]=>
      string(8) "seamless"
    }
  }
  ["aliases"]=>
  array(0) {
  }
  ["multisite"]=>
  bool(false)
}
array(1) {
  [0]=>
  array(16) {
    ["ID"]=>
    int(0)
    ["key"]=>
    string(14) "group_aee8ef13"
    ["title"]=>
    string(14) "Product Layout"
    ["fields"]=>
    array(0) {
    }
    ["location"]=>
    array(2) {
      [0]=>
      array(1) {
        [0]=>
        array(3) {
          ["param"]=>
          string(9) "post_type"
          ["operator"]=>
          string(2) "=="
          ["value"]=>
          string(7) "product"
        }
      }
      [1]=>
      array(1) {
        [0]=>
        array(3) {
          ["param"]=>
          string(9) "post_type"
          ["operator"]=>
          string(2) "=="
          ["value"]=>
          string(4) "page"
        }
      }
    }
    ["menu_order"]=>
    int(2)
    ["position"]=>
    string(6) "normal"
    ["style"]=>
    string(8) "seamless"
    ["label_placement"]=>
    string(3) "top"
    ["instruction_placement"]=>
    string(5) "label"
    ["hide_on_screen"]=>
    array(0) {
    }
    ["active"]=>
    bool(true)
    ["description"]=>
    string(0) ""
    ["show_in_rest"]=>
    bool(false)
    ["local"]=>
    string(3) "php"
    ["_valid"]=>
    bool(true)
  }
}
amichel86 commented 8 months ago

I'm experiencing some what of the same issue with the Flexible Content field, yesterday all my data was there in one of my layouts, today I lost data in another layout. Fields have the same names but can that be the problem?

https://www.loom.com/share/1e16b5523766437e91c9c3a2339e2e56

Mytraas commented 8 months ago

Fields can have the same name as long as they are in different groups. This is literally a bug in ACF, I think.

amichel86 commented 8 months ago

Fields can have the same name as long as they are in different groups. This is literally a bug in ACF, I think.

You're right, I don't know why it wasn't working the first time, but everything's fine now. Thanks!

stilltli commented 5 months ago

We are experiencing the same issue, in our case the issue can be resolved, by not using pagination, i. e.: 'pagination' => 1, instead using 'pagination' => 0,

hopefully the issue can be resolved, because pagnation is actually a useful feature in that context.

Kind regards