Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.992 diff -u -p -r1.992 common.inc --- includes/common.inc 18 Sep 2009 10:54:20 -0000 1.992 +++ includes/common.inc 20 Sep 2009 19:17:01 -0000 @@ -4704,6 +4704,9 @@ function drupal_common_theme() { 'form_element' => array( 'arguments' => array('element' => NULL), ), + 'form_required_marker' => array( + 'arguments' => array(), + ), 'text_format_wrapper' => array( 'arguments' => array('element' => NULL), ), Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.374 diff -u -p -r1.374 form.inc --- includes/form.inc 20 Sep 2009 07:32:17 -0000 1.374 +++ includes/form.inc 20 Sep 2009 19:17:03 -0000 @@ -2606,7 +2606,7 @@ function theme_form_element($element) { } $output = '
' . "\n"; - $required = !empty($element['#required']) ? '*' : ''; + $required = !empty($element['#required']) ? theme('form_required_marker') : ''; if (!empty($element['#title']) && empty($element['#form_element_skip_title'])) { $title = $element['#title']; @@ -2630,6 +2630,20 @@ function theme_form_element($element) { } /** + * Theme the marker for requried form elements. + * + * @return + * A string representing the marker to identify required form elements. + * + * @ingroup themeable + */ +function theme_form_required_marker() { + // This is also used in the installer, pre-database setup. + $t = get_t(); + return '*'; +} + +/** * Sets a form element's class attribute. * * Adds 'required' and 'error' classes as needed. Index: modules/simpletest/tests/form.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form.test,v retrieving revision 1.15 diff -u -p -r1.15 form.test --- modules/simpletest/tests/form.test 18 Sep 2009 00:12:48 -0000 1.15 +++ modules/simpletest/tests/form.test 20 Sep 2009 19:17:03 -0000 @@ -27,46 +27,61 @@ class FormsTestCase extends DrupalWebTes $empty_strings = array('""' => "", '"\n"' => "\n", '" "' => " ", '"\t"' => "\t", '" \n\t "' => " \n\t ", '"\n\n\n\n\n"' => "\n\n\n\n\n"); $empty_arrays = array('array()' => array()); - $elements['textfield']['element'] = array('#title' => $this->randomName(), '#type' => 'textfield', '#required' => TRUE); + $elements['textfield']['element'] = array('#title' => $this->randomName(), '#type' => 'textfield'); $elements['textfield']['empty_values'] = $empty_strings; - $elements['password']['element'] = array('#title' => $this->randomName(), '#type' => 'password', '#required' => TRUE); + $elements['password']['element'] = array('#title' => $this->randomName(), '#type' => 'password'); $elements['password']['empty_values'] = $empty_strings; - $elements['password_confirm']['element'] = array('#title' => $this->randomName(), '#type' => 'password_confirm', '#required' => TRUE); + $elements['password_confirm']['element'] = array('#title' => $this->randomName(), '#type' => 'password_confirm'); $elements['password_confirm']['empty_values'] = $empty_strings; - $elements['textarea']['element'] = array('#title' => $this->randomName(), '#type' => 'textarea', '#required' => TRUE); + $elements['textarea']['element'] = array('#title' => $this->randomName(), '#type' => 'textarea'); $elements['textarea']['empty_values'] = $empty_strings; - $elements['radios']['element'] = array('#title' => $this->randomName(), '#type' => 'radios', '#required' => TRUE, '#options' => array($this->randomName(), $this->randomName(), $this->randomName())); + $elements['radios']['element'] = array('#title' => $this->randomName(), '#type' => 'radios', '#options' => array($this->randomName(), $this->randomName(), $this->randomName())); $elements['radios']['empty_values'] = $empty_arrays; - $elements['checkboxes']['element'] = array('#title' => $this->randomName(), '#type' => 'checkboxes', '#required' => TRUE, '#options' => array($this->randomName(), $this->randomName(), $this->randomName())); + $elements['checkboxes']['element'] = array('#title' => $this->randomName(), '#type' => 'checkboxes', '#options' => array($this->randomName(), $this->randomName(), $this->randomName())); $elements['checkboxes']['empty_values'] = $empty_arrays; - $elements['select']['element'] = array('#title' => $this->randomName(), '#type' => 'select', '#required' => TRUE, '#options' => array($this->randomName(), $this->randomName(), $this->randomName())); + $elements['select']['element'] = array('#title' => $this->randomName(), '#type' => 'select', '#options' => array($this->randomName(), $this->randomName(), $this->randomName())); $elements['select']['empty_values'] = $empty_strings; - $elements['file']['element'] = array('#title' => $this->randomName(), '#type' => 'file', '#required' => TRUE); + $elements['file']['element'] = array('#title' => $this->randomName(), '#type' => 'file'); $elements['file']['empty_values'] = $empty_strings; + // Regular expression to find the expected marker on required elements. + $required_marker_preg = '@\*@'; // Go through all the elements and all the empty values for them foreach ($elements as $type => $data) { foreach ($data['empty_values'] as $key => $empty) { - $form_id = $this->randomName(); - $form = $form_state = array(); - $form['op'] = array('#type' => 'submit', '#value' => t('Submit')); - $element = $data['element']['#title']; - $form[$element] = $data['element']; - $form_state['values'][$element] = $empty; - $form_state['input'] = $form_state['values']; - $form_state['input']['form_id'] = $form_id; - $form_state['method'] = 'post'; - drupal_prepare_form($form_id, $form, $form_state); - drupal_process_form($form_id, $form, $form_state); - $errors = form_get_errors(); - $this->assertTrue(isset($errors[$element]), "Check empty($key) '$type' field '$element'"); + foreach (array(TRUE, FALSE) as $required) { + $form_id = $this->randomName(); + $form = $form_state = array(); + $form['op'] = array('#type' => 'submit', '#value' => t('Submit')); + $element = $data['element']['#title']; + $form[$element] = $data['element']; + $form[$element]['#required'] = $required; + $form_state['values'][$element] = $empty; + $form_state['input'] = $form_state['values']; + $form_state['input']['form_id'] = $form_id; + $form_state['method'] = 'post'; + drupal_prepare_form($form_id, $form, $form_state); + drupal_process_form($form_id, $form, $form_state); + $form_output = drupal_render($form[$element]); + if ($required) { + $errors = form_get_errors(); + // Make sure we have a form error for this element. + $this->assertTrue(isset($errors[$element]), "Check empty($key) '$type' field '$element'"); + // Make sure the form element is marked as required. + $this->assertTrue(preg_match($required_marker_preg, $form_output), "Required '$type' field is marked as required"); + } + else { + // Make sure the form element is *not* marked as required. + $this->assertFalse(preg_match($required_marker_preg, $form_output), "Optional '$type' field is not marked as required"); + } + } } } // Clear the expected form error messages so they don't appear as exceptions.