1

After a D7 update and migration of fields, most of our problems with converted fields result from invalid or incompatible field settings. Field settings are stored in the
field_config_instance.data column in the database as serialized php objects.

How can I, for any given field instance, generate a fresh field configuration string, as if the field was just created in D7, while leaving the already stored field data intact?

My manual approach seems to work but is very cumbersome:

  • create a new content type
  • add an existing field to the new content type, generating new settings string
  • search the new and old field in the database
  • using sql: replacing the string in the data column of the old field (with the same name) with the new data content.

There must be a way to automate this a bit.

1

I guess you will need a combination of field_update_field() and field_create_field().

During field_create_field(), the settings are loaded from the default field definition as each field has defined in its own hook_field_info().

$field['settings'] += field_info_field_settings($field['type']);

What you are looking for is to apply this logic to field_update_field().

Basically you will need to load all fields:

$fields = field_info_fields();

Optionally limit the fields to your selection:

foreach ($fields as $field_name => $field) {
  if ($field['type'] == 'some type') {} // Filter by type
  if ($field_name == 'some name') {} // Filter by name
}

And update the fields:

$field['settings'] = field_info_field_settings($field['type']);
field_update_field($field);

So I guess it should look something like this:

$fields = field_info_fields();
foreach ($fields as $field_name => $field) {
  if ($field['type'] == 'some type') {
    $field['settings'] = field_info_field_settings($field['type']);
    field_update_field($field);
  }
}
|improve this answer|||||
  • Thank you for your answer, I think its very good information. I have run the suggested script and am printing the field settings before and after for all fields, however, the field settings appear unchanged whenever I run the script. Looking into the code of field_update_field. this line: $field['settings'] += $prior_field['settings']; computes the union of new and old settings. If I am not mistaken, this will always guarantee I will not loose any settings. In my case I need to remove the full settings record unfortunately, or at least remove some keys. – Michael Mar 18 '16 at 10:22
  • That is why I changed it into a regular = in the final snippet ;) – Neograph734 Mar 18 '16 at 10:51
  • I see, but what I am saying is that field_update_field contains the same logic inside (using +=), so I will never be able to delete anything from the settings when using this function, if I am correct. So whenever a field is missing in the new settings but present in the old settings, field_update_field will keep the old settings. – Michael Mar 18 '16 at 11:01
  • 1
    Ah I see what you mean, but that union will make sure all non-defined values in the settings array will be set with the values of the previous field. Since we redefine the whole settings array with its defaults, I assumed it should be good. If the result is not as expected you can place the contents of the complete field_update_field() function in the snippet above and remove the union. – Neograph734 Mar 18 '16 at 11:06
  • 1
    It might also be that modules implement hook_field_update_forbid. So you could attempt to bypass that as well. – Neograph734 Mar 18 '16 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.