From 6a1752cce9a3c376c9076e094f9a34e78e236939 Mon Sep 17 00:00:00 2001
From: Florent Torregrosa
 <14238-florenttorregrosa@users.noreply.drupalcode.org>
Date: Fri, 2 Jun 2023 10:17:22 +0200
Subject: [PATCH 1/2] Issue #3352946 by Grimreaper: Get forms are always
 validated

---
 src/HookHandler/FormAlter.php       | 60 +++++++++++++++++++++++++++++
 src/HookHandler/PreprocessInput.php |  5 ++-
 ui_suite_bootstrap.theme            | 11 ++++++
 3 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 src/HookHandler/FormAlter.php

diff --git a/src/HookHandler/FormAlter.php b/src/HookHandler/FormAlter.php
new file mode 100644
index 00000000..a04b4649
--- /dev/null
+++ b/src/HookHandler/FormAlter.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\ui_suite_bootstrap\HookHandler;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+
+/**
+ * Alter forms.
+ */
+class FormAlter {
+
+  /**
+   * Alter forms.
+   *
+   * @param array $form
+   *   The form structure.
+   * @param \Drupal\Core\Form\FormStateInterface $formState
+   *   The form state.
+   * @param string $form_id
+   *   The form ID.
+   */
+  public function alter(array &$form, FormStateInterface $formState, string $form_id): void {
+    // See \Drupal\Core\Form\FormBuilder::processForm().
+    if ($formState->isMethodType('get') && $formState->getAlwaysProcess()) {
+      $form['#after_build'][] = [
+        static::class,
+        'afterBuildAddGetFormMethod',
+      ];
+    }
+  }
+
+  /**
+   * Form element #after_build callback.
+   */
+  public static function afterBuildAddGetFormMethod(array $element, FormStateInterface $form_state): array {
+    static::addGetFormMethod($element);
+    return $element;
+  }
+
+  /**
+   * Set form method to all form elements.
+   *
+   * To allow other processing to act based on this information.
+   *
+   * @param array $form
+   *   The form or form element which children should have form method attached.
+   */
+  protected static function addGetFormMethod(array &$form): void {
+    foreach (Element::children($form) as $child) {
+      if (!isset($form[$child]['#form_method'])) {
+        $form[$child]['#form_method'] = 'get';
+      }
+      static::addGetFormMethod($form[$child]);
+    }
+  }
+
+}
diff --git a/src/HookHandler/PreprocessInput.php b/src/HookHandler/PreprocessInput.php
index 26600a84..c5460897 100644
--- a/src/HookHandler/PreprocessInput.php
+++ b/src/HookHandler/PreprocessInput.php
@@ -132,7 +132,10 @@ class PreprocessInput {
       if ($this->element->getProperty('errors')) {
         $this->element->addClass('is-invalid');
       }
-      else {
+      // Per \Drupal\Core\Form\processForm::processForm(), GET forms are always
+      // processed and validated, so we exclude the valid feedback for GET
+      // forms.
+      elseif (!($this->element->hasProperty('form_method')) || $this->element->getProperty('form_method') != 'get') {
         $this->element->addClass('is-valid');
       }
     }
diff --git a/ui_suite_bootstrap.theme b/ui_suite_bootstrap.theme
index da8eaa66..e210c100 100644
--- a/ui_suite_bootstrap.theme
+++ b/ui_suite_bootstrap.theme
@@ -11,6 +11,7 @@ use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Template\AttributeHelper;
 use Drupal\ui_suite_bootstrap\HookHandler\ElementInfoAlter;
+use Drupal\ui_suite_bootstrap\HookHandler\FormAlter;
 use Drupal\ui_suite_bootstrap\HookHandler\FormCommerceCheckoutFlowMultistepDefaultAlter;
 use Drupal\ui_suite_bootstrap\HookHandler\FormSearchBlockFormAlter;
 use Drupal\ui_suite_bootstrap\HookHandler\PreprocessFormElement;
@@ -43,6 +44,16 @@ function ui_suite_bootstrap_element_info_alter(array &$info): void {
   $instance->alter($info);
 }
 
+/**
+ * Implements hook_form_alter().
+ */
+function ui_suite_bootstrap_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
+  /** @var \Drupal\ui_suite_bootstrap\HookHandler\FormAlter $instance */
+  $instance = \Drupal::service('class_resolver')
+    ->getInstanceFromDefinition(FormAlter::class);
+  $instance->alter($form, $form_state, $form_id);
+}
+
 /**
  * Implements hook_form_FORM_ID_alter() for 'commerce_checkout_flow_multistep_default'.
  */
-- 
GitLab


From 8dd035f24db49dd8b1d96a1d8b8efbc0a9132af9 Mon Sep 17 00:00:00 2001
From: Florent Torregrosa
 <14238-florenttorregrosa@users.noreply.drupalcode.org>
Date: Fri, 2 Jun 2023 10:24:55 +0200
Subject: [PATCH 2/2] Issue #3352946 by Grimreaper: Get forms are always
 validated

---
 src/HookHandler/PreprocessInput.php | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/HookHandler/PreprocessInput.php b/src/HookHandler/PreprocessInput.php
index c5460897..d3f6139a 100644
--- a/src/HookHandler/PreprocessInput.php
+++ b/src/HookHandler/PreprocessInput.php
@@ -127,12 +127,13 @@ class PreprocessInput {
       return;
     }
 
-    // This is the same test as in RenderElement::setAttributes().
+    // This is the same test as in
+    // \Drupal\Core\Render\Element\RenderElement::setAttributes().
     if ($this->element->getProperty('parents') && $this->element->getProperty('validated')) {
       if ($this->element->getProperty('errors')) {
         $this->element->addClass('is-invalid');
       }
-      // Per \Drupal\Core\Form\processForm::processForm(), GET forms are always
+      // Per \Drupal\Core\Form\FormBuilder::processForm(), GET forms are always
       // processed and validated, so we exclude the valid feedback for GET
       // forms.
       elseif (!($this->element->hasProperty('form_method')) || $this->element->getProperty('form_method') != 'get') {
-- 
GitLab