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')) {
|
if (!$this->languageManager->isMultilingual() || !$this->entityType->hasKey('langcode')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$langcode_key = $this->entityType->getKey('langcode');
|
$langcode_table = $this->getLangcodeTable($query, $relationship);
|
||||||
$storage = \Drupal::entityManager()->getStorage($this->entityType->id());
|
if ($langcode_table) {
|
||||||
|
/** @var \Drupal\views\Plugin\views\query\Sql $query */
|
||||||
if ($table = $storage->getTableMapping()->getFieldTableName($langcode_key)) {
|
$table_alias = $query->ensureTable($langcode_table, $relationship);
|
||||||
$table_alias = $query->ensureTable($table, $relationship);
|
$langcode_key = $this->entityType->getKey('langcode');
|
||||||
$this->langcodeAlias = $query->addField($table_alias, $langcode_key);
|
$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}
|
* {@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\language\Entity\ConfigurableLanguage;
|
||||||
use Drupal\node\Entity\NodeType;
|
use Drupal\node\Entity\NodeType;
|
||||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||||
|
use Drupal\user\Entity\User;
|
||||||
use Drupal\views\Views;
|
use Drupal\views\Views;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +28,10 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
|
||||||
*
|
*
|
||||||
* @var array
|
* @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.
|
* An array of added languages.
|
||||||
|
@ -43,6 +47,20 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
|
||||||
*/
|
*/
|
||||||
protected $expected;
|
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}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -64,19 +82,25 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
|
||||||
ConfigurableLanguage::createFromLangcode($langcode)->save();
|
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.
|
// Make sure we do not try to render non-existing user data.
|
||||||
$node_type = NodeType::create(['type' => 'test']);
|
$node_type = NodeType::create(['type' => 'test']);
|
||||||
$node_type->setDisplaySubmitted(FALSE);
|
$node_type->setDisplaySubmitted(FALSE);
|
||||||
$node_type->save();
|
$node_type->save();
|
||||||
|
|
||||||
$this->values = [];
|
$this->values = [];
|
||||||
|
$this->ids = [];
|
||||||
$controller = \Drupal::entityManager()->getStorage('node');
|
$controller = \Drupal::entityManager()->getStorage('node');
|
||||||
$langcode_index = 0;
|
$langcode_index = 0;
|
||||||
|
|
||||||
for ($i = 0; $i < count($this->langcodes); $i++) {
|
for ($i = 0; $i < count($this->langcodes); $i++) {
|
||||||
// Create a node with a different default language each time.
|
// Create a node with a different default language each time.
|
||||||
$default_langcode = $this->langcodes[$langcode_index++];
|
$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.
|
// Ensure the default language is processed first.
|
||||||
$langcodes = array_merge([$default_langcode], array_diff($this->langcodes, [$default_langcode]));
|
$langcodes = array_merge([$default_langcode], array_diff($this->langcodes, [$default_langcode]));
|
||||||
|
|
||||||
|
@ -92,6 +116,11 @@ class RowEntityRenderersTest extends ViewsKernelTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
$node->save();
|
$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);
|
$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.
|
* Checks that the language renderer configurations work as expected.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue