diff --git a/includes/form.inc b/includes/form.inc index 15c18cbda73709f1cc7aaa33cf031ce5ba09bbcb..02f82725e1a52a84a9d711b082da8b7b049156cc 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -1446,8 +1446,10 @@ function form_set_error($name = NULL, $message = '', $limit_validation_errors = // reconstructed #parents begin with the same keys as the specified // section, then the element's values are within the part of // $form_state['values'] that the clicked button requires to be valid, - // so errors for this element must be recorded. - if (array_slice(explode('][', $name), 0, count($section)) === $section) { + // so errors for this element must be recorded. As the exploded array + // will all be strings, we need to cast every value of the section + // array to string. + if (explode('][', $name, count($section)) === array_map('strval', $section)) { $record = TRUE; break; } diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test index a0df090524e95e3840faa13b59e60fe338cdac07..4370f18433daeb1173b9f0428f0279d9eb128a23 100644 --- a/modules/simpletest/tests/form.test +++ b/modules/simpletest/tests/form.test @@ -521,16 +521,33 @@ class FormValidationTestCase extends DrupalWebTestCase { * Tests partial form validation through #limit_validation_errors. */ function testValidateLimitErrors() { - $edit = array('test' => 'invalid'); + $edit = array( + 'test' => 'invalid', + 'test_numeric_index[0]' => 'invalid', + 'test_substring[foo]' => 'invalid', + ); $path = 'form-test/limit-validation-errors'; - // Submit the form by pressing the button with #limit_validation_errors and - // ensure that the title field is not validated, but the #element_validate - // handler for the 'test' field is triggered. + // Submit the form by pressing the 'Partial validate' button (uses + // #limit_validation_errors) and ensure that the title field is not + // validated, but the #element_validate handler for the 'test' field + // is triggered. $this->drupalPost($path, $edit, t('Partial validate')); $this->assertNoText(t('!name field is required.', array('!name' => 'Title'))); $this->assertText('Test element is invalid'); + // Edge case of #limit_validation_errors containing numeric indexes: same + // thing with the 'Partial validate (numeric index)' button and the + // 'test_numeric_index' field. + $this->drupalPost($path, $edit, t('Partial validate (numeric index)')); + $this->assertNoText(t('!name field is required.', array('!name' => 'Title'))); + $this->assertText('Test (numeric index) element is invalid'); + + // Ensure something like 'foobar' isn't considered "inside" 'foo'. + $this->drupalPost($path, $edit, t('Partial validate (substring)')); + $this->assertNoText(t('!name field is required.', array('!name' => 'Title'))); + $this->assertText('Test (substring) foo element is invalid'); + // Ensure not validated values are not available to submit handlers. $this->drupalPost($path, array('title' => '', 'test' => 'valid'), t('Partial validate')); $this->assertText('Only validated values appear in the form values.'); diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module index abaae06c1c5d3ef9836d8664aaac8dc5807d2b7c..52cca5e1824d514fdd098951d3d65cb1e68d2f06 100644 --- a/modules/simpletest/tests/form_test.module +++ b/modules/simpletest/tests/form_test.module @@ -333,16 +333,53 @@ function form_test_limit_validation_errors_form($form, &$form_state) { '#title' => 'Title', '#required' => TRUE, ); + $form['test'] = array( + '#title' => 'Test', + '#type' => 'textfield', + '#element_validate' => array('form_test_limit_validation_errors_element_validate_test'), + ); + $form['test_numeric_index'] = array( + '#tree' => TRUE, + ); + $form['test_numeric_index'][0] = array( + '#title' => 'Test (numeric index)', + '#type' => 'textfield', + '#element_validate' => array('form_test_limit_validation_errors_element_validate_test'), + ); + + $form['test_substring'] = array( + '#tree' => TRUE, + ); + $form['test_substring']['foo'] = array( + '#title' => 'Test (substring) foo', '#type' => 'textfield', '#element_validate' => array('form_test_limit_validation_errors_element_validate_test'), ); + $form['test_substring']['foobar'] = array( + '#title' => 'Test (substring) foobar', + '#type' => 'textfield', + '#element_validate' => array('form_test_limit_validation_errors_element_validate_test'), + ); + $form['actions']['partial'] = array( '#type' => 'submit', '#limit_validation_errors' => array(array('test')), '#submit' => array('form_test_limit_validation_errors_form_partial_submit'), '#value' => t('Partial validate'), ); + $form['actions']['partial_numeric_index'] = array( + '#type' => 'submit', + '#limit_validation_errors' => array(array('test_numeric_index', 0)), + '#submit' => array('form_test_limit_validation_errors_form_partial_submit'), + '#value' => t('Partial validate (numeric index)'), + ); + $form['actions']['substring'] = array( + '#type' => 'submit', + '#limit_validation_errors' => array(array('test_substring', 'foo')), + '#submit' => array('form_test_limit_validation_errors_form_partial_submit'), + '#value' => t('Partial validate (substring)'), + ); $form['actions']['full'] = array( '#type' => 'submit', '#value' => t('Full validate'), @@ -355,7 +392,7 @@ function form_test_limit_validation_errors_form($form, &$form_state) { */ function form_test_limit_validation_errors_element_validate_test(&$element, &$form_state) { if ($element['#value'] == 'invalid') { - form_error($element, 'Test element is invalid'); + form_error($element, t('@label element is invalid', array('@label' => $element['#title']))); } }