function SqlContentEntityStorageSchema::onFieldStorageDefinitionDelete

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

Reacts to the deletion of a field storage definition.

Parameters

\Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition: The field being deleted.

Overrides FieldStorageDefinitionListenerInterface::onFieldStorageDefinitionDelete

File

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

Class

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

Namespace

Drupal\Core\Entity\Sql

Code

public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) {
  // If the field storage does not have any data, we can safely delete its
  // schema.
  if (!$this->storage
    ->countFieldData($storage_definition, TRUE)) {
    $this->performFieldSchemaOperation('delete', $storage_definition);
    return;
  }
  // There's nothing else we can do if the field storage has a custom storage.
  if ($storage_definition->hasCustomStorage()) {
    return;
  }
  $table_mapping = $this->getTableMapping($this->entityType, [
    $storage_definition,
  ]);
  $field_table_name = $table_mapping->getFieldTableName($storage_definition->getName());
  if ($table_mapping->requiresDedicatedTableStorage($storage_definition)) {
    // Move the table to a unique name while the table contents are being
    // deleted.
    $table = $table_mapping->getDedicatedDataTableName($storage_definition);
    $new_table = $table_mapping->getDedicatedDataTableName($storage_definition, TRUE);
    $this->database
      ->schema()
      ->renameTable($table, $new_table);
    if ($this->entityType
      ->isRevisionable()) {
      $revision_table = $table_mapping->getDedicatedRevisionTableName($storage_definition);
      $revision_new_table = $table_mapping->getDedicatedRevisionTableName($storage_definition, TRUE);
      $this->database
        ->schema()
        ->renameTable($revision_table, $revision_new_table);
    }
  }
  else {
    // Move the field data from the shared table to a dedicated one in order
    // to allow it to be purged like any other field.
    $shared_table_field_columns = $table_mapping->getColumnNames($storage_definition->getName());
    // Refresh the table mapping to use the deleted storage definition.
    $deleted_storage_definition = $this->deletedFieldsRepository()
      ->getFieldStorageDefinitions()[$storage_definition->getUniqueStorageIdentifier()];
    $table_mapping = $this->getTableMapping($this->entityType, [
      $deleted_storage_definition,
    ]);
    $dedicated_table_field_schema = $this->getDedicatedTableSchema($deleted_storage_definition);
    $dedicated_table_field_columns = $table_mapping->getColumnNames($deleted_storage_definition->getName());
    $dedicated_table_name = $table_mapping->getDedicatedDataTableName($deleted_storage_definition, TRUE);
    $dedicated_table_name_mapping[$table_mapping->getDedicatedDataTableName($deleted_storage_definition)] = $dedicated_table_name;
    if ($this->entityType
      ->isRevisionable()) {
      $dedicated_revision_table_name = $table_mapping->getDedicatedRevisionTableName($deleted_storage_definition, TRUE);
      $dedicated_table_name_mapping[$table_mapping->getDedicatedRevisionTableName($deleted_storage_definition)] = $dedicated_revision_table_name;
    }
    // Create the dedicated field tables using "deleted" table names.
    foreach ($dedicated_table_field_schema as $name => $table) {
      if (!$this->database
        ->schema()
        ->tableExists($dedicated_table_name_mapping[$name])) {
        $this->database
          ->schema()
          ->createTable($dedicated_table_name_mapping[$name], $table);
      }
      else {
        throw new EntityStorageException('The field ' . $storage_definition->getName() . ' has already been deleted and it is in the process of being purged.');
      }
    }
    try {
      if ($this->database
        ->supportsTransactionalDDL()) {
        // If the database supports transactional DDL, we can go ahead and rely
        // on it. If not, we will have to rollback manually if something fails.
        $transaction = $this->database
          ->startTransaction();
      }
      // Copy the data from the base table.
      $this->database
        ->insert($dedicated_table_name)
        ->from($this->getSelectQueryForFieldStorageDeletion($field_table_name, $shared_table_field_columns, $dedicated_table_field_columns))
        ->execute();
      // Copy the data from the revision table.
      if (isset($dedicated_revision_table_name)) {
        if ($this->entityType
          ->isTranslatable()) {
          $revision_table = $storage_definition->isRevisionable() ? $this->storage
            ->getRevisionDataTable() : $this->storage
            ->getDataTable();
        }
        else {
          $revision_table = $storage_definition->isRevisionable() ? $this->storage
            ->getRevisionTable() : $this->storage
            ->getBaseTable();
        }
        $this->database
          ->insert($dedicated_revision_table_name)
          ->from($this->getSelectQueryForFieldStorageDeletion($revision_table, $shared_table_field_columns, $dedicated_table_field_columns, $field_table_name))
          ->execute();
      }
    } catch (\Exception $e) {
      if ($this->database
        ->supportsTransactionalDDL()) {
        if (isset($transaction)) {
          $transaction->rollBack();
        }
      }
      else {
        // Delete the dedicated tables.
        foreach ($dedicated_table_field_schema as $name => $table) {
          $this->database
            ->schema()
            ->dropTable($dedicated_table_name_mapping[$name]);
        }
      }
      throw $e;
    }
    // Delete the field from the shared tables.
    $this->deleteSharedTableSchema($storage_definition);
  }
  unset($this->fieldStorageDefinitions[$storage_definition->getName()]);
}

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