Issue #2896381 by plach, Sam152, tacituseu, amateescu, Berdir: TranslationLanguageRenderer uses the wrong table for the langcode column with entity revision views

8.5.x
Nathaniel Catchpole 2017-08-11 13:13:53 +09:00
parent e6f77992cd
commit 10c87c672e
3 changed files with 309 additions and 7 deletions

View File

@ -28,15 +28,54 @@ class TranslationLanguageRenderer extends EntityTranslationRendererBase {
if (!$this->languageManager->isMultilingual() || !$this->entityType->hasKey('langcode')) {
return;
}
$langcode_key = $this->entityType->getKey('langcode');
$storage = \Drupal::entityManager()->getStorage($this->entityType->id());
if ($table = $storage->getTableMapping()->getFieldTableName($langcode_key)) {
$table_alias = $query->ensureTable($table, $relationship);
$langcode_table = $this->getLangcodeTable($query, $relationship);
if ($langcode_table) {
/** @var \Drupal\views\Plugin\views\query\Sql $query */
$table_alias = $query->ensureTable($langcode_table, $relationship);
$langcode_key = $this->entityType->getKey('langcode');
$this->langcodeAlias = $query->addField($table_alias, $langcode_key);
}
}
/**
* Returns the name of the table holding the "langcode" field.
*
* @param \Drupal\views\Plugin\views\query\QueryPluginBase $query
* The query being executed.
* @param string $relationship
* The relationship used by the entity type.
*
* @return string
* A table name.
*/
protected function getLangcodeTable(QueryPluginBase $query, $relationship) {
/** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
$storage = \Drupal::entityTypeManager()->getStorage($this->entityType->id());
$langcode_key = $this->entityType->getKey('langcode');
$langcode_table = $storage->getTableMapping()->getFieldTableName($langcode_key);
// If the entity type is revisionable, we need to take into account views of
// entity revisions. Usually the view will use the entity data table as the
// query base table, however, in case of an entity revision view, we need to
// use the revision table or the revision data table, depending on which one
// is being used as query base table.
if ($this->entityType->isRevisionable()) {
$query_base_table = isset($query->relationships[$relationship]['base']) ?
$query->relationships[$relationship]['base'] :
$this->view->storage->get('base_table');
$revision_table = $storage->getRevisionTable();
$revision_data_table = $storage->getRevisionDataTable();
if ($query_base_table === $revision_table) {
$langcode_table = $revision_table;
}
elseif ($query_base_table === $revision_data_table) {
$langcode_table = $revision_data_table;
}
}
return $langcode_table;
}
/**
* {@inheritdoc}
*/

View File

@ -0,0 +1,225 @@
uuid: b133bd43-c494-4db6-83f0-24380fe3964b
langcode: en
status: true
dependencies:
module:
- user
id: test_entity_row_renderers_revisions_base
label: test_entity_row_renderers_revisions_base
module: views
description: ''
tag: ''
base_table: node_field_revision
base_field: vid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: perm
options:
perm: 'view all revisions'
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: none
options:
offset: 0
style:
type: default
options:
grouping: { }
row_class: ''
default_row_class: true
uses_fields: false
row:
type: fields
options:
inline: { }
separator: ''
hide_empty: false
default_field_elements: true
fields:
nid:
id: nid
table: node_field_revision
field: nid
relationship: none
group_type: group
admin_label: ''
label: ''
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: number_integer
settings:
thousand_separator: ''
prefix_suffix: true
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: node
entity_field: nid
plugin_id: field
uid:
id: uid
table: users_field_data
field: uid
relationship: revision_uid
group_type: group
admin_label: ''
label: ''
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: number_integer
settings:
thousand_separator: ''
prefix_suffix: true
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: user
entity_field: uid
plugin_id: field
filters: { }
sorts: { }
header: { }
footer: { }
empty: { }
relationships:
revision_uid:
id: revision_uid
table: node_revision
field: revision_uid
relationship: none
group_type: group
admin_label: 'revision user'
required: false
entity_type: node
entity_field: revision_uid
plugin_id: standard
arguments: { }
display_extenders: { }
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- 'user.node_grants:view'
- user.permissions
tags: { }

View File

@ -5,6 +5,7 @@ namespace Drupal\Tests\views\Kernel\Entity;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
use Drupal\user\Entity\User;
use Drupal\views\Views;
/**
@ -27,7 +28,10 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
*
* @var array
*/
public static $testViews = ['test_entity_row_renderers'];
public static $testViews = [
'test_entity_row_renderers',
'test_entity_row_renderers_revisions_base',
];
/**
* An array of added languages.
@ -43,6 +47,20 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
*/
protected $expected;
/**
* The author of the test content.
*
* @var \Drupal\user\UserInterface
*/
protected $testAuthor;
/**
* An array of IDs of the test content.
*
* @var array[]
*/
protected $testIds;
/**
* {@inheritdoc}
*/
@ -64,19 +82,25 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
ConfigurableLanguage::createFromLangcode($langcode)->save();
}
$this->testAuthor = User::create([
'name' => 'foo',
]);
$this->testAuthor->save();
// Make sure we do not try to render non-existing user data.
$node_type = NodeType::create(['type' => 'test']);
$node_type->setDisplaySubmitted(FALSE);
$node_type->save();
$this->values = [];
$this->ids = [];
$controller = \Drupal::entityManager()->getStorage('node');
$langcode_index = 0;
for ($i = 0; $i < count($this->langcodes); $i++) {
// Create a node with a different default language each time.
$default_langcode = $this->langcodes[$langcode_index++];
$node = $controller->create(['type' => 'test', 'uid' => 0, 'langcode' => $default_langcode]);
$node = $controller->create(['type' => 'test', 'uid' => $this->testAuthor->id(), 'langcode' => $default_langcode]);
// Ensure the default language is processed first.
$langcodes = array_merge([$default_langcode], array_diff($this->langcodes, [$default_langcode]));
@ -92,6 +116,11 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
}
$node->save();
$this->ids[] = [
'nid' => $node->id(),
'uid' => $this->testAuthor->id(),
];
}
}
}
@ -110,6 +139,15 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
$this->checkLanguageRenderers('page_2', $this->values);
}
/**
* Tests the row renderer with a revision base table.
*/
public function testRevisionBaseTable() {
$view = Views::getView('test_entity_row_renderers_revisions_base');
$view->execute();
$this->assertIdenticalResultset($view, $this->ids, ['nid' => 'nid', 'uid' => 'uid']);
}
/**
* Checks that the language renderer configurations work as expected.
*