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