diff --git a/core/core.services.yml b/core/core.services.yml index 9b0e053..d050591 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -125,9 +125,7 @@ services: arguments: ['@form_validator', '@module_handler', '@keyvalue.expirable', '@event_dispatcher', '@url_generator', '@request_stack', '@?csrf_token', '@?http_kernel'] form_validator: class: Drupal\Core\Form\FormValidator - arguments: ['@url_generator', '@?csrf_token'] - calls: - - [setRequest, ['@?request=']] + arguments: ['@request_stack', '@?csrf_token'] keyvalue: class: Drupal\Core\KeyValueStore\KeyValueFactory arguments: ['@service_container', '@settings'] diff --git a/core/includes/form.inc b/core/includes/form.inc index 0dc41e9..984daf7 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -11,7 +11,7 @@ use Drupal\Component\Utility\UrlHelper; use Drupal\Component\Utility\Xss; use Drupal\Core\Database\Database; -use Drupal\Core\Form\FormHelper; +use Drupal\Core\Form\OptGroup; use Drupal\Core\Language\Language; use Drupal\Core\Render\Element; use Drupal\Core\Template\Attribute; @@ -346,10 +346,11 @@ function drupal_redirect_form($form_state) { * Executes custom validation and submission handlers for a given form. * * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. - * Use \Drupal::formBuilder()->executeSubmitHandlers(). + * Use either \Drupal::formBuilder()->executeSubmitHandlers() or + * \Drupal::service('form_validator')->executeValidateHandlers(). * * @see \Drupal\Core\Form\FormBuilderInterface::executeSubmitHandlers() - * @see \Drupal\Core\Form\FormBuilderInterface::executeValidateHandlers() + * @see \Drupal\Core\Form\FormValidatorInterface::executeValidateHandlers() */ function form_execute_handlers($type, &$form, &$form_state) { if ($type == 'submit') { @@ -851,12 +852,10 @@ function form_set_value($element, $value, &$form_state) { * An array with all hierarchical elements flattened to a single array. * * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. - * Use \Drupal\Core\Form\FormHelper::flattenOptions(). - * - * @see \Drupal\Core\Form\FormBuilderInterface::flattenOptions(). + * Use \Drupal\Core\Form\OptGroup::flattenOptions(). */ function form_options_flatten($array) { - return FormHelper::flattenOptions($array); + return OptGroup::flattenOptions($array); } /** diff --git a/core/lib/Drupal/Core/Form/FormBuilderInterface.php b/core/lib/Drupal/Core/Form/FormBuilderInterface.php index f13f707..1e43984 100644 --- a/core/lib/Drupal/Core/Form/FormBuilderInterface.php +++ b/core/lib/Drupal/Core/Form/FormBuilderInterface.php @@ -7,8 +7,6 @@ namespace Drupal\Core\Form; -use Symfony\Component\HttpFoundation\Request; - /** * Provides an interface for form building and processing. */ diff --git a/core/lib/Drupal/Core/Form/FormValidator.php b/core/lib/Drupal/Core/Form/FormValidator.php index e10e4fe..2cb1141 100644 --- a/core/lib/Drupal/Core/Form/FormValidator.php +++ b/core/lib/Drupal/Core/Form/FormValidator.php @@ -9,12 +9,11 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\Unicode; -use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Access\CsrfTokenGenerator; use Drupal\Core\Render\Element; -use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; -use Symfony\Component\HttpFoundation\Request; +use Drupal\Core\Form\OptGroup; +use Symfony\Component\HttpFoundation\RequestStack; /** * Provides validation of form submissions. @@ -24,13 +23,6 @@ class FormValidator implements FormValidatorInterface { use StringTranslationTrait; /** - * The URL generator. - * - * @var \Drupal\Core\Routing\UrlGeneratorInterface - */ - protected $urlGenerator; - - /** * The CSRF token generator to validate the form token. * * @var \Drupal\Core\Access\CsrfTokenGenerator @@ -38,22 +30,22 @@ class FormValidator implements FormValidatorInterface { protected $csrfToken; /** - * The current request. + * The request stack. * - * @var \Symfony\Component\HttpFoundation\Request + * @var \Symfony\Component\HttpFoundation\RequestStack */ - protected $request; + protected $requestStack; /** * Constructs a new FormValidator. * - * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator - * The URL generator. + * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack + * The request stack. * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token * The CSRF token generator. */ - public function __construct(UrlGeneratorInterface $url_generator, CsrfTokenGenerator $csrf_token = NULL) { - $this->urlGenerator = $url_generator; + public function __construct(RequestStack $request_stack, CsrfTokenGenerator $csrf_token = NULL) { + $this->requestStack = $request_stack; $this->csrfToken = $csrf_token; } @@ -97,9 +89,7 @@ public function validateForm($form_id, &$form, &$form_state) { // matches the current user's session. if (isset($form['#token'])) { if (!$this->csrfToken->validate($form_state['values']['form_token'], $form['#token'])) { - $path = $this->request->attributes->get('_system_path'); - $query = UrlHelper::filterQueryParameters($this->request->query->all()); - $url = $this->urlGenerator->generateFromPath($path, array('query' => $query)); + $url = $this->requestStack->getCurrentRequest()->getRequestUri(); // Setting this error will cause the form to fail validation. $this->setErrorByName('form_token', $form_state, $this->t('The form has become outdated. Copy any unsaved work in the form below and then reload this page.', array('@link' => $url))); @@ -315,7 +305,7 @@ protected function performRequiredValidation(&$elements, &$form_state) { if (isset($elements['#options']) && isset($elements['#value'])) { if ($elements['#type'] == 'select') { - $options = FormHelper::flattenOptions($elements['#options']); + $options = OptGroup::flattenOptions($elements['#options']); } else { $options = $elements['#options']; @@ -451,7 +441,7 @@ public function setErrorByName($name, array &$form_state, $message = '') { } if ($record) { $form_state['errors'][$name] = $message; - $this->request->attributes->set('_form_errors', TRUE); + $this->requestStack->getCurrentRequest()->attributes->set('_form_errors', TRUE); if ($message) { $this->drupalSetMessage($message, 'error'); } @@ -489,7 +479,7 @@ public function getError($element, array &$form_state) { */ public function clearErrors(array &$form_state) { $form_state['errors'] = array(); - $this->request->attributes->set('_form_errors', FALSE); + $this->requestStack->getCurrentRequest()->attributes->set('_form_errors', FALSE); } /** @@ -503,14 +493,7 @@ public function getErrors(array $form_state) { * {@inheritdoc} */ public function getAnyErrors() { - return (bool) $this->request->attributes->get('_form_errors'); - } - - /** - * {@inheritdoc} - */ - public function setRequest(Request $request) { - $this->request = $request; + return (bool) $this->requestStack->getCurrentRequest()->attributes->get('_form_errors'); } /** diff --git a/core/lib/Drupal/Core/Form/FormValidatorInterface.php b/core/lib/Drupal/Core/Form/FormValidatorInterface.php index 4de9bfa..806e6a0 100644 --- a/core/lib/Drupal/Core/Form/FormValidatorInterface.php +++ b/core/lib/Drupal/Core/Form/FormValidatorInterface.php @@ -7,8 +7,6 @@ namespace Drupal\Core\Form; -use Symfony\Component\HttpFoundation\Request; - /** * Provides an interface for validating form submissions. */ @@ -56,12 +54,4 @@ public function executeValidateHandlers(&$form, &$form_state); */ public function validateForm($form_id, &$form, &$form_state); - /** - * Sets the request object to use. - * - * @param \Symfony\Component\HttpFoundation\Request $request - * The request object. - */ - public function setRequest(Request $request); - } diff --git a/core/lib/Drupal/Core/Form/FormHelper.php b/core/lib/Drupal/Core/Form/OptGroup.php similarity index 92% rename from core/lib/Drupal/Core/Form/FormHelper.php rename to core/lib/Drupal/Core/Form/OptGroup.php index 833160f..f94d62d 100644 --- a/core/lib/Drupal/Core/Form/FormHelper.php +++ b/core/lib/Drupal/Core/Form/OptGroup.php @@ -2,15 +2,15 @@ /** * @file - * Contains \Drupal\Core\Form\FormHelper. + * Contains \Drupal\Core\Form\OptGroup. */ namespace Drupal\Core\Form; /** - * Provides utility methods used by form processing. + * Provides helpers for HTML option groups. */ -class FormHelper { +class OptGroup { /** * Allows PHP array processing of multiple select options with the same value. diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php index f03f829..4757302 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php @@ -10,7 +10,7 @@ use Drupal\Component\Utility\String; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; -use Drupal\Core\Form\FormHelper; +use Drupal\Core\Form\OptGroup; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\AllowedValuesInterface; use Drupal\Core\TypedData\DataDefinition; @@ -70,7 +70,7 @@ public function getPossibleOptions(AccountInterface $account = NULL) { public function getSettableValues(AccountInterface $account = NULL) { // Flatten options first, because "settable options" may contain group // arrays. - $flatten_options = FormHelper::flattenOptions($this->getSettableOptions($account)); + $flatten_options = OptGroup::flattenOptions($this->getSettableOptions($account)); return array_keys($flatten_options); } diff --git a/core/modules/options/lib/Drupal/options/Plugin/Field/FieldType/ListItemBase.php b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldType/ListItemBase.php index 5fbf7d2..64604e5 100644 --- a/core/modules/options/lib/Drupal/options/Plugin/Field/FieldType/ListItemBase.php +++ b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldType/ListItemBase.php @@ -8,7 +8,7 @@ namespace Drupal\options\Plugin\Field\FieldType; use Drupal\Core\Field\FieldItemBase; -use Drupal\Core\Form\FormHelper; +use Drupal\Core\Form\OptGroup; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\AllowedValuesInterface; @@ -33,7 +33,7 @@ public static function defaultSettings() { public function getPossibleValues(AccountInterface $account = NULL) { // Flatten options firstly, because Possible Options may contain group // arrays. - $flatten_options = FormHelper::flattenOptions($this->getPossibleOptions($account)); + $flatten_options = OptGroup::flattenOptions($this->getPossibleOptions($account)); return array_keys($flatten_options); } @@ -50,7 +50,7 @@ public function getPossibleOptions(AccountInterface $account = NULL) { public function getSettableValues(AccountInterface $account = NULL) { // Flatten options firstly, because Settable Options may contain group // arrays. - $flatten_options = FormHelper::flattenOptions($this->getSettableOptions($account)); + $flatten_options = OptGroup::flattenOptions($this->getSettableOptions($account)); return array_keys($flatten_options); } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php index fc1fa46..cc8ef7e 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php @@ -9,7 +9,7 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; -use Drupal\Core\Form\FormHelper; +use Drupal\Core\Form\OptGroup; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\AllowedValuesInterface; @@ -49,7 +49,7 @@ public static function defaultSettings() { public function getPossibleValues(AccountInterface $account = NULL) { // Flatten options firstly, because Possible Options may contain group // arrays. - $flatten_options = FormHelper::flattenOptions($this->getPossibleOptions($account)); + $flatten_options = OptGroup::flattenOptions($this->getPossibleOptions($account)); return array_keys($flatten_options); } @@ -66,7 +66,7 @@ public function getPossibleOptions(AccountInterface $account = NULL) { public function getSettableValues(AccountInterface $account = NULL) { // Flatten options firstly, because Settable Options may contain group // arrays. - $flatten_options = FormHelper::flattenOptions($this->getSettableOptions($account)); + $flatten_options = OptGroup::flattenOptions($this->getSettableOptions($account)); return array_keys($flatten_options); } diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php index bd272e0..916ad1d 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php @@ -9,7 +9,7 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; -use Drupal\Core\Form\FormHelper; +use Drupal\Core\Form\OptGroup; use Drupal\Core\Form\FormInterface; use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -478,7 +478,7 @@ public function testRebuildForm() { * @dataProvider providerTestFlattenOptions */ public function testFlattenOptions($options) { - $this->assertSame(array('foo' => 1), FormHelper::flattenOptions($options)); + $this->assertSame(array('foo' => 1), OptGroup::flattenOptions($options)); } /** diff --git a/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php b/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php index 2a723bb..81bfeb8 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php @@ -10,6 +10,7 @@ use Drupal\Component\Utility\String; use Drupal\Tests\UnitTestCase; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; /** * Tests the form validator. @@ -113,11 +114,9 @@ public function testMustValidate() { * @covers ::validateForm */ public function testValidateInvalidFormToken() { - $url_generator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface'); - $url_generator->expects($this->once()) - ->method('generateFromPath') - ->with('test/example', array('query' => array('foo' => 'bar'))) - ->will($this->returnValue('/test/example?foo=bar')); + $request_stack = new RequestStack(); + $request = new Request(array(), array(), array(), array(), array(), array('REQUEST_URI' => '/test/example?foo=bar')); + $request_stack->push($request); $csrf_token = $this->getMockBuilder('Drupal\Core\Access\CsrfTokenGenerator') ->disableOriginalConstructor() ->getMock(); @@ -126,7 +125,7 @@ public function testValidateInvalidFormToken() { ->will($this->returnValue(FALSE)); $form_validator = $this->getMockBuilder('Drupal\Core\Form\FormValidator') - ->setConstructorArgs(array($url_generator, $csrf_token)) + ->setConstructorArgs(array($request_stack, $csrf_token)) ->setMethods(array('setErrorByName', 't', 'doValidateForm')) ->getMock(); $form_validator->expects($this->once()) @@ -139,8 +138,6 @@ public function testValidateInvalidFormToken() { ->with('form_token', $this->isType('array'), 'The form has become outdated. Copy any unsaved work in the form below and then reload this page.'); $form_validator->expects($this->never()) ->method('doValidateForm'); - $request = new Request(array('foo' => 'bar'), array(), array('_system_path' => 'test/example')); - $form_validator->setRequest($request); $form['#token'] = 'test_form_id'; $form_state = $this->getFormStateDefaults(); @@ -153,7 +150,7 @@ public function testValidateInvalidFormToken() { * @covers ::validateForm */ public function testValidateValidFormToken() { - $url_generator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface'); + $request_stack = new RequestStack(); $csrf_token = $this->getMockBuilder('Drupal\Core\Access\CsrfTokenGenerator') ->disableOriginalConstructor() ->getMock(); @@ -162,7 +159,7 @@ public function testValidateValidFormToken() { ->will($this->returnValue(TRUE)); $form_validator = $this->getMockBuilder('Drupal\Core\Form\FormValidator') - ->setConstructorArgs(array($url_generator, $csrf_token)) + ->setConstructorArgs(array($request_stack, $csrf_token)) ->setMethods(array('setErrorByName', 'doValidateForm')) ->getMock(); $form_validator->expects($this->never()) @@ -237,14 +234,15 @@ public function providerTestGetError() { * @dataProvider providerTestSetErrorByName */ public function testSetErrorByName($limit_validation_errors, $expected_errors, $set_message = FALSE) { + $request_stack = new RequestStack(); + $request = new Request(); + $request_stack->push($request); $form_validator = $this->getMockBuilder('Drupal\Core\Form\FormValidator') - ->disableOriginalConstructor() + ->setConstructorArgs(array($request_stack)) ->setMethods(array('drupalSetMessage')) ->getMock(); $form_validator->expects($set_message ? $this->once() : $this->never()) ->method('drupalSetMessage'); - $request = new Request(); - $form_validator->setRequest($request); $form_state = $this->getFormStateDefaults(); $form_state['limit_validation_errors'] = $limit_validation_errors; @@ -272,12 +270,13 @@ public function providerTestSetErrorByName() { * @covers ::setElementErrorsFromFormState */ public function testSetElementErrorsFromFormState() { + $request_stack = new RequestStack(); + $request = new Request(); + $request_stack->push($request); $form_validator = $this->getMockBuilder('Drupal\Core\Form\FormValidator') - ->disableOriginalConstructor() + ->setConstructorArgs(array($request_stack)) ->setMethods(array('drupalSetMessage')) ->getMock(); - $request = new Request(); - $form_validator->setRequest($request); $form = array( '#parents' => array(), @@ -439,8 +438,6 @@ public function testRequiredErrorMessage($element, $expected_message) { $form_validator->expects($this->once()) ->method('setErrorByName') ->with('test', $this->isType('array'), $expected_message); - $request = new Request(); - $form_validator->setRequest($request); $form = array(); $form['test'] = $element + array( @@ -493,8 +490,6 @@ public function testElementValidate() { $mock->expects($this->once()) ->method('element_validate') ->with($this->isType('array'), $this->isType('array'), NULL); - $request = new Request(); - $form_validator->setRequest($request); $form = array(); $form['test'] = array( @@ -517,8 +512,6 @@ public function testPerformRequiredValidation($element, $expected_message, $call ->disableOriginalConstructor() ->setMethods(array('t', 'setErrorByName', 'watchdog')) ->getMock(); - $request = new Request(); - $form_validator->setRequest($request); $form_validator->expects($this->any()) ->method('t') ->will($this->returnCallback(function ($string, $args) {