function SqlContentEntityStorageSchema::postUpdateEntityTypeSchema

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::postUpdateEntityTypeSchema()
  2. 10 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::postUpdateEntityTypeSchema()
  3. 11.x core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::postUpdateEntityTypeSchema()

Overrides SqlFieldableEntityTypeListenerTrait::postUpdateEntityTypeSchema

File

core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php, line 527

Class

SqlContentEntityStorageSchema
Defines a schema handler that supports revisionable, translatable entities.

Namespace

Drupal\Core\Entity\Sql

Code

protected function postUpdateEntityTypeSchema(EntityTypeInterface $entity_type, EntityTypeInterface $original, array $field_storage_definitions, array $original_field_storage_definitions, array &$sandbox = NULL) {
    
    /** @var \Drupal\Core\Entity\Sql\TableMappingInterface $original_table_mapping */
    $original_table_mapping = $sandbox['original_table_mapping'];
    
    /** @var \Drupal\Core\Entity\Sql\TableMappingInterface $new_table_mapping */
    $new_table_mapping = $sandbox['new_table_mapping'];
    
    /** @var \Drupal\Core\Entity\Sql\TableMappingInterface $backup_table_mapping */
    $backup_table_mapping = $sandbox['backup_table_mapping'];
    // Rename the original tables so we can put them back in place in case
    // anything goes wrong.
    $backup_table_names = array_combine($this->getTableNames($original, $original_field_storage_definitions, $original_table_mapping), $this->getTableNames($original, $original_field_storage_definitions, $backup_table_mapping));
    $renamed_tables = [];
    try {
        foreach ($backup_table_names as $original_table_name => $backup_table_name) {
            $this->database
                ->schema()
                ->renameTable($original_table_name, $backup_table_name);
            $renamed_tables[$original_table_name] = $backup_table_name;
        }
    } catch (\Exception $e) {
        foreach ($renamed_tables as $original_table_name => $backup_table_name) {
            $this->database
                ->schema()
                ->renameTable($backup_table_name, $original_table_name);
        }
        // Re-throw the original exception.
        throw $e;
    }
    // Put the new tables in place and update the entity type and field storage
    // definitions.
    try {
        foreach ($sandbox['temporary_table_names'] as $current_table_name => $temp_table_name) {
            $this->database
                ->schema()
                ->renameTable($temp_table_name, $current_table_name);
        }
        // Store the updated entity schema.
        $new_entity_schema = $sandbox['new_entity_schema'];
        $this->schema[$entity_type->id()] = $new_entity_schema;
        $this->entityType = $entity_type;
        $this->fieldStorageDefinitions = $field_storage_definitions;
        $this->saveEntitySchemaData($entity_type, $new_entity_schema);
        // The storage needs to use the updated definitions and table mapping
        // before generating and saving the final field schema data.
        $this->storage
            ->setEntityType($entity_type);
        $this->storage
            ->setFieldStorageDefinitions($field_storage_definitions);
        $this->storage
            ->setTableMapping($new_table_mapping);
        // Store the updated field schema for each field storage.
        foreach ($field_storage_definitions as $field_storage_definition) {
            if ($new_table_mapping->requiresDedicatedTableStorage($field_storage_definition)) {
                $this->createDedicatedTableSchema($field_storage_definition, TRUE);
            }
            elseif ($new_table_mapping->allowsSharedTableStorage($field_storage_definition)) {
                // The shared tables are already fully created, but we need to save
                // the per-field schema definitions for later use.
                $this->createSharedTableSchema($field_storage_definition, TRUE);
            }
        }
    } 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 thrown already. We can either keep the backup tables in
    // place or drop them.
    if (Settings::get('entity_update_backup', TRUE)) {
        $backup_key = $sandbox['backup_prefix_key'];
        $backup = [
            'entity_type' => $original,
            'field_storage_definitions' => $original_field_storage_definitions,
            'table_mapping' => $backup_table_mapping,
            'request_time' => $sandbox['backup_request_time'],
        ];
        $this->updateBackupRepository()
            ->set("{$original->id()}.{$backup_key}", $backup);
    }
    else {
        foreach ($backup_table_names as $original_table_name => $backup_table_name) {
            $this->database
                ->schema()
                ->dropTable($backup_table_name);
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.