diff --git a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php index f992081..03a2afc 100644 --- a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php +++ b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php @@ -130,18 +130,38 @@ public function getFieldNames($table_name) { */ public function getColumnNames($field_name) { if (!isset($this->columnMapping[$field_name])) { - $column_names = array_keys($this->fieldStorageDefinitions[$field_name]->getColumns()); - if (count($column_names) == 1) { - $this->columnMapping[$field_name] = array(reset($column_names) => $field_name); + $this->columnMapping[$field_name] = array(); + foreach (array_keys($this->fieldStorageDefinitions[$field_name]->getColumns()) as $column_name) { + $this->columnMapping[$field_name][$column_name] = $this->getFieldColumnName($this->fieldStorageDefinitions[$field_name], $column_name); + } + } + return $this->columnMapping[$field_name]; + } + + /** + * {@inheritdoc} + */ + public function getFieldColumnName(FieldStorageDefinitionInterface $storage_definition, $column_name) { + $field_name = $storage_definition->getName(); + + if ($this->allowsSharedTableStorage($storage_definition)) { + if (count($storage_definition->getColumns()) == 1) { + $column_name = $field_name; } else { - $this->columnMapping[$field_name] = array(); - foreach ($column_names as $column_name) { - $this->columnMapping[$field_name][$column_name] = $field_name . '__' . $column_name; - } + $column_name = $field_name . '__' . $column_name; } } - return $this->columnMapping[$field_name]; + elseif ($this->requiresDedicatedTableStorage($storage_definition)) { + if (!in_array($column_name, $this->getReservedColumns())) { + $column_name = $field_name . '_' . $column_name; + } + } + else { + throw new SqlContentEntityStorageException('Column information not available for the specified field.'); + } + + return $column_name; } /** @@ -319,11 +339,4 @@ protected function generateFieldTableName(FieldStorageDefinitionInterface $stora return $table_name; } - /** - * {@inheritdoc} - */ - public function getFieldColumnName(FieldStorageDefinitionInterface $storage_definition, $column) { - return in_array($column, $this->getReservedColumns()) ? $column : $storage_definition->getName() . '_' . $column; - } - } diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageException.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageException.php new file mode 100644 index 0000000..cbda75f --- /dev/null +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageException.php @@ -0,0 +1,16 @@ +setUpDefinition('test', $columns, $base_field); + + $definitions['test_custom'] = $this->setUpDefinition('test_custom', [], $base_field); + $definitions['test_custom']->expects($this->any()) + ->method('hasCustomStorage') + ->willReturn(TRUE); + + $table_mapping = new DefaultTableMapping($definitions); + + try { + $result = $table_mapping->getFieldColumnName($definitions[$field_name], $column); + $this->assertEquals($expected, $result); + } + catch (SqlContentEntityStorageException $e) { + $this->assertTrue($exception); + } + } + + /** + * Provides test data for testGetFieldColumnName(). + * + * @return array[] + * An nested array where each inner array has the following values: test + * field name, base field status, list of field columns, name of the column + * to be retrieved, expected result, whether an exception is expected. + */ + public function providerTestGetFieldColumnName() { + $data = []; + // Base field with single column. + $data[] = ['test', TRUE, ['foo'], 'foo', 'test']; + + // Base field with multiple columns. + $data[] = ['test', TRUE, ['foo', 'bar'], 'foo', 'test__foo']; + $data[] = ['test', TRUE, ['foo', 'bar'], 'bar', 'test__bar']; + // Bundle field with single column. + $data[] = ['test', FALSE, ['foo'], 'foo', 'test_foo']; + // Bundle field with multiple columns. + $data[] = ['test', FALSE, ['foo', 'bar'], 'foo', 'test_foo']; + $data[] = ['test', FALSE, ['foo', 'bar'], 'bar', 'test_bar']; + // Bundle field with reserved column. + $data[] = ['test', FALSE, ['foo', 'bar'], 'deleted', 'deleted']; + // Custom storage fields. + $data[] = ['test_custom', TRUE, [], '', '', TRUE]; + $data[] = ['test_custom', FALSE, [], '', '', TRUE]; + + return $data; + } + + /** * Sets up a field storage definition for the test. * * @param string $name @@ -244,11 +315,11 @@ public function testGetExtraColumns() { * * @return \Drupal\Core\Field\FieldStorageDefinitionInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected function setUpDefinition($name, array $column_names) { + protected function setUpDefinition($name, array $column_names, $base_field = TRUE) { $definition = $this->getMock('Drupal\Tests\Core\Field\TestBaseFieldDefinitionInterface'); $definition->expects($this->any()) ->method('isBaseField') - ->will($this->returnValue(TRUE)); + ->willReturn($base_field); $definition->expects($this->any()) ->method('getName') ->will($this->returnValue($name)); diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php index 3a37f90..cfa5cd9 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php @@ -281,7 +281,7 @@ public function testOnEntityTypeCreate() { ); $this->fieldDefinitions = $this->mockFieldDefinitions(array('id')); - $this->fieldDefinitions['id']->expects($this->once()) + $this->fieldDefinitions['id']->expects($this->any()) ->method('getColumns') ->will($this->returnValue($columns)); $this->fieldDefinitions['id']->expects($this->once())