diff --git a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php index 02c79bc..8767593 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php @@ -35,9 +35,9 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase implements C /** * The base field definitions for this entity type. * - * @var \Drupal\Core\Field\FieldDefinitionInterface[] + * @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] */ - protected $fieldDefinitions; + protected $storageDefinitions; /** * The table layout associated to the entity type. @@ -63,15 +63,6 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase implements C protected $revisionKey = FALSE; /** - * Name of entity's default_langcode database table field. - * - * Has the value FALSE if this entity does not support multilingual storage. - * - * @var string|bool - */ - protected $defaultLangcodeKey = FALSE; - - /** * The base table of the entity, if the entity has storage. * * @var string @@ -165,7 +156,11 @@ public function __construct(EntityTypeInterface $entity_type, Connection $databa $this->database = $database; $this->fieldInfo = $field_info; $this->entityManager = $entity_manager; - $this->fieldDefinitions = $entity_manager->getBaseFieldDefinitions($entity_type->id()); + $this->storageDefinitions = $entity_manager->getFieldStorageDefinitions($entity_type->id(), FALSE); + // @todo Remove this when multiple-value base fields are supported. + $this->storageDefinitions = array_filter($this->storageDefinitions, function (FieldStorageDefinitionInterface $definition) { + return !$definition->isMultiple(); + }); $this->initTableLayout(); } @@ -180,8 +175,8 @@ protected function initTableLayout() { // The bundle key is optional. $this->bundleKey = $this->entityType->getKey('bundle'); - // @todo Table names do not belong to the entity type definition, they are - // storage implementation details. Rip them out. + // @todo Remove table names from the entity type definition in + // https://drupal.org/node/2232465 $this->baseTable = $this->entityType->getBaseTable() ?: $this->entityTypeId; // Retrieve the current table layout type based on the entity type @@ -346,6 +341,30 @@ public function getTableMapping() { // data field values for all the available revisions without // denormalizations. case static::LAYOUT_MULTILINGUAL_REVISION: + $table_mappings[$this->baseTable] = new TableMapping(); + $table_mappings[$this->dataTable] = new TableMapping(); + $table_mappings[$this->revisionTable] = new TableMapping(); + $table_mappings[$this->revisionDataTable] = new TableMapping(); + + foreach($this->storageDefinitions as $field_name => $definition) { + $column_names = $this->getColumnNames($definition); + if (in_array($field_name, $key_fields)) { + $table_mappings[$this->baseTable]->addFieldColumns($field_name, $column_names); + } + if ($field_name != $this->uuidKey) { + $table_mappings[$this->dataTable]->addFieldColumns($field_name, $column_names); + } + } + + $table_mappings[$this->dataTable]->addDenormalizationColumn('default_langcode'); + break; + + // 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 available revisions without + // denormalizations. + case static::LAYOUT_MULTILINGUAL_REVISION: $table_mapping[$this->baseTable] = $this->getColumnMapping(array_diff($key_fields, array($this->langcodeKey))); $data_key_fields = array_diff($key_fields, array($this->uuidKey)); $data_fields = array_diff($storable_fields, $key_fields, $revision_metadata_fields); @@ -382,9 +401,9 @@ public function getTableMapping() { protected function getColumnMapping($field_names) { $mapping = array(); foreach ($field_names as $field_name) { - $columns = isset($this->fieldDefinitions[$field_name]) ? array_keys($this->fieldDefinitions[$field_name]->getColumns()) : array(); - foreach ($columns as $index => $column) { - $mapping[$field_name][] = $this->schemaHandler()->getFieldColumnName($this->fieldDefinitions[$field_name], $column); + $columns = isset($this->storageDefinitions[$field_name]) ? array_keys($this->storageDefinitions[$field_name]->getColumns()) : array(); + foreach ($columns as $column) { + $mapping[$field_name][] = $this->schemaHandler()->getFieldColumnName($this->storageDefinitions[$field_name], $column); } } return $mapping; diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 679f849..ca56163 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -489,12 +489,12 @@ protected function buildBundleFieldDefinitions($entity_type_id, $bundle, array $ /** * {@inheritdoc} */ - public function getFieldStorageDefinitions($entity_type_id) { + public function getFieldStorageDefinitions($entity_type_id, $include_custom_storage = TRUE) { if (!isset($this->fieldStorageDefinitions[$entity_type_id])) { $this->fieldStorageDefinitions[$entity_type_id] = array(); // Add all non-computed base fields. foreach ($this->getBaseFieldDefinitions($entity_type_id) as $field_name => $definition) { - if (!$definition->isComputed()) { + if (!$definition->isComputed() && ($include_custom_storage || !$definition->hasCustomStorage())) { $this->fieldStorageDefinitions[$entity_type_id][$field_name] = $definition; } } diff --git a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php index da36a36..66c55c9 100644 --- a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php @@ -67,6 +67,8 @@ public function getFieldDefinitions($entity_type_id, $bundle); * * @param string $entity_type_id * The entity type ID. Only content entities are supported. + * @param bool $include_custom_storage + * Whether or not to include storage definitions that have a custom storage. * * @return \Drupal\Core\Field\FieldStorageDefinitionInterface[] * The array of field storage definitions for the entity type, keyed by @@ -74,7 +76,7 @@ public function getFieldDefinitions($entity_type_id, $bundle); * * @see \Drupal\Core\Field\FieldStorageDefinitionInterface */ - public function getFieldStorageDefinitions($entity_type_id); + public function getFieldStorageDefinitions($entity_type_id, $include_custom_storage = TRUE); /** * Creates a new access controller instance.