diff --git a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php index cc03f9e..3d506d0 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php @@ -811,66 +811,33 @@ protected function invokeHook($hook, EntityInterface $entity) { * * @param \Drupal\Core\Entity\ContentEntityInterface $entity * The entity object. - * @param string $table_key - * (optional) The entity key identifying the target table. Defaults to - * 'base_table'. + * @param string $table_name + * (optional) The table name to map records to. Defaults to the base table. * * @return \stdClass * The record to store. */ - protected function mapToStorageRecord(ContentEntityInterface $entity, $table_key = 'base_table') { - $record = new \stdClass(); - $values = array(); - $schema = drupal_get_schema($this->entityType->get($table_key)); - $is_new = $entity->isNew(); - - $multi_column_fields = array(); - foreach (drupal_schema_fields_sql($this->entityType->get($table_key)) as $name) { - // Check for fields which store data in multiple columns and process them - // separately. - if ($field = strstr($name, '__', TRUE)) { - $multi_column_fields[$field] = TRUE; - continue; - } - $values[$name] = NULL; - if ($entity->hasField($name)) { - // Only the first field item is stored. - $field_item = $entity->get($name)->first(); - $main_property = $entity->getFieldDefinition($name)->getMainPropertyName(); - if ($main_property && isset($field_item->$main_property)) { - // If the field has a main property, store the value of that. - $values[$name] = $field_item->$main_property; - } - elseif (!$main_property) { - // If there is no main property, get all properties from the first - // field item and assume that they will be stored serialized. - // @todo Give field types more control over this behavior in - // https://drupal.org/node/2232427. - $values[$name] = $field_item->getValue(); - } - } + protected function mapToStorageRecord(ContentEntityInterface $entity, $table_name = NULL) { + if (!isset($table_name)) { + $table_name = $this->baseTable; } - // 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(); - foreach (array_keys($field_items->getFieldDefinition()->getColumns()) as $field_schema_column) { - if (isset($schema['fields'][$field_name . '__' . $field_schema_column])) { - $values[$field_name . '__' . $field_schema_column] = isset($field_value[0][$field_schema_column]) ? $field_value[0][$field_schema_column] : NULL; + $record = new \stdClass(); + $table_mapping = $this->getTableMapping(); + foreach ($table_mapping->getFieldNames($table_name) as $field_name) { + $columns = $table_mapping->getColumnNames($field_name); + if (!empty($this->storageDefinitions[$field_name])) { + $definition = $this->storageDefinitions[$field_name]; + foreach ($columns as $column_name => $schema_name) { + $value = isset($entity->$field_name->$column_name) ? $entity->$field_name->$column_name : NULL; + if (!empty($definition->getSchema()['columns'][$column_name]['serialize'])) { + $value = serialize($value); + } + $record->$schema_name = drupal_schema_get_field_value($definition->getSchema()['columns'][$column_name], $value); } } } - foreach ($values as $field_name => $value) { - // If we are creating a new entity, we must not populate the record with - // NULL values otherwise defaults would not be applied. - if (isset($value) || !$is_new) { - $record->$field_name = drupal_schema_get_field_value($schema['fields'][$field_name], $value); - } - } - return $record; } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/KernelTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/KernelTestBase.php index 1188822..f1f4efb 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/KernelTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/KernelTestBase.php @@ -7,11 +7,13 @@ namespace Drupal\simpletest; +use Drupal\Component\Utility\String; use Drupal\Core\Database\Database; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DrupalKernel; use Drupal\Core\KeyValueStore\KeyValueMemoryFactory; use Drupal\Core\Language\Language; +use Drupal\Core\Entity\Schema\ContentEntitySchemaHandlerInterface; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Request; @@ -338,6 +340,39 @@ protected function installSchema($module, $tables) { ))); } + + + /** + * Installs the tables for a specific entity type. + * + * @param string $entity_type_id + * The ID of the entity type. + */ + protected function installEntitySchema($entity_type_id) { + /** @var \Drupal\Core\Entity\EntityManagerInterface $entity_manager */ + $entity_manager = $this->container->get('entity.manager'); + /** @var \Drupal\Core\Database\Schema $schema_handler */ + $schema_handler = $this->container->get('database')->schema(); + + $storage = $entity_manager->getStorage($entity_type_id); + if ($storage instanceof ContentEntitySchemaHandlerInterface) { + $schema = $storage->getSchema(); + foreach ($schema as $table_name => $table_schema) { + $schema_handler->createTable($table_name, $table_schema); + } + + $this->pass(String::format('Installed entity type tables for the %entity_type entity type: %tables', array( + '%entity_type' => $entity_type_id, + '%tables' => '{' . implode('}, {', array_keys($schema)) . '}', + ))); + } + else { + throw new \RuntimeException(String::format('Entity type %entity_type does not support automatic schema installation.', array( + '%entity-type' => $entity_type_id, + ))); + } + } + /** * Enables modules for this test. *