diff --git a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php index 4fd6a32..dafc5d0 100644 --- a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php +++ b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php @@ -3,6 +3,7 @@ namespace Drupal\Core\Entity\Sql; use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; /** @@ -18,6 +19,34 @@ class DefaultTableMapping implements TableMappingInterface { protected $entityType; /** + * The base table of the entity. + * + * @var string + */ + protected $baseTable; + + /** + * The table that stores revisions, if the entity supports revisions. + * + * @var string + */ + protected $revisionTable; + + /** + * The table that stores properties, if the entity has multilingual support. + * + * @var string + */ + protected $dataTable; + + /** + * The table that stores revision field data if the entity supports revisions. + * + * @var string + */ + protected $revisionDataTable; + + /** * The field storage definitions of this mapping. * * @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] @@ -87,6 +116,162 @@ class DefaultTableMapping implements TableMappingInterface { public function __construct(ContentEntityTypeInterface $entity_type, array $storage_definitions) { $this->entityType = $entity_type; $this->fieldStorageDefinitions = $storage_definitions; + + $this->initializeMapping(); + } + + /** + * Initialize the table mapping. + */ + public function initializeMapping() { + $revisionable = $this->entityType->isRevisionable(); + $translatable = $this->entityType->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(); + if ($revisionable) { + $this->revisionTable = $this->entityType->getRevisionTable() ?: $this->entityType->id() . '_revision'; + } + if ($translatable) { + $this->dataTable = $this->entityType->getDataTable() ?: $this->entityType->id() . '_field_data'; + } + if ($revisionable && $translatable) { + $this->revisionDataTable = $this->entityType->getRevisionDataTable() ?: $this->entityType->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'); + + $shared_table_definitions = array_filter($this->fieldStorageDefinitions, function (FieldStorageDefinitionInterface $definition) { + return $this->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)); + + $revisionable = $this->entityType->isRevisionable(); + $revision_metadata_fields = $revisionable ? array_values($this->entityType->getRevisionMetadataKeys()) : []; + + $translatable = $this->entityType->isTranslatable(); + if (!$revisionable && !$translatable) { + // The base layout stores all the base field values in the base table. + $this->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. + $this->setFieldNames($this->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)); + } + 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. + $this + ->setFieldNames($this->baseTable, $key_fields) + ->setFieldNames($this->dataTable, array_values(array_diff($all_fields, [$uuid_key]))); + } + 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. + $this->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, [$uuid_key], $revision_metadata_fields)); + $this->setFieldNames($this->dataTable, $data_fields); + + $revision_base_fields = array_merge([$id_key, $revision_key, $langcode_key], $revision_metadata_fields); + $this->setFieldNames($this->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)); + } + + // Add dedicated tables. + $dedicated_table_definitions = array_filter($this->fieldStorageDefinitions, function (FieldStorageDefinitionInterface $definition) { + return $this->requiresDedicatedTableStorage($definition); + }); + $extra_columns = [ + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'langcode', + 'delta', + ]; + foreach ($dedicated_table_definitions as $field_name => $definition) { + $tables = [$this->getDedicatedDataTableName($definition)]; + if ($revisionable && $definition->isRevisionable()) { + $tables[] = $this->getDedicatedRevisionTableName($definition); + } + foreach ($tables as $table_name) { + $this->setFieldNames($table_name, [$field_name]); + $this->setExtraColumns($table_name, $extra_columns); + } + } + } + + /** + * Gets the base table name. + * + * @return string + * The table name. + */ + public function getBaseTable() { + return $this->baseTable; + } + + /** + * Gets the revision table name. + * + * @return string|false + * The table name or FALSE if it is not available. + */ + public function getRevisionTable() { + return $this->revisionTable; + } + + /** + * Gets the data table name. + * + * @return string|false + * The table name or FALSE if it is not available. + */ + public function getDataTable() { + return $this->dataTable; + } + + /** + * Gets the revision data table name. + * + * @return string|false + * The table name or FALSE if it is not available. + */ + public function getRevisionDataTable() { + return $this->revisionDataTable; } /** @@ -143,17 +328,13 @@ public function getFieldTableName($field_name) { // where field data is stored, otherwise the base table is responsible for // storing field data. Revision metadata is an exception as it's stored // only in the revision table. - // @todo The table mapping itself should know about entity tables. See - // https://www.drupal.org/node/2274017. - /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */ - $storage = \Drupal::entityManager()->getStorage($this->entityType->id()); $storage_definition = $this->fieldStorageDefinitions[$field_name]; - $table_names = [ - $storage->getDataTable(), - $storage->getBaseTable(), - $storage->getRevisionTable(), + $table_names = array_filter([ + $this->dataTable, + $this->baseTable, + $this->revisionTable, $this->getDedicatedDataTableName($storage_definition), - ]; + ]); // Collect field columns. $field_columns = []; @@ -161,7 +342,7 @@ public function getFieldTableName($field_name) { $field_columns[] = $this->getFieldColumnName($storage_definition, $property_name); } - foreach (array_filter($table_names) as $table_name) { + foreach ($table_names as $table_name) { $columns = $this->getAllColumns($table_name); // We assume finding one field column belonging to the mapping is enough // to identify the field table. diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php index d696a94..3361010 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php @@ -170,27 +170,19 @@ protected function initTableLayout() { // are correctly reflected in the table layout. $this->tableMapping = NULL; $this->revisionKey = NULL; - $this->revisionTable = NULL; - $this->dataTable = NULL; - $this->revisionDataTable = NULL; - - // @todo Remove table names from the entity type definition in - // https://www.drupal.org/node/2232465. - $this->baseTable = $this->entityType->getBaseTable() ?: $this->entityTypeId; - $revisionable = $this->entityType->isRevisionable(); - if ($revisionable) { + + $this->baseTable = $this->getTableMapping()->getBaseTable(); + $this->revisionTable = $this->getTableMapping()->getRevisionTable(); + $this->dataTable = $this->getTableMapping()->getDataTable(); + $this->revisionDataTable = $this->getTableMapping()->getRevisionDataTable(); + + if ($this->entityType->isRevisionable()) { $this->revisionKey = $this->entityType->getKey('revision') ?: 'revision_id'; - $this->revisionTable = $this->entityType->getRevisionTable() ?: $this->entityTypeId . '_revision'; } - $translatable = $this->entityType->isTranslatable(); - if ($translatable) { - $this->dataTable = $this->entityType->getDataTable() ?: $this->entityTypeId . '_field_data'; + if ($translatable = $this->entityType->isTranslatable()) { $this->langcodeKey = $this->entityType->getKey('langcode'); $this->defaultLangcodeKey = $this->entityType->getKey('default_langcode'); } - if ($revisionable && $translatable) { - $this->revisionDataTable = $this->entityType->getRevisionDataTable() ?: $this->entityTypeId . '_field_revision'; - } } /** @@ -248,25 +240,6 @@ protected function getStorageSchema() { } /** - * Updates the wrapped entity type definition. - * - * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type - * The update entity type. - * - * @internal Only to be used internally by Entity API. Expected to be - * removed by https://www.drupal.org/node/2274017. - */ - public function setEntityType(EntityTypeInterface $entity_type) { - if ($this->entityType->id() == $entity_type->id()) { - $this->entityType = $entity_type; - $this->initTableLayout(); - } - else { - throw new EntityStorageException("Unsupported entity type {$entity_type->id()}"); - } - } - - /** * {@inheritdoc} */ public function getTableMapping(array $storage_definitions = NULL) { @@ -276,101 +249,10 @@ public function getTableMapping(array $storage_definitions = NULL) { // 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); - $shared_table_definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) { - return $table_mapping->allowsSharedTableStorage($definition); - }); - - $key_fields = array_values(array_filter([$this->idKey, $this->revisionKey, $this->bundleKey, $this->uuidKey, $this->langcodeKey])); - $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)); - - // If the entity is revisionable, gather the fields that need to be put - // in the revision table. - $revisionable = $this->entityType->isRevisionable(); - $revision_metadata_fields = $revisionable ? array_values($this->entityType->getRevisionMetadataKeys()) : []; - - $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 = [$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, [$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, [$this->uuidKey], $revision_metadata_fields)); - $table_mapping->setFieldNames($this->dataTable, $data_fields); - - $revision_base_fields = array_merge([$this->idKey, $this->revisionKey, $this->langcodeKey], $revision_metadata_fields); - $table_mapping->setFieldNames($this->revisionTable, $revision_base_fields); - - $revision_data_key_fields = [$this->idKey, $this->revisionKey, $this->langcodeKey]; - $revision_data_fields = array_diff($revisionable_fields, $revision_metadata_fields, [$this->langcodeKey]); - $table_mapping->setFieldNames($this->revisionDataTable, array_merge($revision_data_key_fields, $revision_data_fields)); - } - - // Add dedicated tables. - $dedicated_table_definitions = array_filter($definitions, 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); - } - } - // Cache the computed table mapping only if we are using our internal // storage definitions. if (!$storage_definitions) { @@ -644,7 +526,7 @@ protected function buildPropertyQuery(QueryInterface $entity_query, array $value * A SelectQuery object for loading the entity. */ protected function buildQuery($ids, $revision_id = FALSE) { - $query = $this->database->select($this->entityType->getBaseTable(), 'base'); + $query = $this->database->select($this->baseTable, 'base'); $query->addTag($this->entityTypeId . '_load_multiple'); @@ -719,7 +601,7 @@ public function delete(array $entities) { protected function doDeleteFieldItems($entities) { $ids = array_keys($entities); - $this->database->delete($this->entityType->getBaseTable()) + $this->database->delete($this->baseTable) ->condition($this->idKey, $ids, 'IN') ->execute(); @@ -1040,7 +922,7 @@ protected function saveRevision(ContentEntityInterface $entity) { $record->{$this->revisionKey} = $insert_id; } if ($entity->isDefaultRevision()) { - $this->database->update($this->entityType->getBaseTable()) + $this->database->update($this->baseTable) ->fields([$this->revisionKey => $record->{$this->revisionKey}]) ->condition($this->idKey, $record->{$this->idKey}) ->execute(); @@ -1399,12 +1281,6 @@ public function onEntityTypeDelete(EntityTypeInterface $entity_type) { public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition) { // If we are adding a field stored in a shared table we need to recompute // the table mapping. - // @todo This does not belong here. Remove it once we are able to generate a - // fresh table mapping in the schema handler. See - // https://www.drupal.org/node/2274017. - if ($this->getTableMapping()->allowsSharedTableStorage($storage_definition)) { - $this->tableMapping = NULL; - } $this->wrapSchemaException(function () use ($storage_definition) { $this->getStorageSchema()->onFieldStorageDefinitionCreate($storage_definition); }); @@ -1632,16 +1508,7 @@ public function countFieldData($storage_definition, $as_bool = FALSE) { elseif ($table_mapping->allowsSharedTableStorage($storage_definition)) { // Ascertain the table this field is mapped too. $field_name = $storage_definition->getName(); - try { - $table_name = $table_mapping->getFieldTableName($field_name); - } - catch (SqlContentEntityStorageException $e) { - // This may happen when changing field storage schema, since we are not - // able to use a table mapping matching the passed storage definition. - // @todo Revisit this once we are able to instantiate the table mapping - // properly. See https://www.drupal.org/node/2274017. - $table_name = $this->dataTable ?: $this->baseTable; - } + $table_name = $table_mapping->getFieldTableName($field_name); $query = $this->database->select($table_name, 't'); $or = $query->orConditionGroup(); foreach (array_keys($storage_definition->getColumns()) as $property_name) { diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php index f9dd0c0..ed87047 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php @@ -353,23 +353,19 @@ public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeI public function onEntityTypeDelete(EntityTypeInterface $entity_type) { $this->checkEntityType($entity_type); $schema_handler = $this->database->schema(); - $actual_definition = $this->entityManager->getDefinition($entity_type->id()); - // @todo Instead of switching the wrapped entity type, we should be able to - // instantiate a new table mapping for each entity type definition. See - // https://www.drupal.org/node/2274017. - $this->storage->setEntityType($entity_type); + + $field_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type->id()); + $this->originalDefinitions = $field_storage_definitions; + $table_mapping = new DefaultTableMapping($entity_type, $field_storage_definitions); // Delete entity tables. - foreach ($this->getEntitySchemaTables() as $table_name) { + foreach ($this->getEntitySchemaTables($table_mapping) as $table_name) { if ($schema_handler->tableExists($table_name)) { $schema_handler->dropTable($table_name); } } // Delete dedicated field tables. - $field_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type->id()); - $this->originalDefinitions = $field_storage_definitions; - $table_mapping = $this->storage->getTableMapping($field_storage_definitions); foreach ($field_storage_definitions as $field_storage_definition) { // If we have a field having dedicated storage we need to drop it, // otherwise we just remove the related schema data. @@ -382,8 +378,6 @@ public function onEntityTypeDelete(EntityTypeInterface $entity_type) { } $this->originalDefinitions = NULL; - $this->storage->setEntityType($actual_definition); - // Delete the entity schema. $this->deleteEntitySchemaData($entity_type); } @@ -414,17 +408,8 @@ public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $ // Only configurable fields currently support purging, so prevent deletion // of ones we can't purge if they have existing data. // @todo Add purging to all fields: https://www.drupal.org/node/2282119. - try { - if (!($storage_definition instanceof FieldStorageConfigInterface) && $this->storage->countFieldData($storage_definition, TRUE)) { - throw new FieldStorageDefinitionUpdateForbiddenException('Unable to delete a field (' . $storage_definition->getName() . ' in ' . $storage_definition->getTargetEntityTypeId() . ' entity) with data that cannot be purged.'); - } - } - catch (DatabaseException $e) { - // This may happen when changing field storage schema, since we are not - // able to use a table mapping matching the passed storage definition. - // @todo Revisit this once we are able to instantiate the table mapping - // properly. See https://www.drupal.org/node/2274017. - return; + if (!($storage_definition instanceof FieldStorageConfigInterface) && $this->storage->countFieldData($storage_definition, TRUE)) { + throw new FieldStorageDefinitionUpdateForbiddenException('Unable to delete a field (' . $storage_definition->getName() . ' in ' . $storage_definition->getTargetEntityTypeId() . ' entity) with data that cannot be purged.'); } // Retrieve a table mapping which contains the deleted field still. @@ -502,15 +487,11 @@ protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $res $entity_type_id = $entity_type->id(); if (!isset($this->schema[$entity_type_id]) || $reset) { - // Back up the storage definition and replace it with the passed one. - // @todo Instead of switching the wrapped entity type, we should be able - // to instantiate a new table mapping for each entity type definition. - // See https://www.drupal.org/node/2274017. - $actual_definition = $this->entityManager->getDefinition($entity_type_id); - $this->storage->setEntityType($entity_type); + $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); + $table_mapping = new DefaultTableMapping($entity_type, $storage_definitions); // Prepare basic information about the entity type. - $tables = $this->getEntitySchemaTables(); + $tables = $this->getEntitySchemaTables($table_mapping); // Initialize the table schema. $schema[$tables['base_table']] = $this->initializeBaseTable($entity_type); @@ -525,9 +506,7 @@ protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $res } // We need to act only on shared entity schema tables. - $table_mapping = $this->storage->getTableMapping(); $table_names = array_diff($table_mapping->getTableNames(), $table_mapping->getDedicatedTableNames()); - $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); foreach ($table_names as $table_name) { if (!isset($schema[$table_name])) { $schema[$table_name] = []; @@ -576,9 +555,6 @@ protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $res } $this->schema[$entity_type_id] = $schema; - - // Restore the actual definition. - $this->storage->setEntityType($actual_definition); } return $this->schema[$entity_type_id]; @@ -587,15 +563,18 @@ protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $res /** * Gets a list of entity type tables. * + * @param \Drupal\Core\Entity\Sql\TableMappingInterface $table_mapping + * The SQL table mapping. + * * @return array * A list of entity type tables, keyed by table key. */ - protected function getEntitySchemaTables() { + protected function getEntitySchemaTables(TableMappingInterface $table_mapping) { return array_filter([ - 'base_table' => $this->storage->getBaseTable(), - 'revision_table' => $this->storage->getRevisionTable(), - 'data_table' => $this->storage->getDataTable(), - 'revision_data_table' => $this->storage->getRevisionDataTable(), + 'base_table' => $table_mapping->getBaseTable(), + 'revision_table' => $table_mapping->getRevisionTable(), + 'data_table' => $table_mapping->getDataTable(), + 'revision_data_table' => $table_mapping->getRevisionDataTable(), ]); } diff --git a/core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php b/core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php index 6060ae4..993ee82 100644 --- a/core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php +++ b/core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php @@ -6,6 +6,7 @@ use Drupal\Core\Entity\EntityTypeEventSubscriberTrait; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityTypeListenerInterface; +use Drupal\Core\Entity\Sql\DefaultTableMapping; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\views\Views; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -312,11 +313,8 @@ protected function dataTableRename($all_views, $entity_type_id, $old_data_table, * The base table. */ protected function dataTableAddition($all_views, EntityTypeInterface $entity_type, $new_data_table, $base_table) { - /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */ $entity_type_id = $entity_type->id(); - $storage = $this->entityManager->getStorage($entity_type_id); - $storage->setEntityType($entity_type); - $table_mapping = $storage->getTableMapping(); + $table_mapping = new DefaultTableMapping($entity_type, $this->entityManager->getFieldStorageDefinitions($entity_type_id)); $data_table_fields = $table_mapping->getFieldNames($new_data_table); $base_table_fields = $table_mapping->getFieldNames($base_table);