diff --git a/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php b/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php index 9af998b..370dea6 100644 --- a/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php +++ b/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php @@ -281,15 +281,19 @@ protected function mapFromStorageRecords(array $records, $load_revision = FALSE) $entities = array(); foreach ($records as $id => $record) { $entities[$id] = array(); + // Skip the item delta and item value levels but let the field assign + // the value as suiting. This avoids unnecessary array hierarchies and + // saves memory here. foreach ($record as $name => $value) { - // Skip the item delta and item value levels but let the field assign - // the value as suiting. This avoids unnecessary array hierarchies and - // saves memory here. + // Handle columns named [field_name]__[column_name] (e.g for field types + // that store several properties). if ($field = strstr($name, '__', TRUE)) { $property_name = substr($name, strpos($name, '__') + 2); $entities[$id][$field][Language::LANGCODE_DEFAULT][$property_name] = $value; } else { + // Handle columns named directly after the field (e.g if the field + // type only stores one property). $entities[$id][$name][Language::LANGCODE_DEFAULT] = $value; } } @@ -338,13 +342,13 @@ protected function attachPropertyData(array &$entities, $revision_id = FALSE) { } $data = $query->execute(); - $field_definition = \Drupal::entityManager()->getFieldDefinitions($this->entityType); + $field_definitions = \Drupal::entityManager()->getFieldDefinitions($this->entityType); $translations = array(); if ($this->revisionDataTable) { - $data_fields = array_flip(array_diff(drupal_schema_fields_sql($this->entityInfo['revision_data_table']), drupal_schema_fields_sql($this->entityInfo['base_table']))); + $data_column_names = array_flip(array_diff(drupal_schema_fields_sql($this->entityInfo['revision_data_table']), drupal_schema_fields_sql($this->entityInfo['base_table']))); } else { - $data_fields = array_flip(drupal_schema_fields_sql($this->entityInfo['data_table'])); + $data_column_names = array_flip(drupal_schema_fields_sql($this->entityInfo['data_table'])); } foreach ($data as $values) { @@ -355,15 +359,19 @@ protected function attachPropertyData(array &$entities, $revision_id = FALSE) { $langcode = empty($values['default_langcode']) ? $values['langcode'] : Language::LANGCODE_DEFAULT; $translations[$id][$langcode] = TRUE; - foreach ($field_definition as $name => $definition) { - if (isset($data_fields[$name])) { - $entities[$id][$name][$langcode] = $values[$name]; + foreach (array_keys($field_definitions) as $field_name) { + // Handle columns named directly after the field. + if (isset($data_column_names[$field_name])) { + $entities[$id][$field_name][$langcode] = $values[$field_name]; } else { - foreach ($data_fields as $data_field) { - if (($field = strstr($data_field, '__', TRUE)) && $field === $name) { - $property_name = substr($data_field, strpos($data_field, '__') + 2); - $entities[$id][$name][$langcode][$property_name] = $values[$data_field]; + foreach ($data_column_names as $data_column_name) { + // Handle columns named [field_name]__[column_name], for which we + // need to look through all column names from the table that start + // with the name of the field. + if (($field = strstr($data_column_name, '__', TRUE)) && $field === $field_name) { + $property_name = substr($data_column_name, strpos($data_column_name, '__') + 2); + $entities[$id][$field_name][$langcode][$property_name] = $values[$data_column_name]; } } } @@ -774,9 +782,13 @@ protected function mapToStorageRecord(EntityInterface $entity, $table_key = 'bas $values[$name] = isset($definitions[$name]) && isset($entity->$name->value) ? $entity->$name->value : NULL; } + // Handle fields that store multiple properties and match each property name + // to its schema column name. foreach (array_keys($multi_column_fields) as $field_name) { $field_items = $entity->get($field_name); $field_value = $field_items->getValue(); + // @todo Reconsider the usage of getFieldPropertyNames() after + // https://drupal.org/node/2144327. foreach ($field_items->getFieldDefinition()->getFieldPropertyNames() as $property_name) { if (isset($schema['fields'][$field_name . '__' . $property_name])) { $values[$field_name . '__' . $property_name] = isset($field_value[0][$property_name]) ? $field_value[0][$property_name] : NULL;