public function MultiversionStorageSchemaConverter::convertToMultiversionable in Multiversion 8.2
File
- src/
Entity/ Storage/ Sql/ MultiversionStorageSchemaConverter.php, line 64
Class
Namespace
Drupal\multiversion\Entity\Storage\SqlCode
public function convertToMultiversionable(array &$sandbox) {
// Return if the conversion for current entity type has been finished.
if (isset($sandbox[$this->entityTypeId]['finished']) && $sandbox[$this->entityTypeId]['finished'] == 1 || !empty($sandbox[$this->entityTypeId]['failed'])) {
return;
}
// Initialize entity types conversion.
$this
->initializeConversion($sandbox);
// If the condition is TRUE, then this will be the first run of the
// operation.
if (!isset($sandbox[$this->entityTypeId]['finished']) || $sandbox[$this->entityTypeId]['finished'] < 1) {
// Store the original entity type and field definitions in the $sandbox
// array so we can use them later in the update process.
$this
->collectOriginalDefinitions($sandbox);
// Create a temporary environment in which the new data will be stored.
$fields_to_update = $this
->getFieldsToUpdate();
$this
->createTemporaryDefinitions($sandbox, $fields_to_update);
// Create the updated entity schema using temporary tables.
/** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
$storage = $this->entityTypeManager
->getStorage($this->entityTypeId);
$storage
->setTemporary(TRUE);
$storage
->setEntityType($sandbox['temporary_entity_type']);
$storage
->onEntityTypeCreate($sandbox['temporary_entity_type']);
}
// Copy over the existing data to the new temporary tables.
$this
->copyData($sandbox);
// If the data copying has finished successfully, we can drop the temporary
// tables and call the appropriate update mechanisms.
if ($sandbox[$this->entityTypeId]['finished'] == 1) {
$sandbox['current_id'] = 0;
$this->entityTypeManager
->useCaches(FALSE);
$actual_entity_type = $this->entityTypeManager
->getDefinition($this->entityTypeId);
// Rename the original tables so we can put them back in place in case
// anything goes wrong.
$backup_table_names = array_combine($sandbox['original_table_mapping']
->getTableNames(), $sandbox['backup_table_mapping']
->getTableNames());
foreach ($backup_table_names as $original_table_name => $backup_table_name) {
$this->database
->schema()
->renameTable($original_table_name, $backup_table_name);
}
// Put the new tables in place and update the entity type and field
// storage definitions.
try {
$storage = $this->entityTypeManager
->createHandlerInstance($actual_entity_type
->getStorageClass(), $actual_entity_type);
$current_table_mapping = $storage
->getCustomTableMapping($actual_entity_type, $sandbox['updated_storage_definitions']);
$table_name_mapping = array_combine($sandbox['temporary_table_mapping']
->getTableNames(), $current_table_mapping
->getTableNames());
foreach ($table_name_mapping as $temp_table_name => $new_table_name) {
$this->database
->schema()
->renameTable($temp_table_name, $new_table_name);
}
// Rename the tables in the cached entity schema data.
$entity_schema_data = $this->installedStorageSchema
->get($this->entityTypeId . '.entity_schema_data', []);
foreach ($entity_schema_data as $temp_table_name => $schema) {
if (isset($table_name_mapping[$temp_table_name])) {
$entity_schema_data[$table_name_mapping[$temp_table_name]] = $schema;
unset($entity_schema_data[$temp_table_name]);
}
}
$this->installedStorageSchema
->set($this->entityTypeId . '.entity_schema_data', $entity_schema_data);
// Rename the tables in the cached field schema data.
foreach ($sandbox['updated_storage_definitions'] as $storage_definition) {
$field_schema_data = $this->installedStorageSchema
->get($this->entityTypeId . '.field_schema_data.' . $storage_definition
->getName(), []);
foreach ($field_schema_data as $temp_table_name => $schema) {
if (isset($table_name_mapping[$temp_table_name])) {
$field_schema_data[$table_name_mapping[$temp_table_name]] = $schema;
unset($field_schema_data[$temp_table_name]);
}
}
$this->installedStorageSchema
->set($this->entityTypeId . '.field_schema_data.' . $storage_definition
->getName(), $field_schema_data);
}
// Instruct the entity schema handler that data migration has been
// handled already and update the entity type.
$actual_entity_type
->set('requires_data_migration', FALSE);
$this->entityDefinitionUpdateManager
->updateEntityType($actual_entity_type);
// Update the field storage definitions.
$this
->updateFieldStorageDefinitionsToRevisionable($actual_entity_type, $sandbox['original_storage_definitions'], $fields_to_update);
// Install the published status field.
$this
->installPublishedStatusField($actual_entity_type);
// Install the fields provided by Multiversion.
$this
->installMultiversionFields($actual_entity_type);
// Multiversion makes changes for other fields, those updates need to be
// applied.
$this->entityTypeManager
->clearCachedDefinitions();
$field_definitions = $this->entityFieldManager
->getFieldStorageDefinitions($this->entityTypeId);
foreach ($field_definitions as $field_definition) {
$this->entityDefinitionUpdateManager
->updateFieldStorageDefinition($field_definition);
}
} catch (\Exception $e) {
// Something went wrong, bring back the original tables.
foreach ($backup_table_names as $original_table_name => $backup_table_name) {
// We are in the 'original data recovery' phase, so we need to be sure
// that the initial tables can be properly restored.
if ($this->database
->schema()
->tableExists($original_table_name)) {
$this->database
->schema()
->dropTable($original_table_name);
}
$this->database
->schema()
->renameTable($backup_table_name, $original_table_name);
}
// Re-throw the original exception.
throw $e;
}
// At this point the update process either finished successfully or any
// error has been handled already, so we can drop the backup entity
// tables.
foreach ($backup_table_names as $original_table_name => $backup_table_name) {
$this->database
->schema()
->dropTable($backup_table_name);
}
}
}