From 87bc567b6ec9d5aa3d9956888157d0d872705a87 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Mon, 26 Feb 2024 11:15:05 +0000 Subject: [PATCH] Issue #3396741 by recrit, smustgrave: Content Moderation moderation_state_filter cannot join the entity revision table when the filter uses relationship to the entity revision table (cherry picked from commit f742d155c1ee259f88988a6d7b48215b06a53a99) --- .../views/filter/ModerationStateFilter.php | 5 +- ...ation_filter_via_revision_relationship.yml | 351 ++++++++++++++++++ .../content_moderation_test_views.module | 23 ++ .../Kernel/ViewsModerationStateFilterTest.php | 28 ++ 4 files changed, 405 insertions(+), 2 deletions(-) create mode 100644 core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_filter_via_revision_relationship.yml diff --git a/core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php b/core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php index 0dfbe3d865d8..b5b9f1dcc9cc 100644 --- a/core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php +++ b/core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php @@ -144,16 +144,17 @@ protected function opSimple() { $entity_base_table = $entity_type->getBaseTable(); $entity_revision_base_table = $entity_type->isTranslatable() ? $entity_type->getRevisionDataTable() : $entity_type->getRevisionTable(); if ($this->table === $entity_revision_base_table) { + $entity_revision_base_table_alias = $this->relationship ?: $this->table; $configuration = [ 'table' => $entity_base_table, 'field' => $entity_type->getKey('id'), - 'left_table' => $entity_revision_base_table, + 'left_table' => $entity_revision_base_table_alias, 'left_field' => $entity_type->getKey('id'), 'type' => 'INNER', ]; $join = Views::pluginManager('join')->createInstance('standard', $configuration); - $entity_base_table_alias = $this->query->addRelationship($entity_base_table, $join, $entity_revision_base_table); + $entity_base_table_alias = $this->query->addRelationship($entity_base_table, $join, $entity_revision_base_table_alias); } $bundle_condition = $this->view->query->getConnection()->condition('AND'); diff --git a/core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_filter_via_revision_relationship.yml b/core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_filter_via_revision_relationship.yml new file mode 100644 index 000000000000..ca998cde89df --- /dev/null +++ b/core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_filter_via_revision_relationship.yml @@ -0,0 +1,351 @@ +langcode: en +status: true +dependencies: + module: + - content_moderation + - user +id: test_content_moderation_filter_via_revision_relationship +label: test_content_moderation_filter_via_revision_relationship +module: views +description: '' +tag: '' +base_table: users_field_data +base_field: uid +display: + default: + id: default + display_title: Default + display_plugin: default + position: 0 + display_options: + title: test_content_moderation_filter_via_revision_relationship + fields: + name: + id: name + table: users_field_data + field: name + relationship: none + group_type: group + admin_label: '' + entity_type: user + entity_field: name + plugin_id: field + 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: false + ellipsis: false + 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: user_name + settings: + link_to_entity: 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 + title: + id: title + table: node_field_revision + field: title + relationship: uid_revision_test + group_type: group + admin_label: '' + entity_type: node + entity_field: title + plugin_id: field + 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: string + settings: + link_to_entity: 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 + moderation_state: + id: moderation_state + table: node_field_revision + field: moderation_state + relationship: uid_revision_test + group_type: group + admin_label: '' + entity_type: node + plugin_id: moderation_state_field + 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: content_moderation_state + settings: { } + 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 + pager: + type: none + options: + offset: 0 + 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 + access: + type: perm + options: + perm: 'access user profiles' + cache: + type: tag + options: { } + empty: { } + sorts: + vid: + id: vid + table: node_field_revision + field: vid + relationship: uid_revision_test + group_type: group + admin_label: '' + entity_type: node + entity_field: vid + plugin_id: standard + order: ASC + expose: + label: '' + field_identifier: '' + exposed: false + arguments: { } + filters: + moderation_state: + id: moderation_state + table: node_field_revision + field: moderation_state + relationship: uid_revision_test + group_type: group + admin_label: '' + entity_type: node + plugin_id: moderation_state_filter + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: moderation_state_op + label: 'Moderation state' + description: '' + use_operator: false + operator: moderation_state_op + operator_limit_selection: false + operator_list: { } + identifier: moderation_state + 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: { } + style: + type: default + row: + type: fields + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + replica: false + query_tags: { } + relationships: + uid_revision_test: + id: uid_revision_test + table: users_field_data + field: uid_revision_test + relationship: none + group_type: group + admin_label: 'node revisions' + entity_type: user + plugin_id: standard + required: true + header: { } + footer: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - user.permissions + tags: + - 'config:workflow_list' + page_1: + id: page_1 + display_title: Page + display_plugin: page + position: 1 + display_options: + display_extenders: { } + path: test-content-moderation-filter-revision-relationship + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - user.permissions + tags: + - 'config:workflow_list' diff --git a/core/modules/content_moderation/tests/modules/content_moderation_test_views/content_moderation_test_views.module b/core/modules/content_moderation/tests/modules/content_moderation_test_views/content_moderation_test_views.module index 11fe27088391..47f34c21f667 100644 --- a/core/modules/content_moderation/tests/modules/content_moderation_test_views/content_moderation_test_views.module +++ b/core/modules/content_moderation/tests/modules/content_moderation_test_views/content_moderation_test_views.module @@ -20,3 +20,26 @@ function content_moderation_test_views_views_query_alter(ViewExecutable $view, Q $query->addOrderBy('node_field_revision', 'vid', 'ASC'); } } + +/** + * Implements hook_views_data_alter(). + * + * @see \Drupal\Tests\content_moderation\Kernel\ViewsModerationStateFilterTest + */ +function content_moderation_test_views_views_data_alter(array &$data) { + if (isset($data['users_field_data'])) { + $data['users_field_data']['uid_revision_test'] = [ + 'help' => t('Relate the content revision to the user who created it.'), + 'real field' => 'uid', + 'relationship' => [ + 'title' => t('Content revision authored'), + 'help' => t('Relate the content revision to the user who created it. This relationship will create one record for each content revision item created by the user.'), + 'id' => 'standard', + 'base' => 'node_field_revision', + 'base field' => 'uid', + 'field' => 'uid', + 'label' => t('node revisions'), + ], + ]; + } +} diff --git a/core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php b/core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php index c4912798df98..063d91149580 100644 --- a/core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php +++ b/core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php @@ -240,6 +240,34 @@ public function testModerationStateFilterOnJoinedEntity() { ]); $view->execute(); $this->assertIdenticalResultset($view, [], ['name' => 'name']); + + // Revision Data Table Relationship: Filtering by the published state will + // filter out the sample content. + $view = Views::getView('test_content_moderation_filter_via_revision_relationship'); + $view->setExposedInput([ + 'moderation_state' => 'editorial-published', + ]); + $view->execute(); + $this->assertIdenticalResultset($view, [ + [ + 'name' => 'Test user', + 'title' => 'Test node', + 'moderation_state' => 'published', + ], + ], [ + 'name' => 'name', + 'title' => 'title', + 'moderation_state' => 'moderation_state', + ]); + + // Revision Data Table Relationship: Filtering by the draft state will + // filter out the sample content. + $view = Views::getView('test_content_moderation_filter_via_revision_relationship'); + $view->setExposedInput([ + 'moderation_state' => 'editorial-draft', + ]); + $view->execute(); + $this->assertIdenticalResultset($view, [], ['name' => 'name']); } /** -- GitLab