You are here

public static function DefaultTableMapping::create in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php \Drupal\Core\Entity\Sql\DefaultTableMapping::create()
  2. 10 core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php \Drupal\Core\Entity\Sql\DefaultTableMapping::create()

Initializes the table mapping.

@internal

Parameters

\Drupal\Core\Entity\ContentEntityTypeInterface $entity_type: The entity type definition.

\Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions: A list of field storage definitions that should be available for the field columns of this table mapping.

string $prefix: (optional) A prefix to be used by all the tables of this mapping. Defaults to an empty string.

Return value

static

1 call to DefaultTableMapping::create()
SqlContentEntityStorage::getCustomTableMapping in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Gets a table mapping for the specified entity type and storage definitions.

File

core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php, line 162

Class

DefaultTableMapping
Defines a default table mapping class.

Namespace

Drupal\Core\Entity\Sql

Code

public static function create(ContentEntityTypeInterface $entity_type, array $storage_definitions, $prefix = '') {
  $table_mapping = new static($entity_type, $storage_definitions, $prefix);
  $revisionable = $entity_type
    ->isRevisionable();
  $translatable = $entity_type
    ->isTranslatable();
  $id_key = $entity_type
    ->getKey('id');
  $revision_key = $entity_type
    ->getKey('revision');
  $bundle_key = $entity_type
    ->getKey('bundle');
  $uuid_key = $entity_type
    ->getKey('uuid');
  $langcode_key = $entity_type
    ->getKey('langcode');
  $shared_table_definitions = array_filter($storage_definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
    return $table_mapping
      ->allowsSharedTableStorage($definition);
  });
  $key_fields = array_values(array_filter([
    $id_key,
    $revision_key,
    $bundle_key,
    $uuid_key,
    $langcode_key,
  ]));
  $all_fields = array_keys($shared_table_definitions);
  $revisionable_fields = array_keys(array_filter($shared_table_definitions, function (FieldStorageDefinitionInterface $definition) {
    return $definition
      ->isRevisionable();
  }));

  // Make sure the key fields come first in the list of fields.
  $all_fields = array_merge($key_fields, array_diff($all_fields, $key_fields));
  $revision_metadata_fields = $revisionable ? array_values($entity_type
    ->getRevisionMetadataKeys()) : [];
  $revision_metadata_fields = array_intersect($revision_metadata_fields, array_keys($storage_definitions));
  if (!$revisionable && !$translatable) {

    // The base layout stores all the base field values in the base table.
    $table_mapping
      ->setFieldNames($table_mapping->baseTable, $all_fields);
  }
  elseif ($revisionable && !$translatable) {

    // The revisionable layout stores all the base field values in the base
    // table, except for revision metadata fields. Revisionable fields
    // denormalized in the base table but also stored in the revision table
    // together with the entity ID and the revision ID as identifiers.
    $table_mapping
      ->setFieldNames($table_mapping->baseTable, array_diff($all_fields, $revision_metadata_fields));
    $revision_key_fields = [
      $id_key,
      $revision_key,
    ];
    $table_mapping
      ->setFieldNames($table_mapping->revisionTable, array_merge($revision_key_fields, $revisionable_fields));
  }
  elseif (!$revisionable && $translatable) {

    // Multilingual layouts store key field values in the base table. The
    // other base field values are stored in the data table, no matter
    // whether they are translatable or not. The data table holds also a
    // denormalized copy of the bundle field value to allow for more
    // performant queries. This means that only the UUID is not stored on
    // the data table.
    $table_mapping
      ->setFieldNames($table_mapping->baseTable, $key_fields)
      ->setFieldNames($table_mapping->dataTable, array_values(array_diff($all_fields, [
      $uuid_key,
    ])));
  }
  elseif ($revisionable && $translatable) {

    // The revisionable multilingual layout stores key field values in the
    // base table and the revision table holds the entity ID, revision ID and
    // langcode ID along with revision metadata. The revision data table holds
    // data field values for all the revisionable fields and the data table
    // holds the data field values for all non-revisionable fields. The data
    // field values of revisionable fields are denormalized in the data
    // table, as well.
    $table_mapping
      ->setFieldNames($table_mapping->baseTable, $key_fields);

    // Like in the multilingual, non-revisionable case the UUID is not
    // in the data table. Additionally, do not store revision metadata
    // fields in the data table.
    $data_fields = array_values(array_diff($all_fields, [
      $uuid_key,
    ], $revision_metadata_fields));
    $table_mapping
      ->setFieldNames($table_mapping->dataTable, $data_fields);
    $revision_base_fields = array_merge([
      $id_key,
      $revision_key,
      $langcode_key,
    ], $revision_metadata_fields);
    $table_mapping
      ->setFieldNames($table_mapping->revisionTable, $revision_base_fields);
    $revision_data_key_fields = [
      $id_key,
      $revision_key,
      $langcode_key,
    ];
    $revision_data_fields = array_diff($revisionable_fields, $revision_metadata_fields, [
      $langcode_key,
    ]);
    $table_mapping
      ->setFieldNames($table_mapping->revisionDataTable, array_merge($revision_data_key_fields, $revision_data_fields));
  }

  // Add dedicated tables.
  $dedicated_table_definitions = array_filter($table_mapping->fieldStorageDefinitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
    return $table_mapping
      ->requiresDedicatedTableStorage($definition);
  });
  $extra_columns = [
    'bundle',
    'deleted',
    'entity_id',
    'revision_id',
    'langcode',
    'delta',
  ];
  foreach ($dedicated_table_definitions as $field_name => $definition) {
    $tables = [
      $table_mapping
        ->getDedicatedDataTableName($definition),
    ];
    if ($revisionable && $definition
      ->isRevisionable()) {
      $tables[] = $table_mapping
        ->getDedicatedRevisionTableName($definition);
    }
    foreach ($tables as $table_name) {
      $table_mapping
        ->setFieldNames($table_name, [
        $field_name,
      ]);
      $table_mapping
        ->setExtraColumns($table_name, $extra_columns);
    }
  }
  return $table_mapping;
}