diff --git a/core/includes/form.inc b/core/includes/form.inc index 513615c..d6b6141 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -1781,18 +1781,17 @@ function form_builder($form_id, &$element, &$form_state) { // Initialize as unprocessed. $element['#processed'] = FALSE; - // Use element defaults. - if (isset($element['#type']) && empty($element['#defaults_loaded']) && ($info = element_info($element['#type']))) { - // Overlay $info onto $element, retaining preexisting keys in $element. - $element += $info; - $element['#defaults_loaded'] = TRUE; + form_element_info_merge($element); + + // Validate required properties. + foreach ($element['#property_validate'] as $property => $callback) { + if (call_user_func($calback, $element[$property])) { + throw new \UnexpectedValueException(t('Form element @element has a non-valid@property $property, + '@element' => $form_id . '[' . implode('][', $element['#array_parents']) . ']', + ))); + } } - // Assign basic defaults common for all form elements. - $element += array( - '#required' => FALSE, - '#attributes' => array(), - '#title_display' => 'before', - ); // Special handling if we're on the top level form element. if (isset($element['#type']) && $element['#type'] == 'form') { @@ -1851,12 +1850,7 @@ function form_builder($form_id, &$element, &$form_state) { // Recurse through all child elements. $count = 0; foreach (element_children($element) as $key) { - // Prior to checking properties of child elements, their default properties - // need to be loaded. - if (isset($element[$key]['#type']) && empty($element[$key]['#defaults_loaded']) && ($info = element_info($element[$key]['#type']))) { - $element[$key] += $info; - $element[$key]['#defaults_loaded'] = TRUE; - } + form_element_info_merge($element[$key]); // Don't squash an existing tree value. if (!isset($element[$key]['#tree'])) { @@ -4843,6 +4837,46 @@ function _form_set_attributes(&$element, $class = array()) { } /** + * Retrieves the default properties for the defined element type. + * + * @param $type + * An element type as defined by hook_element_info(). + */ +function form_element_info($type) { + $info = element_info($type); + // Merge in form-element-specific defaults. + $info += array( + '#required' => FALSE, + '#attributes' => array(), + '#title_display' => 'before', + ); + $info['#property_validate'] += array( + '#title' => 'strlen', + ); + + return $info; +} + +/** + * Expands a form element with its default values. + * + * @param array &$element + * + * @return NULL + */ +function form_element_info_merge(array &$element) { + if (isset($element['#type']) && empty($element['#defaults_loaded']) { + $info = form_element_info($element['#type']); + if ($info) { + // Overlay $info onto $element, retaining preexisting keys in $element. + $element += $info; + $element['#defaults_loaded'] = TRUE; + } + } +} + + +/** * @} End of "defgroup form_api". */