Score:1

Programmatically update field config (not storage)

ru flag

SOLVED, both methods below work perfectly fine, it was just a typo.

I need to programmatically update a field's config in hook_update. I need to do this on multiple projects, so I can't use the normal way with field UI and config sync. I've found documentation how to update the field storage and DB schema (1, 2), but no documentation how to update a field config only, so I assumed I can go along with common ConfigFactory.

/**
 * Add my new paragraph to the list of allowed bundles in the host field config
 */
function MYMODULE_update_9001(&$sandbox) {
  $config = \Drupal::configFactory()->getEditable('field.field.node.BUNDLE.FIELD_NAME');
  $existingAllowedParagraphs = $config->get('settings.handler_settings.target_bundles');
  if (!in_array('NEW_PARAGRAPH_BUNDLE', $existingAllowedParagraphs )) {
    $dependencies = $config->get('dependencies.config');
    $dependencies[] = 'paragraphs.paragraphs_type.NEW_PARAGRAPH_BUNDLE';
    $config->set('dependencies.config', $dependencies);
    $config->set('settings.handler_settings.target_bundles.NEW_PARAGRAPH_BUNDLE', 'NEW_PARAGRAPH_BUNDLE');
    $config->set('settings.handler_settings.target_bundles_drag_drop.NEW_PARAGRAPH_BUNDLE', ['enabled' => true, 'weight' => 1234]);
    $config->save(TRUE);
  }
}

This worked only in active config (drush cex creates the expected, updated and correct YAML config), but weirdly not anywhere else. E.g. in Field UI or in the node edit form, everything works like the old, pre-hook config, it does not use the active config. I've tried doing multiple config imports and cache clears, but the field is not using the values from the ConfigFactory. I'm absolutely sure that my new config is correct and active, but somehow the field is now out of sync with its own config.

Update: I've also tried an alternative approach using FieldConfig, but the problem is exaclty the same: Proper active config, but no effect in field UI or node edit form.

/**
 * Add tour to allowed slides in DGM TV
 */
function wt_dgm_update_9011(&$sandbox) {
  /** @var $config Drupal\field\FieldConfigInterface */
  $config = Drupal\field\Entity\FieldConfig::loadByName('node', 'dgmtv', 'field_slides');
  $handlerSettings = $config->getSetting('handler_settings');
  $allowedParagraphs = $handlerSettings['target_bundles'];
  if (!in_array('dgmtour', $allowedParagraphs)) {
    $dependencies = $config->get('dependencies');
    $dependencies['config'][] = 'paragraphs.paragraphs_type.dgmtour';
    $config->set('dependencies', $dependencies);
    $handlerSettings['target_bundles']['dgmtour'] = 'dgmtour';
    $handlerSettings['target_bundles_drag_drop']['dgmtour'] = ['enabled' => true, 'weight' => 1234];
    $settings = $config->get('settings');
    $settings['handler_settings'] = $handlerSettings;
    $config->set('settings', $settings);
    $config->save();
  }
}

What else do I need to do so that the field uses the new config?

4uk4 avatar
cn flag
Is there a reason why you are loading the field config via the config factory? It could be necessary if your config contains mixed original languages. If you don't have this problem then try to load the config directly via `FieldConfig::loadByName()`.
ru flag
I personally find `ConfigFactory` much more comfortable to work with because it allows to directly manipulate `$config->get('very.deep.nested.settings')` and it works for any config. Tried with `FieldConfig` too, same problem.
ru flag
Gosh, it was just a typo with ninja-grade hiding skills: The core related stuff was correct, but I had an error in the Paragraphs field widget related part of the config.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.