diff --git a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php index dbf1b71..d27a217 100644 --- a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php +++ b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php @@ -116,38 +116,48 @@ class DefaultTableMapping implements TableMappingInterface { public function __construct(ContentEntityTypeInterface $entity_type, array $storage_definitions) { $this->entityType = $entity_type; $this->fieldStorageDefinitions = $storage_definitions; - - $this->initializeMapping(); } /** * Initializes the table mapping. + * + * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type + * The entity type definition. + * @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions + * A list of field storage definitions that should be available for the + * field columns of this table mapping. + * + * @return static + * + * @internal */ - protected function initializeMapping() { - $revisionable = $this->entityType->isRevisionable(); - $translatable = $this->entityType->isTranslatable(); + public static function create(ContentEntityTypeInterface $entity_type, array $storage_definitions) { + $table_mapping = new static($entity_type, $storage_definitions); + + $revisionable = $entity_type->isRevisionable(); + $translatable = $entity_type->isTranslatable(); // @todo Remove table names from the entity type definition in // https://www.drupal.org/node/2232465. - $this->baseTable = $this->entityType->getBaseTable() ?: $this->entityType->id(); + $table_mapping->baseTable = $entity_type->getBaseTable() ?: $entity_type->id(); if ($revisionable) { - $this->revisionTable = $this->entityType->getRevisionTable() ?: $this->entityType->id() . '_revision'; + $table_mapping->revisionTable = $entity_type->getRevisionTable() ?: $entity_type->id() . '_revision'; } if ($translatable) { - $this->dataTable = $this->entityType->getDataTable() ?: $this->entityType->id() . '_field_data'; + $table_mapping->dataTable = $entity_type->getDataTable() ?: $entity_type->id() . '_field_data'; } if ($revisionable && $translatable) { - $this->revisionDataTable = $this->entityType->getRevisionDataTable() ?: $this->entityType->id() . '_field_revision'; + $table_mapping->revisionDataTable = $entity_type->getRevisionDataTable() ?: $entity_type->id() . '_field_revision'; } - $id_key = $this->entityType->getKey('id'); - $revision_key = $this->entityType->getKey('revision'); - $bundle_key = $this->entityType->getKey('bundle'); - $uuid_key = $this->entityType->getKey('uuid'); - $langcode_key = $this->entityType->getKey('langcode'); + $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($this->fieldStorageDefinitions, function (FieldStorageDefinitionInterface $definition) { - return $this->allowsSharedTableStorage($definition); + $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])); @@ -158,20 +168,20 @@ protected function initializeMapping() { // 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($this->entityType->getRevisionMetadataKeys()) : []; + $revision_metadata_fields = $revisionable ? array_values($entity_type->getRevisionMetadataKeys()) : []; if (!$revisionable && !$translatable) { // The base layout stores all the base field values in the base table. - $this->setFieldNames($this->baseTable, $all_fields); + $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. - $this->setFieldNames($this->baseTable, array_diff($all_fields, $revision_metadata_fields)); + $table_mapping->setFieldNames($table_mapping->baseTable, array_diff($all_fields, $revision_metadata_fields)); $revision_key_fields = [$id_key, $revision_key]; - $this->setFieldNames($this->revisionTable, array_merge($revision_key_fields, $revisionable_fields)); + $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 @@ -180,9 +190,9 @@ protected function initializeMapping() { // 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. - $this - ->setFieldNames($this->baseTable, $key_fields) - ->setFieldNames($this->dataTable, array_values(array_diff($all_fields, [$uuid_key]))); + $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 @@ -192,25 +202,25 @@ protected function initializeMapping() { // 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. - $this->setFieldNames($this->baseTable, $key_fields); + $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)); - $this->setFieldNames($this->dataTable, $data_fields); + $table_mapping->setFieldNames($table_mapping->dataTable, $data_fields); $revision_base_fields = array_merge([$id_key, $revision_key, $langcode_key], $revision_metadata_fields); - $this->setFieldNames($this->revisionTable, $revision_base_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]); - $this->setFieldNames($this->revisionDataTable, array_merge($revision_data_key_fields, $revision_data_fields)); + $table_mapping->setFieldNames($table_mapping->revisionDataTable, array_merge($revision_data_key_fields, $revision_data_fields)); } // Add dedicated tables. - $dedicated_table_definitions = array_filter($this->fieldStorageDefinitions, function (FieldStorageDefinitionInterface $definition) { - return $this->requiresDedicatedTableStorage($definition); + $dedicated_table_definitions = array_filter($table_mapping->fieldStorageDefinitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) { + return $table_mapping->requiresDedicatedTableStorage($definition); }); $extra_columns = [ 'bundle', @@ -221,15 +231,17 @@ protected function initializeMapping() { 'delta', ]; foreach ($dedicated_table_definitions as $field_name => $definition) { - $tables = [$this->getDedicatedDataTableName($definition)]; + $tables = [$table_mapping->getDedicatedDataTableName($definition)]; if ($revisionable && $definition->isRevisionable()) { - $tables[] = $this->getDedicatedRevisionTableName($definition); + $tables[] = $table_mapping->getDedicatedRevisionTableName($definition); } foreach ($tables as $table_name) { - $this->setFieldNames($table_name, [$field_name]); - $this->setExtraColumns($table_name, $extra_columns); + $table_mapping->setFieldNames($table_name, [$field_name]); + $table_mapping->setExtraColumns($table_name, $extra_columns); } } + + return $table_mapping; } /** @@ -370,8 +382,6 @@ public function getFieldColumnName(FieldStorageDefinitionInterface $storage_defi * @deprecated in Drupal 8.6.0 and will be changed to a protected method * before Drupal 9.0.0. There will be no replacement for it because the * default table mapping is now able to be initialized on its own. - * - * @internal */ public function setFieldNames($table_name, array $field_names) { $this->fieldNames[$table_name] = $field_names; @@ -403,8 +413,6 @@ public function getExtraColumns($table_name) { * @deprecated in Drupal 8.6.0 and will be changed to a protected method * before Drupal 9.0.0. There will be no replacement for it because the * default table mapping is now able to be initialized on its own. - * - * @internal */ public function setExtraColumns($table_name, array $column_names) { $this->extraColumns[$table_name] = $column_names; diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php index 9a5ccba..932d6f3 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php @@ -312,7 +312,7 @@ public function getTableMapping(array $storage_definitions = NULL) { $definitions = $storage_definitions ?: $this->entityManager->getFieldStorageDefinitions($this->entityTypeId); /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping|\Drupal\Core\Entity\Sql\TemporaryTableMapping $table_mapping */ - $table_mapping = new $table_mapping_class($this->entityType, $definitions); + $table_mapping = $table_mapping_class::create($this->entityType, $definitions); // Cache the computed table mapping only if we are using our internal // storage definitions.