1,20d0 < diff --git a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml < index 9ec9758185..98be95b22d 100644 < --- a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml < +++ b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml < @@ -120,9 +120,12 @@ views.filter.taxonomy_index_tid: < type: views.filter.many_to_one < label: 'Taxonomy term ID' < mapping: < - vid: < - type: string < - label: 'Vocabulary' < + vids: < + type: sequence < + label: 'Vocabularies' < + sequence: < + type: string < + label: 'Vocabulary' < type: < type: string < label: 'Selection type' 22c2 < index efadf83126..baf3c68f15 100644 --- > index efadf83126..42685c79f3 100644 71c51 < + $this->options['vids'] = [$first_vocabulary->id()]; --- > + $this->options['vids'] = $first_vocabulary->id(); 128,129c108 < - $terms = $this->value ? Term::loadMultiple(($this->value)) : []; < + $terms = $this->value ? Term::loadMultiple($this->value) : []; --- > $terms = $this->value ? Term::loadMultiple(($this->value)) : []; 171c150 < @@ -195,16 +223,22 @@ protected function valueForm(&$form, FormStateInterface $form_state) { --- > @@ -195,12 +223,18 @@ protected function valueForm(&$form, FormStateInterface $form_state) { 193,197d171 < - $default_value = (array) $this->value; < + $default_value = $this->value; < < if ($exposed = $form_state->get('exposed')) { < $identifier = $this->options['expose']['identifier']; 310c284 < index 8b1b822e3e..ab3879f30b 100644 --- > index 8b1b822e3e..edf0c03ab8 100644 339c313 < @@ -46,13 +55,38 @@ class TaxonomyIndexTidUiTest extends UITestBase { --- > @@ -46,13 +55,30 @@ class TaxonomyIndexTidUiTest extends UITestBase { 370,377d343 < + < + $vocab = Vocabulary::load($vocab_id); < + if (!$vocab) { < + Vocabulary::create([ < + 'vid' => $vocab_id, < + 'name' => 'Test Vocabulary ' . $vocab_id, < + ])->save(); < + } 381c347 < @@ -61,29 +95,26 @@ protected function setUp($import_test_views = TRUE) { --- > @@ -61,22 +87,18 @@ protected function setUp($import_test_views = TRUE) { 408,417c374 < * Tests the filter UI. < */ < public function testFilterUI() { < - $this->drupalGet('admin/structure/views/nojs/handler/test_filter_taxonomy_index_tid/default/filter/tid'); < + $out = $this->drupalGet('admin/structure/views/nojs/handler/test_filter_taxonomy_index_tid/default/filter/tid'); < + $this->assertFieldByXpath('//select[@id="edit-options-value"]', NULL); < < $result = $this->xpath('//select[@id="edit-options-value"]/option'); < < @@ -126,6 +157,75 @@ public function testFilterUI() { --- > @@ -126,6 +148,75 @@ public function testFilterUI() { 493,519c450,567 < @@ -203,7 +303,11 @@ public function testExposedFilter() { < ]; < $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_taxonomy_term_name/default/filter', $edit, 'Add and configure filter criteria'); < // Select 'Empty Vocabulary' and 'Autocomplete' from the list of options. < - $this->drupalPostForm('admin/structure/views/nojs/handler-extra/test_taxonomy_term_name/default/filter/tid', [], 'Apply and continue'); < + $edit = [ < + 'options[vids][empty_vocabulary]' => TRUE, < + 'options[type]' => 'textfield', < + ]; < + $this->drupalPostForm('admin/structure/views/nojs/handler-extra/test_taxonomy_term_name/default/filter/tid', $edit, 'Apply and continue'); < // Expose the filter. < $edit = ['options[expose_button][checkbox][checkbox]' => TRUE]; < $this->drupalPostForm('admin/structure/views/nojs/handler/test_taxonomy_term_name/default/filter/tid', $edit, 'Expose filter'); < diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml < index 26b1d3259e..f855181fd5 100644 < --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml < +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml < @@ -108,7 +108,8 @@ display: < reduce_duplicates: false < type: select < limit: true < - vid: test_exposed_checkboxes < + vids: < + - test_exposed_checkboxes < hierarchy: false < error_message: true < plugin_id: taxonomy_index_tid --- > diff --git a/core/modules/views/views.module b/core/modules/views/views.module > index b82f36d4a5..09a5bc594f 100644 > --- a/core/modules/views/views.module > +++ b/core/modules/views/views.module > @@ -29,7 +29,9 @@ function views_help($route_name, RouteMatchInterface $route_match) { > $output .= '

' . t('About') . '

'; > $output .= '

' . t('The Views module provides a back end to fetch information from content, user accounts, taxonomy terms, and other entities from the database and present it to the user as a grid, HTML list, table, unformatted list, etc. The resulting displays are known generally as views.') . '

'; > $output .= '

' . t('For more information, see the online documentation for the Views module.', [':views' => 'https://www.drupal.org/documentation/modules/views']) . '

'; > - $output .= '

' . t('In order to create and modify your own views using the administration and configuration user interface, you will need to enable either the Views UI module in core or a contributed module that provides a user interface for Views. See the Views UI module help page for more information.', [':views-ui' => (\Drupal::moduleHandler()->moduleExists('views_ui')) ? \Drupal::url('help.page', ['name' => 'views_ui']) : '#']) . '

'; > + $output .= '

' . t('In order to create and modify your own views using the administration and configuration user interface, you will need to enable either the Views UI module in core or a contributed module that provides a user interface for Views. See the Views UI module help page for more information.', [ > + ':views-ui' => (\Drupal::moduleHandler()->moduleExists('views_ui')) ? \Drupal::url('help.page', ['name' => 'views_ui']) : '#' > + ]) . '

'; > $output .= '

' . t('Uses') . '

'; > $output .= '
'; > $output .= '
' . t('Adding functionality to administrative pages') . '
'; > @@ -91,7 +93,12 @@ function views_theme($existing, $type, $theme, $path) { > > // Our extra version of pager from pager.inc > $hooks['views_mini_pager'] = $base + [ > - 'variables' => ['tags' => [], 'quantity' => 9, 'element' => 0, 'parameters' => []], > + 'variables' => [ > + 'tags' => [], > + 'quantity' => 9, > + 'element' => 0, > + 'parameters' => [], > + ], > ]; > > $variables = [ > @@ -113,8 +120,18 @@ function views_theme($existing, $type, $theme, $path) { > 'attachment_before' => [], > 'attachment_after' => [], > ], > - 'style' => ['view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL], > - 'row' => ['view' => NULL, 'options' => NULL, 'row' => NULL, 'field_alias' => NULL], > + 'style' => [ > + 'view' => NULL, > + 'options' => NULL, > + 'rows' => NULL, > + 'title' => NULL, > + ], > + 'row' => [ > + 'view' => NULL, > + 'options' => NULL, > + 'row' => NULL, > + 'field_alias' => NULL, > + ], > 'exposed_form' => ['view' => NULL, 'options' => NULL], > 'pager' => [ > 'view' => NULL, > @@ -131,7 +148,13 @@ function views_theme($existing, $type, $theme, $path) { > 'variables' => ['view' => NULL, 'field' => NULL, 'row' => NULL], > ]; > $hooks['views_view_grouping'] = $base + [ > - 'variables' => ['view' => NULL, 'grouping' => NULL, 'grouping_level' => NULL, 'rows' => NULL, 'title' => NULL], > + 'variables' => [ > + 'view' => NULL, > + 'grouping' => NULL, > + 'grouping_level' => NULL, > + 'rows' => NULL, > + 'title' => NULL, > + ], > ]; > > // Only display, pager, row, and style plugins can provide theme hooks. > @@ -241,9 +264,10 @@ function views_preprocess_node(&$variables) { > // If a node is being rendered in a view, and the view does not have a path, > // prevent drupal from accidentally setting the $page variable: > if (!empty($variables['view']->current_display) > - && $variables['page'] > - && $variables['view_mode'] == 'full' > - && !$variables['view']->display_handler->hasPath()) { > + && $variables['page'] > + && $variables['view_mode'] == 'full' > + && !$variables['view']->display_handler->hasPath() > + ) { > $variables['page'] = FALSE; > } > } > @@ -872,6 +896,23 @@ function views_view_presave(ViewEntityInterface $view) { > $displays = $view->get('display'); > $changed = FALSE; > foreach ($displays as $display_name => &$display) { > + if (isset($display['display_options']['filters'])) { > + foreach ($display['display_options']['filters'] as $filter_name => $filter) { > + if (isset($filter['plugin_id']) && $filter['plugin_id'] === 'boolean') { > + $new_value = FALSE; > + // Update all boolean and integer values to strings. > + if ($filter['value'] === TRUE || $filter['value'] === 1) { > + $new_value = '1'; > + } > + elseif ($filter['value'] === FALSE || $filter['value'] === 0) { > + $new_value = '0'; > + } > + if ($new_value !== FALSE) { > + $view->set("display.$display_name.display_options.filters.$filter_name.value", $new_value); > + } > + } > + } > + } > if (isset($display['display_options']['fields'])) { > foreach ($display['display_options']['fields'] as $field_name => &$field) { > if (isset($field['plugin_id']) && $field['plugin_id'] === 'entity_link') { > diff --git a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php > index 8e71123389..ff7f53ce6b 100644 > --- a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php > +++ b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php > @@ -95,6 +95,10 @@ public function buildForm(array $form, FormStateInterface $form_state) { > */ > public function validateForm(array &$form, FormStateInterface $form_state) { > $form_state->get('handler')->validateExtraOptionsForm($form['options'], $form_state); > + > + if ($form_state->getErrors()) { > + $form_state->set('rerender', TRUE); > + } > } > > /**