Commit 28356f4e authored by alexpott's avatar alexpott

Issue #2506805 by jibran, tstoeckler, chx: Non-revisionable base fields with...

Issue #2506805 by jibran, tstoeckler, chx: Non-revisionable base fields with multiple columns break revisionable entity types
parent db9e7191
......@@ -515,15 +515,29 @@ protected function loadFromSharedTables(array &$values, array &$translations) {
// Find revisioned fields that are not entity keys. Exclude the langcode
// key as the base table holds only the default language.
$base_fields = array_diff($table_mapping->getFieldNames($this->baseTable), array($this->langcodeKey));
$fields = array_diff($table_mapping->getFieldNames($this->revisionDataTable), $base_fields);
$revisioned_fields = array_diff($table_mapping->getFieldNames($this->revisionDataTable), $base_fields);
// Find fields that are not revisioned or entity keys. Data fields have
// the same value regardless of entity revision.
$data_fields = array_diff($table_mapping->getFieldNames($this->dataTable), $fields, $base_fields);
$data_fields = array_diff($table_mapping->getFieldNames($this->dataTable), $revisioned_fields, $base_fields);
// If there are no data fields then only revisioned fields are needed
// else both data fields and revisioned fields are needed to map the
// entity values.
$all_fields = $revisioned_fields;
if ($data_fields) {
$fields = array_merge($fields, $data_fields);
$all_fields = array_merge($revisioned_fields, $data_fields);
$query->leftJoin($this->dataTable, 'data', "(revision.$this->idKey = data.$this->idKey)");
$query->fields('data', $data_fields);
$column_names = [];
// Some fields can have more then one columns in the data table so
// column names are needed.
foreach ($data_fields as $data_field) {
// \Drupal\Core\Entity\Sql\TableMappingInterface:: getColumNames()
// returns an array keyed by property names so remove the keys
// before array_merge() to avoid losing data with fields having the
// same columns i.e. value.
$column_names = array_merge($column_names, array_values($table_mapping->getColumnNames($data_field)));
}
$query->fields('data', $column_names);
}
// Get the revision IDs.
......@@ -534,7 +548,7 @@ protected function loadFromSharedTables(array &$values, array &$translations) {
$query->condition('revision.' . $this->revisionKey, $revision_ids, 'IN');
}
else {
$fields = $table_mapping->getFieldNames($this->dataTable);
$all_fields = $table_mapping->getFieldNames($this->dataTable);
}
$result = $query->execute();
......@@ -547,7 +561,7 @@ protected function loadFromSharedTables(array &$values, array &$translations) {
$translations[$id][$langcode] = TRUE;
foreach ($fields as $field_name) {
foreach ($all_fields as $field_name) {
$columns = $table_mapping->getColumnNames($field_name);
// Do not key single-column fields by property name.
if (count($columns) == 1) {
......
......@@ -45,7 +45,11 @@ public function getTableNames();
public function getAllColumns($table_name);
/**
* Gets a list of names of fields stored in the specified table.
* Gets a list of names for entity fields stored in the specified table.
*
* The return list is contains the entity field names, not database field
* (i.e. column) names. To get the mapping of specific entity field to
* database columns use ::getColumnNames().
*
* @param string $table_name
* The name of the table to return the field names for.
......
......@@ -114,6 +114,11 @@ function entity_test_entity_base_field_info(EntityTypeInterface $entity_type) {
->setRevisionable(TRUE)
->setTranslatable(TRUE);
}
if ($entity_type->id() == 'entity_test_mulrev' && \Drupal::state()->get('entity_test.multi_column')) {
$fields['description'] = BaseFieldDefinition::create('shape')
->setLabel(t('Some custom description'))
->setTranslatable(TRUE);
}
return $fields;
}
......
......@@ -174,4 +174,37 @@ public function testNonRevisionableField() {
$this->assertEquals($expected_non_rev_field_revision_ids, $non_rev_field_revision_ids, 'Revision ids found');
}
/**
* Tests multi column non revisionable base field for revisionable entity.
*/
public function testMultiColumnNonRevisionableBaseField() {
\Drupal::state()->set('entity_test.multi_column', TRUE);
\Drupal::entityDefinitionUpdateManager()->applyUpdates();
// Refresh the storage.
$this->mulRev = $this->entityManager->getStorage('entity_test_mulrev');
$user1 = $this->createUser();
// Create a test entity.
$entity = EntityTestMulRev::create([
'name' => $this->randomString(),
'user_id' => $user1->id(),
'language' => 'en',
'non_rev_field' => 'Huron',
'description' => [
'shape' => 'shape',
'color' => 'color',
],
]);
$entity->save();
$entity = $this->mulRev->loadUnchanged($entity->id());
$expected = [
[
'shape' => 'shape',
'color' => 'color',
],
];
$this->assertEquals('Huron', $entity->get('non_rev_field')->value, 'Huron found on entity 1');
$this->assertEquals($expected, $entity->description->getValue());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment