diff --git a/core/includes/pager.inc b/core/includes/pager.inc index e532a96..2a535bc 100644 --- a/core/includes/pager.inc +++ b/core/includes/pager.inc @@ -148,6 +148,10 @@ function pager_default_initialize($total, $limit, $element = 0) { function pager_get_query_parameters() { $query = &drupal_static(__FUNCTION__); if (!isset($query)) { + // There is a chance that the pager is rendered in the context of an ajax + // form request. Therefore exclude AJAX_FORM_REQUEST from there, as + // otherwise clicking the link would be interpreted potentially as form + // request, especially when done as POST request using JS. $query = UrlHelper::filterQueryParameters(\Drupal::request()->query->all(), array('page', \Drupal\Core\Form\FormBuilderInterface::AJAX_FORM_REQUEST)); } return $query; diff --git a/core/lib/Drupal/Core/Form/FormState.php b/core/lib/Drupal/Core/Form/FormState.php index 8e6f13a..294846a 100644 --- a/core/lib/Drupal/Core/Form/FormState.php +++ b/core/lib/Drupal/Core/Form/FormState.php @@ -475,8 +475,7 @@ public function getButtons() { * {@inheritdoc} */ public function setCached($cache = TRUE) { - // We try to determine whether this is the initial load of the form. - // For normal forms it is enough + // We determine whether this is the initial rendering of the form. if ($this->isMethodType('GET') && !$this->isSubmitted()) { throw new \LogicException('Initial form rendering is not allowed to cache the form.'); } diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php index 4ae3a57..239916b 100644 --- a/core/lib/Drupal/Core/Render/Element/RenderElement.php +++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Render\Element; +use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\PluginBase; @@ -231,8 +232,7 @@ public static function preRenderAjaxForm($element) { $element['#attached']['library'][] = 'core/drupal.ajax'; $settings = $element['#ajax']; - // Do not support custom URLs, only allow this method to use it for - // internal reasons. + // Do not support custom URLs, $settings['url'] is generated below. if (isset($settings['url'])) { throw new \InvalidArgumentException('Custom AJAX URLs are not allowed'); } @@ -249,8 +249,8 @@ public static function preRenderAjaxForm($element) { $query = \Drupal::request()->query->all(); $query[FormBuilderInterface::AJAX_FORM_REQUEST] = TRUE; - $settings += ['options' => []]; - $settings['options'] += ['query' => []]; + // Add options['query'] => [] as default value. + $settings = NestedArray::mergeDeep($settings, ['options' => ['query' => []]]); $options['query'] = $settings['options']['query'] + $query; $settings['url'] = Url::fromRoute('', [], $options)->toString(); diff --git a/core/tests/Drupal/Tests/Core/Form/FormStateTest.php b/core/tests/Drupal/Tests/Core/Form/FormStateTest.php index 3eca4cc..fe73b5f 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormStateTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormStateTest.php @@ -482,6 +482,7 @@ public function testSetCachedPost() { * @covers ::setCached * * @expectedException \LogicException + * @expectedExceptionMessage Initial form rendering is not allowed to cache the form. */ public function testSetCachedGet() { $form_state = new FormState(); @@ -498,7 +499,7 @@ public function testSetCachedGetWithSubmission() { $form_state->setSubmitted(); $form_state->setCached(); - // Get form submissions should not be cached. + // GET form submissions should not be cached. $this->assertFalse($form_state->isCached()); }