Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
709c4ab9
Commit
709c4ab9
authored
Apr 23, 2014
by
webchick
Browse files
Issue
#2241735
by tim.plunkett: Throw an exception when form errors are set outside of validation.
parent
66800acd
Changes
3
Hide whitespace changes
Inline
Side-by-side
core/lib/Drupal/Core/Form/FormBuilder.php
View file @
709c4ab9
...
...
@@ -105,13 +105,6 @@ class FormBuilder implements FormBuilderInterface {
*/
protected
$forms
;
/**
* An array of validated forms.
*
* @var array
*/
protected
$validatedForms
=
array
();
/**
* An array of options used for recursive flattening.
*
...
...
@@ -301,6 +294,7 @@ public function getFormStateDefaults() {
'files'
=>
array
(),
),
'temporary'
=>
array
(),
'validation_complete'
=>
FALSE
,
'submitted'
=>
FALSE
,
'executed'
=>
FALSE
,
'programmed'
=>
FALSE
,
...
...
@@ -431,6 +425,7 @@ protected function getUncacheableKeys() {
'input'
,
'method'
,
'submit_handlers'
,
'validation_complete'
,
'submitted'
,
'executed'
,
'validate_handlers'
,
...
...
@@ -806,7 +801,14 @@ public function prepareForm($form_id, &$form, &$form_state) {
* {@inheritdoc}
*/
public
function
validateForm
(
$form_id
,
&
$form
,
&
$form_state
)
{
if
(
isset
(
$this
->
validatedForms
[
$form_id
])
&&
empty
(
$form_state
[
'must_validate'
]))
{
// If this form is flagged to always validate, ensure that previous runs of
// validation are ignored.
if
(
!
empty
(
$form_state
[
'must_validate'
]))
{
$form_state
[
'validation_complete'
]
=
FALSE
;
}
// If this form has completed validation, do not validate again.
if
(
!
empty
(
$form_state
[
'validation_complete'
]))
{
return
;
}
...
...
@@ -888,7 +890,7 @@ protected function finalizeValidation($form_id, &$form, &$form_state) {
// After validation, loop through and assign each element its errors.
$this
->
setElementErrorsFromFormState
(
$form
,
$form_state
);
// Mark this form as validated.
$
this
->
validatedForms
[
$form_id
]
=
TRUE
;
$
form_state
[
'validation_complete'
]
=
TRUE
;
}
/**
...
...
@@ -1198,6 +1200,10 @@ public function executeHandlers($type, &$form, &$form_state) {
* {@inheritdoc}
*/
public
function
setErrorByName
(
$name
,
array
&
$form_state
,
$message
=
''
)
{
if
(
!
empty
(
$form_state
[
'validation_complete'
]))
{
throw
new
\
LogicException
(
'Form errors cannot be set after form validation has finished.'
);
}
if
(
!
isset
(
$form_state
[
'errors'
][
$name
]))
{
$record
=
TRUE
;
if
(
isset
(
$form_state
[
'limit_validation_errors'
]))
{
...
...
core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
View file @
709c4ab9
...
...
@@ -17,6 +17,8 @@
/**
* Tests the form builder.
*
* @coversDefaultClass \Drupal\Core\Form\FormBuilder
*
* @group Drupal
* @group Form
*/
...
...
@@ -218,6 +220,34 @@ public function testHandleRedirectWithResponse() {
$this
->
assertSame
(
$response
,
$form_state
[
'response'
]);
}
/**
* Tests that form errors during submission throw an exception.
*
* @covers ::setErrorByName
*
* @expectedException \LogicException
* @expectedExceptionMessage Form errors cannot be set after form validation has finished.
*/
public
function
testFormErrorsDuringSubmission
()
{
$form_id
=
'test_form_id'
;
$expected_form
=
$form_id
();
$form_arg
=
$this
->
getMockForm
(
$form_id
,
$expected_form
);
$form_builder
=
$this
->
formBuilder
;
$form_arg
->
expects
(
$this
->
any
())
->
method
(
'submitForm'
)
->
will
(
$this
->
returnCallback
(
function
(
$form
,
&
$form_state
)
use
(
$form_builder
)
{
$form_builder
->
setErrorByName
(
'test'
,
$form_state
,
'Hello'
);
}));
$form_state
=
array
();
$this
->
formBuilder
->
getFormId
(
$form_arg
,
$form_state
);
$form_state
[
'values'
]
=
array
();
$form_state
[
'input'
][
'form_id'
]
=
$form_id
;
$this
->
simulateFormSubmission
(
$form_id
,
$form_arg
,
$form_state
,
FALSE
);
}
/**
* Tests the redirectForm() method when a redirect is expected.
*
...
...
@@ -527,6 +557,47 @@ public function testSubmitForm() {
$this
->
assertNotEmpty
(
$errors
[
'options'
]);
}
/**
* Tests the 'must_validate' $form_state flag.
*
* @covers ::validateForm
*/
public
function
testMustValidate
()
{
$form_id
=
'test_form_id'
;
$expected_form
=
$form_id
();
$form_arg
=
$this
->
getMock
(
'Drupal\Core\Form\FormInterface'
);
$form_arg
->
expects
(
$this
->
any
())
->
method
(
'getFormId'
)
->
will
(
$this
->
returnValue
(
$form_id
));
$form_arg
->
expects
(
$this
->
any
())
->
method
(
'buildForm'
)
->
will
(
$this
->
returnValue
(
$expected_form
));
$form_builder
=
$this
->
formBuilder
;
$form_arg
->
expects
(
$this
->
exactly
(
2
))
->
method
(
'validateForm'
)
->
will
(
$this
->
returnCallback
(
function
(
&
$form
,
&
$form_state
)
use
(
$form_builder
)
{
$form_builder
->
setErrorByName
(
'test'
,
$form_state
,
'foo'
);
}));
$form_state
=
array
();
// This submission will trigger validation.
$this
->
simulateFormSubmission
(
$form_id
,
$form_arg
,
$form_state
);
$errors
=
$this
->
formBuilder
->
getErrors
(
$form_state
);
$this
->
assertNotEmpty
(
$errors
[
'test'
]);
// This submission will not re-trigger validation.
$this
->
simulateFormSubmission
(
$form_id
,
$form_arg
,
$form_state
);
$errors
=
$this
->
formBuilder
->
getErrors
(
$form_state
);
$this
->
assertNotEmpty
(
$errors
[
'test'
]);
// The must_validate flag will re-trigger validation.
$form_state
[
'must_validate'
]
=
TRUE
;
$this
->
simulateFormSubmission
(
$form_id
,
$form_arg
,
$form_state
);
$errors
=
$this
->
formBuilder
->
getErrors
(
$form_state
);
$this
->
assertNotEmpty
(
$errors
[
'test'
]);
}
/**
* Tests the flattenOptions() method.
*
...
...
core/tests/Drupal/Tests/Core/Form/FormValidationTest.php
View file @
709c4ab9
...
...
@@ -26,37 +26,6 @@ public static function getInfo() {
);
}
public
function
testNoDuplicateErrorsForIdenticalForm
()
{
$form_id
=
'test_form_id'
;
$expected_form
=
$form_id
();
$expected_form
[
'test'
][
'#required'
]
=
TRUE
;
// Mock a form object that will be built three times.
$form_arg
=
$this
->
getMockForm
(
$form_id
,
$expected_form
,
3
);
// The first form will have errors.
$form_state
=
array
();
$this
->
formBuilder
->
getFormId
(
$form_arg
,
$form_state
);
$this
->
simulateFormSubmission
(
$form_id
,
$form_arg
,
$form_state
);
$errors
=
$this
->
formBuilder
->
getErrors
(
$form_state
);
$this
->
assertNotEmpty
(
$errors
[
'test'
]);
// The second form will not have errors.
$form_state
=
array
();
$this
->
simulateFormSubmission
(
$form_id
,
$form_arg
,
$form_state
);
$errors
=
$this
->
formBuilder
->
getErrors
(
$form_state
);
$this
->
assertEmpty
(
$errors
);
// Reset the form builder.
$this
->
setupFormBuilder
();
// On a new request, the first form will have errors again.
$form_state
=
array
();
$this
->
simulateFormSubmission
(
$form_id
,
$form_arg
,
$form_state
);
$errors
=
$this
->
formBuilder
->
getErrors
(
$form_state
);
$this
->
assertNotEmpty
(
$errors
[
'test'
]);
}
public
function
testUniqueHtmlId
()
{
$form_id
=
'test_form_id'
;
$expected_form
=
$form_id
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment