diff --git a/core/modules/node/src/NodeViewsData.php b/core/modules/node/src/NodeViewsData.php index ef7d5d3efad2..86db01c34f40 100644 --- a/core/modules/node/src/NodeViewsData.php +++ b/core/modules/node/src/NodeViewsData.php @@ -243,8 +243,12 @@ class NodeViewsData extends EntityViewsData { $data['node_field_revision']['langcode']['help'] = $this->t('The language the original content is in.'); - $data['node_revision']['revision_uid']['help'] = $this->t('Relate a content revision to the user who created the revision.'); + $data['node_revision']['revision_uid']['help'] = $this->t('The user who created the revision.'); $data['node_revision']['revision_uid']['relationship']['label'] = $this->t('revision user'); + $data['node_revision']['revision_uid']['filter']['id'] = 'user_name'; + + $data['node_revision']['table']['join']['node_field_data']['left_field'] = 'vid'; + $data['node_revision']['table']['join']['node_field_data']['field'] = 'vid'; $data['node_field_revision']['table']['wizard_id'] = 'node_field_revision'; diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_uid.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_uid.yml new file mode 100644 index 000000000000..19d5b7f2d835 --- /dev/null +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_uid.yml @@ -0,0 +1,389 @@ +langcode: en +status: true +dependencies: + module: + - node + - user +id: test_node_revision_uid +label: 'Test node revision uid' +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +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: + 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: false + 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 + vid: + id: vid + table: node_field_revision + field: vid + 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: false + 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: vid + plugin_id: field + uid: + id: uid + table: node_field_data + field: uid + 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: target_id + type: entity_reference_label + settings: + link: false + group_column: target_id + 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: uid + plugin_id: field + revision_uid: + id: revision_uid + table: node_revision + field: revision_uid + 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: target_id + type: entity_reference_label + settings: + link: false + group_column: target_id + 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: revision_uid + plugin_id: field + filters: + revision_uid: + id: revision_uid + table: node_revision + field: revision_uid + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: revision_uid_op + label: 'Revision user' + description: '' + use_operator: false + operator: revision_uid_op + operator_limit_selection: false + operator_list: { } + identifier: revision_uid + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + 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: revision_uid + plugin_id: user_name + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + filter_groups: + operator: AND + groups: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/core/modules/node/tests/src/Kernel/Views/RevisionUidTest.php b/core/modules/node/tests/src/Kernel/Views/RevisionUidTest.php new file mode 100644 index 000000000000..c83a540e86b5 --- /dev/null +++ b/core/modules/node/tests/src/Kernel/Views/RevisionUidTest.php @@ -0,0 +1,156 @@ + 'nid', + 'vid' => 'vid', + 'uid' => 'uid', + 'revision_uid' => 'revision_uid', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp($import_test_views = TRUE) { + parent::setUp($import_test_views); + + $this->installSchema('node', 'node_access'); + $this->installEntitySchema('node'); + $this->installEntitySchema('user'); + + if ($import_test_views) { + ViewTestData::createTestViews(get_class($this), ['node_test_views']); + } + } + + /** + * Tests the node_revision_uid relationship. + */ + public function testRevisionUid() { + $primary_author = $this->createUser(); + $secondary_author = $this->createUser(); + + $node_type = NodeType::create([ + 'type' => 'page', + ]); + $node_type->save(); + $node = Node::create([ + 'title' => 'Test node', + 'type' => 'page', + 'uid' => $primary_author->id(), + ]); + $node->save(); + $view = Views::getView('test_node_revision_uid'); + $this->executeView($view); + $this->assertIdenticalResultset($view, [ + [ + 'nid' => 1, + 'vid' => 1, + 'uid' => $primary_author->id(), + 'revision_uid' => $primary_author->id(), + ], + ], static::$columnMap); + + // Test results shows the original author as well as the revision author. + $node->setRevisionUser($secondary_author); + $node->setNewRevision(); + $node->save(); + + $view = Views::getView('test_node_revision_uid'); + $this->executeView($view); + $this->assertIdenticalResultset($view, [ + [ + 'nid' => 1, + 'vid' => 2, + 'uid' => $primary_author->id(), + 'revision_uid' => $secondary_author->id(), + ], + ], static::$columnMap); + + // Build a larger dataset to allow filtering. + $node2_title = $this->randomString(); + $node2 = Node::create([ + 'title' => $node2_title, + 'type' => 'page', + 'uid' => $primary_author->id(), + ]); + $node2->save(); + $node2->setRevisionUser($primary_author); + $node2->setNewRevision(); + $node2->save(); + + $view = Views::getView('test_node_revision_uid'); + $this->executeView($view); + $this->assertIdenticalResultset($view, [ + [ + 'nid' => 1, + 'vid' => 2, + 'uid' => $primary_author->id(), + 'revision_uid' => $secondary_author->id(), + ], + [ + 'nid' => 2, + 'vid' => 4, + 'uid' => $primary_author->id(), + 'revision_uid' => $primary_author->id(), + ], + ], static::$columnMap); + + // Test filter by revision_uid. + $view = Views::getView('test_node_revision_uid'); + $view->initHandlers(); + $view->filter['revision_uid']->value = [$secondary_author->id()]; + $this->executeView($view); + $this->assertIdenticalResultset($view, [ + [ + 'nid' => 1, + 'vid' => 2, + 'uid' => $primary_author->id(), + 'revision_uid' => $secondary_author->id(), + ], + ], static::$columnMap); + } + +}