You are here

public function SqlContentEntityStorageSchemaConverter::convertToRevisionable in Drupal 8

Converts an entity type with existing data to be revisionable.

This process does the following tasks:

  • creates the schema from scratch with the new revisionable entity type definition (i.e. the current definition of the entity type from code) using temporary table names;
  • loads the initial entity data by using the last installed entity and field storage definitions;
  • saves the entity data to the temporary tables;
  • at the end of the process:
    • deletes the original tables and replaces them with the temporary ones that hold the new (revisionable) entity data;
    • updates the installed entity schema data;
    • updates the entity type definition in order to trigger the \Drupal\Core\Entity\EntityTypeEvents::UPDATE event;
    • updates the field storage definitions in order to mark the revisionable ones as such.

In case of an error during the entity save process, the temporary tables are deleted and the original entity type and field storage definitions are restored.

Parameters

array $sandbox: The sandbox array from a hook_update_N() implementation.

string[] $fields_to_update: (optional) An array of field names that should be converted to be revisionable. Note that the 'langcode' field, if present, is updated automatically. Defaults to an empty array.

Throws

\Exception Re-throws any exception raised during the update process.

File

core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchemaConverter.php, line 92

Class

SqlContentEntityStorageSchemaConverter
Defines a schema converter for entity types with existing data.

Namespace

Drupal\Core\Entity\Sql

Code

public function convertToRevisionable(array &$sandbox, array $fields_to_update = []) {

  /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
  $this->entityTypeManager
    ->useCaches(FALSE);
  $entity_type = $this->entityTypeManager
    ->getDefinition($this->entityTypeId);

  /** @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $last_installed_schema_repository */
  $last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');
  $field_storage_definitions = $last_installed_schema_repository
    ->getLastInstalledFieldStorageDefinitions($this->entityTypeId);

  // Add the revision ID field.
  $field_name = $entity_type
    ->getKey('revision');
  $field_storage_definitions[$entity_type
    ->getKey('revision')] = BaseFieldDefinition::create('integer')
    ->setName($field_name)
    ->setTargetEntityTypeId($entity_type
    ->id())
    ->setTargetBundle(NULL)
    ->setLabel(t('Revision ID'))
    ->setReadOnly(TRUE)
    ->setSetting('unsigned', TRUE);

  // Add the 'revision_default' field.
  $field_name = $entity_type
    ->getRevisionMetadataKey('revision_default');
  $field_storage_definitions[$field_name] = BaseFieldDefinition::create('boolean')
    ->setName($field_name)
    ->setTargetEntityTypeId($entity_type
    ->id())
    ->setTargetBundle(NULL)
    ->setLabel(t('Default revision'))
    ->setDescription(t('A flag indicating whether this was a default revision when it was saved.'))
    ->setStorageRequired(TRUE)
    ->setTranslatable(FALSE)
    ->setRevisionable(TRUE);

  // Add the 'revision_translation_affected' field if needed.
  if ($entity_type
    ->isTranslatable()) {
    $field_name = $entity_type
      ->getKey('revision_translation_affected');
    $field_storage_definitions[$field_name] = BaseFieldDefinition::create('boolean')
      ->setName($field_name)
      ->setTargetEntityTypeId($entity_type
      ->id())
      ->setTargetBundle(NULL)
      ->setLabel(new TranslatableMarkup('Revision translation affected'))
      ->setDescription(new TranslatableMarkup('Indicates if the last edit of a translation belongs to current revision.'))
      ->setReadOnly(TRUE)
      ->setRevisionable(TRUE)
      ->setTranslatable(TRUE);
  }

  // Mark various fields as revisionable.
  $field_storage_definitions[$entity_type
    ->getKey('langcode')]
    ->setRevisionable(TRUE);
  foreach ($fields_to_update as $field_name) {
    $field_storage_definitions[$field_name]
      ->setRevisionable(TRUE);
  }
  $this->entityDefinitionUpdateManager
    ->updateFieldableEntityType($entity_type, $field_storage_definitions, $sandbox);
}