Rebuild the entity bundle field map

By nnevill, 17 February, 2023

In latest Drupal9/Drupal10 entity bundle field map was moved from being generated on demand and cached to being saved in the key value store.

This data is being managed in the FieldDefinitionListener::onFieldDefinitionCreate() and FieldDefinitionListener::onFieldDefinitionDelete() methods. But there is a problem - only data related to specific field (which is being updated or deleted) is updating with the above methods.

Sometimes entity bundle field map could go out of sync – in case of fields machine names changes or some other custom  not very straightforward manipulations. That creates tons of annoying errors in logs.  So while core issue is still in progress here is the snippet to rebuild bundle field map in hook_post_update_NAME or hook_deploy whatever:

use Drupal\Core\Entity\FieldableEntityInterface;

/**
 * Rebuild the entity bundle field map.
 */
function custom_module_deploy_rebuild_entity_bundle_field_map() {
  $entity_bundle_info = \Drupal::service('entity_type.bundle.info');
  $entity_type_manager = \Drupal::service('entity_type.manager');
  $entity_field_manager = \Drupal::service('entity_field.manager');

  $map = [];
  foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
    if (!$entity_type->entityClassImplements(FieldableEntityInterface::class)) {
      continue;
    }
    foreach ($entity_bundle_info->getBundleInfo($entity_type_id) as $bundle => $bundle_info) {
      foreach ($entity_field_manager->getFieldDefinitions($entity_type_id, $bundle) as $field_name => $field_definition) {
        if (!$field_definition->getFieldStorageDefinition()->isBaseField()) {
          $map[$entity_type_id][$field_name]['type'] = $field_definition->getType();
          $map[$entity_type_id][$field_name]['bundles'][$bundle] = $bundle;
        }
      }
    }
  }

  $persistent_map = \Drupal::keyValue('entity.definitions.bundle_field_map');
  $persistent_map->setMultiple($map);
}

 

Short Description
Drupal snippet to programmatically regenerate entity bundle field map.