0

On a paragraph type, I have a field I want to migrate to a new field of type "list_string". To do that in the deployment and like our automatic deployment begin by an update of the database follow by importation of configurations, I want to create the new field programmatically before to do the migration in another hook_update.

I'm using the example of this article https://www.metaltoad.com/blog/programmatically-importing-drupal-8-field-configurations which is perfect except I have a problem because my new field is of type list_string. My configuration for field.storage is:

langcode: fr status: true dependencies: module: - options - paragraphs id: paragraph.field_types_link field_name: field_types_link entity_type: paragraph type: list_string settings: allowed_values: - value: anchor label: Ancre - value: internal label: Interne - value: external label: Externe allowed_values_function: '' module: options locked: false cardinality: 1 translatable: true indexes: { } persist_with_no_fields: false custom_storage: false 

When I create my new field based on my configuration file like that:

$field_storage_link = \Drupal::service('config.storage.sync')->read('field.storage.paragraph.field_types_link'); \Drupal::entityTypeManager()->getStorage('field_storage_config') ->create($field_storage_link) ->save(); 

I have this error.

[error] The configuration property settings.allowed_values.0.label.0 doesn't exist.

If I remove the list of allowed_values, it works and I can add my field to paragraphes bundles but in this case, I'm not able to do my migration properly because the allowed_values of my field are empty and I don't know how to update it programmatically. Someone can explain what's is the problem in my code and how to fix it?

2 Answers 2

2

I finish by find what was the problem. When I read the config file, my allowed value are of format:

[ [ 'value' => 'anchor', 'label' => 'Anchor' ], [ 'value' => 'internal', 'label' => 'Internal' ], [ 'value' => 'external', 'label' => 'External' ] ] 

But the FieldStorageConfig wait a format:

[ 'anchor' => 'Anchor', 'internal' => 'Internal', 'external' => 'External' ] 

So I add a transformation before to save my new field:

$field_storage_link = \Drupal::service('config.storage.sync')->read('field.storage.paragraph.field_types_link'); $allowed_values_link = []; foreach($field_storage_link['settings']['allowed_values'] as $value) { $allowed_values_link[$value['value']] = $value['label']; } $field_storage_link['settings']['allowed_values'] = $allowed_values_link; \Drupal::entityTypeManager()->getStorage('field_storage_config') ->create($field_storage_link) ->save(); $field_type_link = \Drupal::service('config.storage.sync')->read('field.field.paragraph.link_tdm.field_types_link'); \Drupal::entityTypeManager()->getStorage('field_config')->create($field_type_link)->save(); 

It works properly.

1

For others with the same issue, see this important comment by Berdir at https://www.drupal.org/project/drupal/issues/2944144#comment-12481021 saying:

That's not the correct way to create a config entity from config. Here's a snippet based on what I did just today:

 $module_handler = \Drupal::moduleHandler(); $config_storage = new FileStorage($module_handler->getModule('yourmodule')->getPath() . '/config/install'); foreach (['field.storage.user.field_name', 'field.field.user.user.field_name'] as $config_name) { $config_record = $config_storage->read($config_name); $entity_type = \Drupal::service('config.manager')->getEntityTypeIdByName($config_name); /** @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage($entity_type); $entity = $storage->createFromStorageRecord($config_record); $entity->save(); } 

The important part is "$entity = $storage->createFromStorageRecord($config_record);", the config structure and config entity structure doesn't always match 1:1.

I can confirm this solved the problem for me with the same error.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.