Commit 376fb615 authored by xjm's avatar xjm

Issue #2458223 by geertvd, eiriksm, dawehner, lokapujya, Gábor Hojtsy, jeqq,...

Issue #2458223 by geertvd, eiriksm, dawehner, lokapujya, Gábor Hojtsy, jeqq, plach, Dom., jhodgdon, xjm, catch, alexpott, jibran: Duplicated field handlers in field UI for some base table fields
parent da81cd22
......@@ -36,25 +36,24 @@ public function getViewsData() {
),
);
// Advertise this table as a possible base table.
$data['block_content_revision']['table']['base']['help'] = $this->t('Block Content revision is a history of changes to block content.');
$data['block_content_revision']['table']['base']['defaults']['title'] = 'info';
$data['block_content_field_revision']['table']['base']['help'] = $this->t('Block Content revision is a history of changes to block content.');
$data['block_content_field_revision']['table']['base']['defaults']['title'] = 'info';
// @todo EntityViewsData should add these relationships by default.
// https://www.drupal.org/node/2410275
$data['block_content_revision']['id']['relationship']['id'] = 'standard';
$data['block_content_revision']['id']['relationship']['base'] = 'block_content';
$data['block_content_revision']['id']['relationship']['base field'] = 'id';
$data['block_content_revision']['id']['relationship']['title'] = $this->t('Block Content');
$data['block_content_revision']['id']['relationship']['label'] = $this->t('Get the actual block content from a block content revision.');
$data['block_content_revision']['revision_id']['relationship']['id'] = 'standard';
$data['block_content_revision']['revision_id']['relationship']['base'] = 'block_content';
$data['block_content_revision']['revision_id']['relationship']['base field'] = 'revision_id';
$data['block_content_revision']['revision_id']['relationship']['title'] = $this->t('Block Content');
$data['block_content_revision']['revision_id']['relationship']['label'] = $this->t('Get the actual block content from a block content revision.');
$data['block_content_field_revision']['id']['relationship']['id'] = 'standard';
$data['block_content_field_revision']['id']['relationship']['base'] = 'block_content_field_data';
$data['block_content_field_revision']['id']['relationship']['base field'] = 'id';
$data['block_content_field_revision']['id']['relationship']['title'] = $this->t('Block Content');
$data['block_content_field_revision']['id']['relationship']['label'] = $this->t('Get the actual block content from a block content revision.');
$data['block_content_field_revision']['revision_id']['relationship']['id'] = 'standard';
$data['block_content_field_revision']['revision_id']['relationship']['base'] = 'block_content_field_data';
$data['block_content_field_revision']['revision_id']['relationship']['base field'] = 'revision_id';
$data['block_content_field_revision']['revision_id']['relationship']['title'] = $this->t('Block Content');
$data['block_content_field_revision']['revision_id']['relationship']['label'] = $this->t('Get the actual block content from a block content revision.');
return $data;
}
}
......@@ -60,7 +60,7 @@ public function testBlockContentRevisionRelationship() {
$column_map = array(
'revision_id' => 'revision_id',
'id_1' => 'id_1',
'block_content_block_content_revision_id' => 'block_content_block_content_revision_id',
'block_content_field_data_block_content_field_revision_id' => 'block_content_field_data_block_content_field_revision_id',
);
// Here should be two rows.
......@@ -70,12 +70,12 @@ public function testBlockContentRevisionRelationship() {
array(
'revision_id' => '1',
'id_1' => '1',
'block_content_block_content_revision_id' => '1',
'block_content_field_data_block_content_field_revision_id' => '1',
),
array(
'revision_id' => '2',
'id_1' => '1',
'block_content_block_content_revision_id' => '1',
'block_content_field_data_block_content_field_revision_id' => '1',
),
);
$this->assertIdenticalResultset($view_id, $resultset_id, $column_map);
......@@ -87,7 +87,7 @@ public function testBlockContentRevisionRelationship() {
array(
'revision_id' => '2',
'id_1' => '1',
'block_content_block_content_revision_id' => '1',
'block_content_field_data_block_content_field_revision_id' => '1',
),
);
$this->assertIdenticalResultset($view_revision_id, $resultset_revision_id, $column_map);
......
......@@ -8,7 +8,7 @@ label: null
module: views
description: ''
tag: ''
base_table: block_content_revision
base_table: block_content_field_revision
base_field: revision_id
core: '8'
display:
......@@ -17,28 +17,28 @@ display:
relationships:
id:
id: id
table: block_content_revision
table: block_content_field_revision
field: id
required: true
plugin_id: standard
fields:
revision_id:
id: revision_id
table: block_content_revision
table: block_content_field_revision
field: revision_id
plugin_id: field
entity_type: block_content
entity_field: revision_id
id_1:
id: id_1
table: block_content_revision
table: block_content_field_revision
field: id
plugin_id: field
entity_type: block_content
entity_field: id
id:
id: id
table: block_content
table: block_content_field_data
field: id
relationship: id
plugin_id: field
......@@ -47,7 +47,7 @@ display:
arguments:
id:
id: id
table: block_content_revision
table: block_content_field_revision
field: id
plugin_id: numeric
entity_type: block_content
......
......@@ -8,7 +8,7 @@ label: null
module: views
description: ''
tag: ''
base_table: block_content_revision
base_table: block_content_field_revision
base_field: revision_id
core: '8'
display:
......@@ -17,7 +17,7 @@ display:
relationships:
revision_id:
id: revision_id
table: block_content_revision
table: block_content_field_revision
field: revision_id
required: true
entity_type: block_content
......@@ -26,21 +26,21 @@ display:
fields:
revision_id:
id: revision_id
table: block_content_revision
table: block_content_field_revision
field: revision_id
plugin_id: field
entity_type: block_content
entity_field: revision_id
id_1:
id: id_1
table: block_content_revision
table: block_content_field_revision
field: id
plugin_id: field
entity_type: block_content
entity_field: id
id:
id: id
table: block_content
table: block_content_field_data
field: id
relationship: revision_id
plugin_id: field
......@@ -49,7 +49,7 @@ display:
arguments:
id:
id: id
table: block_content_revision
table: block_content_field_revision
field: id
plugin_id: block_content_id
entity_type: block_content
......
......@@ -338,7 +338,7 @@ display:
arguments:
nid:
id: nid
table: node
table: node_field_data
field: nid
relationship: node
group_type: group
......
......@@ -27,7 +27,7 @@ display:
field: nid
id: nid
relationship: none
table: node
table: node_field_data
plugin_id: numeric
pager:
options:
......@@ -39,7 +39,7 @@ display:
id: nid
order: ASC
relationship: none
table: node
table: node_field_data
plugin_id: numeric
display_plugin: default
display_title: Master
......
......@@ -24,7 +24,7 @@ display:
nid:
field: nid
id: nid
table: node
table: node_field_data
plugin_id: node
filters:
field_date_value:
......@@ -38,7 +38,7 @@ display:
id: nid
order: ASC
relationship: none
table: node
table: node_field_data
plugin_id: numeric
pager:
type: full
......
......@@ -24,7 +24,7 @@ display:
nid:
field: nid
id: nid
table: node
table: node_field_data
plugin_id: node
sorts:
field_date_value:
......@@ -39,7 +39,7 @@ display:
id: nid
order: ASC
relationship: none
table: node
table: node_field_data
plugin_id: numeric
pager:
type: full
......
......@@ -9,7 +9,7 @@ label: test_view_fieldapi
module: views
description: ''
tag: default
base_table: node
base_table: node_field_data
base_field: nid
core: '8'
display:
......@@ -21,7 +21,7 @@ display:
nid:
field: nid
id: nid
table: node
table: node_field_data
plugin_id: field
entity_type: node
entity_field: nid
......
......@@ -240,7 +240,7 @@ public function getViewsData() {
'title' => t('Content'),
'label' => t('Get the actual content from a content revision.'),
),
) + $data['node_revision']['vid'];
) + $data['node_field_revision']['vid'];
$data['node_field_revision']['langcode']['help'] = t('The language the original content is in.');
......
......@@ -56,7 +56,7 @@ display:
fields:
nid:
id: nid
table: node
table: node_field_data
field: nid
relationship: none
group_type: group
......
......@@ -41,7 +41,7 @@ display:
fields:
nid:
id: nid
table: node
table: node_field_data
field: nid
plugin_id: field
entity_type: node
......
......@@ -41,7 +41,7 @@ display:
fields:
nid:
id: nid
table: node
table: node_field_data
field: nid
plugin_id: field
entity_type: node
......
......@@ -59,7 +59,7 @@ display:
subquery_namespace: ''
subquery_order: DESC
subquery_regenerate: true
subquery_sort: node.nid
subquery_sort: node_field_data.nid
subquery_view: ''
table: taxonomy_term_field_data
plugin_id: groupwise_max
......
......@@ -156,7 +156,7 @@ display:
plugin_id: field
nid:
id: nid
table: node
table: node_field_data
field: nid
entity_type: node
entity_field: nid
......
......@@ -116,11 +116,29 @@ protected function getFieldStorageDefinitions() {
public function getViewsData() {
$data = [];
$base_table = $this->entityType->getBaseTable();
$base_table = $this->entityType->getBaseTable() ?: $this->entityType->id();
$revisionable = $this->entityType->isRevisionable();
$base_field = $this->entityType->getKey('id');
$data_table = $this->entityType->getDataTable();
$revision_table = $this->entityType->getRevisionTable();
$revision_data_table = $this->entityType->getRevisionDataTable();
$revision_table = '';
if ($revisionable) {
$revision_table = $this->entityType->getRevisionTable() ?: $this->entityType->id() . '_revision';
}
$translatable = $this->entityType->isTranslatable();
$data_table = '';
if ($translatable) {
$data_table = $this->entityType->getDataTable() ?: $this->entityType->id() . '_field_data';
}
// Some entity types do not have a revision data table defined, but still
// have a revision table name set in
// \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() so we
// apply the same kind of logic.
$revision_data_table = '';
if ($revisionable && $translatable) {
$revision_data_table = $this->entityType->getRevisionDataTable() ?: $this->entityType->id() . '_field_revision';
}
$revision_field = $this->entityType->getKey('revision');
// Setup base information of the views data.
......@@ -213,6 +231,10 @@ public function getViewsData() {
// the entity base, revision, data tables.
$field_definitions = $this->entityManager->getBaseFieldDefinitions($this->entityType->id());
if ($table_mapping = $this->storage->getTableMapping()) {
// Fetch all fields that can appear in both the base table and the data
// table.
$entity_keys = $this->entityType->getKeys();
$duplicate_fields = array_intersect_key($entity_keys, array_flip(['id', 'revision', 'bundle']));
// Iterate over each table we have so far and collect field data for each.
// Based on whether the field is in the field_definitions provided by the
// entity manager.
......@@ -221,6 +243,12 @@ public function getViewsData() {
// @todo https://www.drupal.org/node/2337511
foreach ($table_mapping->getTableNames() as $table) {
foreach ($table_mapping->getFieldNames($table) as $field_name) {
// To avoid confusing duplication in the user interface, for fields
// that are on both base and data tables, only add them on the data
// table (same for revision vs. revision data).
if ($data_table && ($table === $base_table || $table === $revision_table) && in_array($field_name, $duplicate_fields)) {
continue;
}
$this->mapFieldDefinition($table, $field_name, $field_definitions[$field_name], $table_mapping, $data[$table]);
}
}
......
<?php
/**
* @file
* Contains \Drupal\views\Tests\Update\FieldHandlersUpdateTest.
*/
namespace Drupal\views\Tests\Update;
use Drupal\system\Tests\Update\UpdatePathTestBase;
use Drupal\views\Entity\View;
/**
* Tests the upgrade path for views field handlers.
*
* @see views_post_update_cleanup_duplicate_views_data()
*
* @group Update
*/
class FieldHandlersUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
__DIR__ . '/../../../tests/fixtures/update/duplicate-field-handler.php',
];
}
/**
* Tests that field handlers are updated properly.
*/
public function testViewsUpdate8004() {
$this->runUpdates();
// Load and initialize our test view.
$view = View::load('test_duplicate_field_handlers');
$data = $view->toArray();
// Check that the field is using the expected base table.
$this->assertEqual('node_field_data', $data['display']['default']['display_options']['fields']['nid']['table']);
$this->assertEqual('node_field_data', $data['display']['default']['display_options']['filters']['type']['table']);
$this->assertEqual('node_field_data', $data['display']['default']['display_options']['sorts']['vid']['table']);
$this->assertEqual('node_field_data', $data['display']['default']['display_options']['arguments']['nid']['table']);
}
}
<?php
$connection = Drupal\Core\Database\Database::getConnection();
$connection->insert('config')
->fields(array(
'collection' => '',
'name' => 'views.view.test_duplicate_field_handlers',
'data' => serialize(\Drupal\Component\Serialization\Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.test_duplicate_field_handlers.yml'))),
))
->execute();
langcode: en
status: true
dependencies:
config:
- node.type.article
module:
- node
- user
id: test_duplicate_field_handlers
label: 'Test Duplicate Field Handlers'
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: perm
options:
perm: 'access content'
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:
items_per_page: null
offset: 0
style:
type: default
row:
type: fields
fields:
nid:
id: nid
table: node
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
filters:
type:
id: type
table: node
field: type
relationship: none
group_type: group
admin_label: ''
operator: in
value:
article: article
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: node
entity_field: type
plugin_id: bundle
sorts:
vid:
id: vid
table: node
field: vid
relationship: none
group_type: group
admin_label: ''
order: ASC
exposed: false
expose:
label: ''
entity_type: node
entity_field: vid
plugin_id: standard
title: 'Test Duplicate Field Handlers'
header: { }
footer: { }
empty: { }
relationships: { }
arguments:
nid:
id: nid
table: node
field: nid
relationship: none
group_type: group
admin_label: ''
default_action: ignore
exception:
value: all
title_enable: false
title: All
title_enable: false
title: ''
default_argument_type: fixed
default_argument_options:
argument: ''
default_argument_skip_url: false
summary_options:
base_path: ''
count: true
items_per_page: 25
override: false
summary:
sort_order: asc
number_of_records: 0
format: default_summary
specify_validation: false
validate:
type: none
fail: 'not found'
validate_options: { }
break_phrase: false
not: false
entity_type: node
entity_field: nid
plugin_id: numeric
display_extenders: { }
cache_metadata:
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- 'user.node_grants:view'
- user.permissions
cacheable: false
page_1:
display_plugin: page
id: page_1
display_title: Page