From 32eb238f75f8620098d04496e36ed9329ad03d7f Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Mon, 18 Oct 2021 10:56:59 +0100
Subject: [PATCH] Issue #3231861 by Lendude, GuyPaddock: PHP errors when
 overriding the query settings

---
 .../views/src/Plugin/views/query/Sql.php      | 10 ++-
 .../Functional/Plugin/QueryOptionsTest.php    | 70 +++++++++++++++++++
 2 files changed, 78 insertions(+), 2 deletions(-)
 create mode 100644 core/modules/views/tests/src/Functional/Plugin/QueryOptionsTest.php

diff --git a/core/modules/views/src/Plugin/views/query/Sql.php b/core/modules/views/src/Plugin/views/query/Sql.php
index c6200bc16a96..53a9ac037c68 100644
--- a/core/modules/views/src/Plugin/views/query/Sql.php
+++ b/core/modules/views/src/Plugin/views/query/Sql.php
@@ -326,8 +326,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    */
   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
     $element = ['#parents' => ['query', 'options', 'query_tags']];
-    $value = explode(',', NestedArray::getValue($form_state->getValues(), $element['#parents']));
-    $value = array_filter(array_map('trim', $value));
+    $value = NestedArray::getValue($form_state->getValues(), $element['#parents']);
+    // When toggling a display to override defaults or vice-versa the submit
+    // handler gets invoked twice, and we don't want to bash the values from the
+    // original call.
+    if (is_array($value)) {
+      return;
+    }
+    $value = array_filter(array_map('trim', explode(',', $value)));
     $form_state->setValueForElement($element, $value);
   }
 
diff --git a/core/modules/views/tests/src/Functional/Plugin/QueryOptionsTest.php b/core/modules/views/tests/src/Functional/Plugin/QueryOptionsTest.php
new file mode 100644
index 000000000000..cb027c06e12c
--- /dev/null
+++ b/core/modules/views/tests/src/Functional/Plugin/QueryOptionsTest.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Drupal\Tests\views\Functional\Plugin;
+
+use Drupal\Tests\views\Functional\ViewTestBase;
+
+/**
+ * Tests setting the query options.
+ *
+ * @group views
+ */
+class QueryOptionsTest extends ViewTestBase {
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = ['test_view'];
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = ['node', 'views_ui'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * Test that query overrides are stored.
+   */
+  public function testStoreQuerySettingsOverride() {
+    // Show the default display so the override selection is shown.
+    \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.default_display', TRUE)->save();
+
+    $admin_user = $this->drupalCreateUser([
+      'administer views',
+      'administer site configuration',
+    ]);
+    $this->drupalLogin($admin_user);
+
+    $edit = [];
+    $this->drupalGet('admin/structure/views/view/test_view/edit');
+    $this->submitForm($edit, 'Add Page');
+
+    $this->drupalGet('admin/structure/views/nojs/display/test_view/page_1/query');
+    $this->assertSession()->checkboxNotChecked('query[options][distinct]');
+    $edit = [
+      'override[dropdown]' => 'page_1',
+      'query[options][distinct]' => 1,
+    ];
+    $this->submitForm($edit, 'Apply');
+    $this->drupalGet('admin/structure/views/nojs/display/test_view/page_1/query');
+    $this->assertSession()->checkboxChecked('query[options][distinct]');
+    $edit = [
+      'query[options][query_comment]' => 'comment',
+      'query[options][query_tags]' => 'query_tag, another_tag',
+    ];
+    $this->submitForm($edit, 'Apply');
+    $this->drupalGet('admin/structure/views/nojs/display/test_view/page_1/query');
+    $this->assertSession()->checkboxChecked('query[options][distinct]');
+    $this->assertSession()->fieldValueEquals('query[options][query_comment]', 'comment');
+    $this->assertSession()->fieldValueEquals('query[options][query_tags]', 'query_tag, another_tag');
+  }
+
+}
-- 
GitLab