Issue #2896381 by plach, Sam152, tacituseu, amateescu, Berdir: TranslationLanguageRenderer uses the wrong table for the langcode column with entity revision views
parent
e6f77992cd
commit
10c87c672e
|
@ -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}
|
||||
*/
|
||||
|
|
|
@ -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: { }
|
||||
|
|
@ -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.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue