diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php index 0163b551b3592cc12ba8241635defdc55650bd93..7758aee4e0d8bd8915ad91772966cc5a5f56b838 100644 --- a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php +++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php @@ -344,6 +344,12 @@ public function validateExposed(&$form, FormStateInterface $form_state) { } $identifier = $this->options['expose']['identifier']; + $input = $form_state->getValue($identifier); + + if ($this->options['is_grouped'] && isset($this->options['group_info']['group_items'][$input])) { + $this->validated_exposed_input = $this->options['group_info']['group_items'][$input]['value']; + return; + } // We only validate if they've chosen the text field style. if ($this->options['type'] != 'textfield') { diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_exposed_grouped_filter.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_exposed_grouped_filter.yml new file mode 100644 index 0000000000000000000000000000000000000000..cf92bcce3e5f9be3280338281434291f8894c8db --- /dev/null +++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_exposed_grouped_filter.yml @@ -0,0 +1,271 @@ +langcode: en +status: true +dependencies: + config: + - node.type.article + - taxonomy.vocabulary.tags + module: + - node + - taxonomy + - user +id: test_taxonomy_exposed_grouped_filter +label: 'Test Taxonomy Exposed Grouped Filter' +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +display: + default: + display_plugin: default + id: default + display_title: Default + 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: mini + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: ‹‹ + next: ›› + 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: + title: + id: title + table: node_field_data + field: title + entity_type: node + entity_field: title + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + settings: + link_to_entity: true + plugin_id: field + relationship: none + group_type: group + admin_label: '' + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + click_sort_column: value + type: string + 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 + filters: + status: + value: '1' + table: node_field_data + field: status + plugin_id: boolean + entity_type: node + entity_field: status + id: status + expose: + operator: '' + operator_limit_selection: false + operator_list: { } + group: 1 + type: + id: type + table: node_field_data + field: type + value: + article: article + entity_type: node + entity_field: type + plugin_id: bundle + expose: + operator_limit_selection: false + operator_list: { } + field_views_testing_tags_target_id: + id: field_views_testing_tags_target_id + table: node__field_views_testing_tags + field: field_views_testing_tags_target_id + relationship: none + group_type: group + admin_label: '' + operator: or + value: { } + group: 1 + exposed: true + expose: + operator_id: field_views_testing_tags_target_id_op + label: 'views_testing_tags (field_views_testing_tags)' + description: null + use_operator: false + operator: field_views_testing_tags_target_id_op + operator_limit_selection: false + operator_list: { } + identifier: field_views_testing_tags_target_id + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + reduce: false + is_grouped: true + group_info: + label: 'views_testing_tags (field_views_testing_tags)' + description: '' + identifier: field_views_testing_tags_target_id + optional: true + widget: radios + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: + 1: + title: 'Group 1' + operator: or + value: + 1: '1' + 2: '2' + 2: + title: 'Group 2' + operator: or + value: + 3: '3' + 4: '4' + 3: + title: 'Group 3' + operator: or + value: + 1: '1' + 5: '5' + reduce_duplicates: false + type: select + limit: true + vid: tags + hierarchy: false + error_message: true + plugin_id: taxonomy_index_tid + sorts: + created: + id: created + table: node_field_data + field: created + order: DESC + entity_type: node + entity_field: created + plugin_id: date + relationship: none + group_type: group + admin_label: '' + exposed: false + expose: + label: '' + field_identifier: '' + granularity: second + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - user + - 'user.node_grants:view' + - user.permissions + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: test-taxonomy-exposed-grouped-filter + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - user + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php index d48d79414e198de5e3a6f0073e253a0c70841df9..51d1398b304ef03c9a4b68a88d6deec420dffcce 100644 --- a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php @@ -24,7 +24,11 @@ class TaxonomyIndexTidUiTest extends UITestBase { * * @var array */ - public static $testViews = ['test_filter_taxonomy_index_tid', 'test_taxonomy_term_name']; + public static $testViews = [ + 'test_filter_taxonomy_index_tid', + 'test_taxonomy_term_name', + 'test_taxonomy_exposed_grouped_filter', + ]; /** * {@inheritdoc} @@ -230,6 +234,50 @@ public function testExposedFilter() { $this->assertSession()->elementNotExists('xpath', "//div[@class='view-content']"); } + /** + * Tests exposed grouped taxonomy filters. + */ + public function testExposedGroupedFilter() { + // Create a content type with a taxonomy field. + $this->drupalCreateContentType(['type' => 'article']); + $field_name = 'field_views_testing_tags'; + $this->createEntityReferenceField('node', 'article', $field_name, NULL, 'taxonomy_term'); + + $nodes = []; + for ($i = 0; $i < 3; $i++) { + $node = []; + $node['type'] = 'article'; + $node['field_views_testing_tags'][0]['target_id'] = $this->terms[$i][0]->id(); + $nodes[] = $this->drupalCreateNode($node); + } + + $this->drupalGet('/admin/structure/views/nojs/handler/test_taxonomy_exposed_grouped_filter/page_1/filter/field_views_testing_tags_target_id'); + $edit = [ + 'options[group_info][group_items][1][value][]' => [$this->terms[0][0]->id(), $this->terms[1][0]->id()], + 'options[group_info][group_items][2][value][]' => [$this->terms[1][0]->id(), $this->terms[2][0]->id()], + 'options[group_info][group_items][3][value][]' => [$this->terms[2][0]->id(), $this->terms[0][0]->id()], + ]; + $this->submitForm($edit, 'Apply'); + $this->submitForm([], 'Save'); + + // Visit the view's page url and validate the results. + $this->drupalGet('/test-taxonomy-exposed-grouped-filter'); + $this->submitForm(['field_views_testing_tags_target_id' => 1], 'Apply'); + $this->assertSession()->pageTextContains($nodes[0]->getTitle()); + $this->assertSession()->pageTextContains($nodes[1]->getTitle()); + $this->assertSession()->pageTextNotContains($nodes[2]->getTitle()); + + $this->submitForm(['field_views_testing_tags_target_id' => 2], 'Apply'); + $this->assertSession()->pageTextContains($nodes[1]->getTitle()); + $this->assertSession()->pageTextContains($nodes[2]->getTitle()); + $this->assertSession()->pageTextNotContains($nodes[0]->getTitle()); + + $this->submitForm(['field_views_testing_tags_target_id' => 3], 'Apply'); + $this->assertSession()->pageTextContains($nodes[0]->getTitle()); + $this->assertSession()->pageTextContains($nodes[2]->getTitle()); + $this->assertSession()->pageTextNotContains($nodes[1]->getTitle()); + } + /** * Tests that an exposed taxonomy filter doesn't show unpublished terms. */