You are here

public function SqlContentEntityStorage::getTableMapping in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php \Drupal\Core\Entity\Sql\SqlContentEntityStorage::getTableMapping()

Gets a table mapping for the entity's SQL tables.

Parameters

\Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions: (optional) An array of field storage definitions to be used to compute the table mapping. Defaults to the ones provided by the entity manager.

Return value

\Drupal\Core\Entity\Sql\TableMappingInterface A table mapping object for the entity's tables.

Overrides SqlEntityStorageInterface::getTableMapping

13 calls to SqlContentEntityStorage::getTableMapping()
SqlContentEntityStorage::buildQuery in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Builds the query to load the entity.
SqlContentEntityStorage::countFieldData in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Determines the number of entities with values for a given field.
SqlContentEntityStorage::deleteFromDedicatedTables in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Deletes values of fields in dedicated tables for all revisions.
SqlContentEntityStorage::deleteRevisionFromDedicatedTables in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Deletes values of fields in dedicated tables for all revisions.
SqlContentEntityStorage::doSaveFieldItems in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Writes entity field values to the storage.

... See full list

File

core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php, line 277
Contains \Drupal\Core\Entity\Sql\SqlContentEntityStorage.

Class

SqlContentEntityStorage
A content entity database storage implementation.

Namespace

Drupal\Core\Entity\Sql

Code

public function getTableMapping(array $storage_definitions = NULL) {
  $table_mapping = $this->tableMapping;

  // If we are using our internal storage definitions, which is our main use
  // case, we can statically cache the computed table mapping. If a new set
  // of field storage definitions is passed, for instance when comparing old
  // and new storage schema, we compute the table mapping without caching.
  // @todo Clean-up this in https://www.drupal.org/node/2274017 so we can
  //   easily instantiate a new table mapping whenever needed.
  if (!isset($this->tableMapping) || $storage_definitions) {
    $definitions = $storage_definitions ?: $this->entityManager
      ->getFieldStorageDefinitions($this->entityTypeId);
    $table_mapping = new DefaultTableMapping($this->entityType, $definitions);
    $definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
      return $table_mapping
        ->allowsSharedTableStorage($definition);
    });
    $key_fields = array_values(array_filter(array(
      $this->idKey,
      $this->revisionKey,
      $this->bundleKey,
      $this->uuidKey,
      $this->langcodeKey,
    )));
    $all_fields = array_keys($definitions);
    $revisionable_fields = array_keys(array_filter($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));

    // Nodes have all three of these fields, while custom blocks only have
    // log.
    // @todo Provide automatic definitions for revision metadata fields in
    //   https://www.drupal.org/node/2248983.
    $revision_metadata_fields = array_intersect(array(
      'revision_timestamp',
      'revision_uid',
      'revision_log',
    ), $all_fields);
    $revisionable = $this->entityType
      ->isRevisionable();
    $translatable = $this->entityType
      ->isTranslatable();
    if (!$revisionable && !$translatable) {

      // The base layout stores all the base field values in the base table.
      $table_mapping
        ->setFieldNames($this->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($this->baseTable, array_diff($all_fields, $revision_metadata_fields));
      $revision_key_fields = array(
        $this->idKey,
        $this->revisionKey,
      );
      $table_mapping
        ->setFieldNames($this->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($this->baseTable, $key_fields)
        ->setFieldNames($this->dataTable, array_values(array_diff($all_fields, array(
        $this->uuidKey,
      ))));
    }
    elseif ($revisionable && $translatable) {

      // The revisionable multilingual layout stores key field values in the
      // base table, except for language, which is stored in the revision
      // table 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($this->baseTable, array_values($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, array(
        $this->uuidKey,
      ), $revision_metadata_fields));
      $table_mapping
        ->setFieldNames($this->dataTable, $data_fields);
      $revision_base_fields = array_merge(array(
        $this->idKey,
        $this->revisionKey,
        $this->langcodeKey,
      ), $revision_metadata_fields);
      $table_mapping
        ->setFieldNames($this->revisionTable, $revision_base_fields);
      $revision_data_key_fields = array(
        $this->idKey,
        $this->revisionKey,
        $this->langcodeKey,
      );
      $revision_data_fields = array_diff($revisionable_fields, $revision_metadata_fields, array(
        $this->langcodeKey,
      ));
      $table_mapping
        ->setFieldNames($this->revisionDataTable, array_merge($revision_data_key_fields, $revision_data_fields));
    }

    // Add dedicated tables.
    $definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
      return $table_mapping
        ->requiresDedicatedTableStorage($definition);
    });
    $extra_columns = array(
      'bundle',
      'deleted',
      'entity_id',
      'revision_id',
      'langcode',
      'delta',
    );
    foreach ($definitions as $field_name => $definition) {
      foreach (array(
        $table_mapping
          ->getDedicatedDataTableName($definition),
        $table_mapping
          ->getDedicatedRevisionTableName($definition),
      ) as $table_name) {
        $table_mapping
          ->setFieldNames($table_name, array(
          $field_name,
        ));
        $table_mapping
          ->setExtraColumns($table_name, $extra_columns);
      }
    }

    // Cache the computed table mapping only if we are using our internal
    // storage definitions.
    if (!$storage_definitions) {
      $this->tableMapping = $table_mapping;
    }
  }
  return $table_mapping;
}