Change record status: 
Project: 
Introduced in branch: 
8.7.x
Introduced in version: 
8.7.0
Description: 

Starting with Drupal 8.7.0, the Entity system provides a new Update API for converting the schema of a content entity type from (non-)revisionable/(non-)translatable to revisionable/translatable, which also works when there is pre-existing data for the entity type whose schema is being changed.

Note that schema conversions when there is existing data are only supported when executed through a hook_post_update_NAME() implementation, because they need to run in a batch process.

New APIs introduced:

  • \Drupal\Core\Entity\EntityDefinitionUpdateManager has a new method: updateFieldableEntityType(EntityTypeInterface $entity_type, array $field_storage_definitions, array &$sandbox = NULL)
  • \Drupal\Core\Entity\EntityTypeListenerInterface has a new method: onFieldableEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeInterface $original, array $field_storage_definitions, array $original_field_storage_definitions, array &$sandbox = NULL)
  • \Drupal\Core\Entity\EntityStorageInterface has a new method: restore(EntityInterface $entity)
  • a new trait \Drupal\Core\Entity\Sql\SqlFieldableEntityTypeListenerTrait was introduced to allow other entity storage implementations to re-use the data copying logic

Example conversions from a non-revisionable to a revisionable schema for entity types provided by Drupal core can be found in the following issues:

Impacts: 
Site builders, administrators, editors
Module developers
Site templates, recipes and distribution developers

Comments

svart’s picture

I find it interesting that Drupal 8 supports a built-in way to change entity fields definition.

I need just that and change a integer field to a numeric field.

Does this new API supports a type change for a field with existing data (I don't think so, as the field type is not part of the field definition) ?

If not, does the following documentation uses the right process : https://www.drupal.org/node/2554097 ?

[EDIT]

I tried the following, but ends up with a Drupal\Core\Entity\EntityStorageException : Unsupported entity type

 function mymodule_post_update_0011_field_conversion(array $sandbox) {
    $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
    $last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');

    $entity_type = $definition_update_manager->getEntityType('my_entity_id');
    $field_storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions('my_entity_id');

    // Update field already existing in $field_storage_definitions
   // I also tried to create a new field, with the same outcome.
    $field_storage_definitions['order_vat'] = BaseFieldDefinition::create('decimal')
      ->setLabel(t('Order VAT Rate'))
      ->setDescription(t('Order VAT Rate.'))
      ->setSettings(['precision' => 5, 'scale' => 2]);

    \Drupal::entityDefinitionUpdateManager()
      ->updateFieldableEntityType($entity_type, $field_storage_definitions,$sandbox);
  }