form_builder
- Versions
- 4.7 – 5
form_builder($form_id, $form)- 6
form_builder($form_id,$form, &$form_state)- 7
form_builder($form_id, $element, &$form_state)
Walk through the structured form array, adding any required properties to each element and mapping the incoming input data to the proper elements. Also, execute any #process handlers attached to a specific element.
Parameters
$form_id A unique string identifying the form for validation, submission, theming, and hook_form_alter functions.
$element An associative array containing the structure of the current element.
$form_state A keyed array containing the current state of the form. In this context, it is used to accumulate information about which button was clicked when the form was submitted, as well as the sanitized $_POST data.
Related topics
Code
includes/form.inc, line 1012
<?php
function form_builder($form_id, $element, &$form_state) {
// Initialize as unprocessed.
$element['#processed'] = FALSE;
// Use element defaults.
if ((!empty($element['#type'])) && ($info = element_info($element['#type']))) {
// Overlay $info onto $element, retaining preexisting keys in $element.
$element += $info;
$element['#defaults_loaded'] = TRUE;
}
// Special handling if we're on the top level form element.
if (isset($element['#type']) && $element['#type'] == 'form') {
if (!empty($element['#https']) && variable_get('https', FALSE) &&
!url_is_external($element['#action'])) {
global $base_root;
// Not an external URL so ensure that it is secure.
$element['#action'] = str_replace('http://', 'https://', $base_root) . $element['#action'];
}
// Store a complete copy of the form in form_state prior to building the form.
$form_state['complete form'] = $element;
// Set a flag if we have a correct form submission. This is always TRUE for
// programmed forms coming from drupal_form_submit(), or if the form_id coming
// from the POST data is set and matches the current form_id.
if ($form_state['programmed'] || (!empty($form_state['input']) && (isset($form_state['input']['form_id']) && ($form_state['input']['form_id'] == $form_id)))) {
$form_state['process_input'] = TRUE;
}
else {
$form_state['process_input'] = FALSE;
}
}
if (!isset($element['#id'])) {
$element['#id'] = drupal_html_id('edit-' . implode('-', $element['#parents']));
}
// Handle input elements.
if (!empty($element['#input'])) {
_form_builder_handle_input_element($form_id, $element, $form_state);
}
// Allow for elements to expand to multiple elements, e.g., radios,
// checkboxes and files.
if (isset($element['#process']) && !$element['#processed']) {
foreach ($element['#process'] as $process) {
if (function_exists($process)) {
$element = $process($element, $form_state, $form_state['complete form']);
}
}
$element['#processed'] = TRUE;
}
// We start off assuming all form elements are in the correct order.
$element['#sorted'] = TRUE;
// Recurse through all child elements.
$count = 0;
foreach (element_children($element) as $key) {
// Don't squash an existing tree value.
if (!isset($element[$key]['#tree'])) {
$element[$key]['#tree'] = $element['#tree'];
}
// Deny access to child elements if parent is denied.
if (isset($element['#access']) && !$element['#access']) {
$element[$key]['#access'] = FALSE;
}
// Don't squash existing parents value.
if (!isset($element[$key]['#parents'])) {
// Check to see if a tree of child elements is present. If so,
// continue down the tree if required.
$element[$key]['#parents'] = $element[$key]['#tree'] && $element['#tree'] ? array_merge($element['#parents'], array($key)) : array($key);
$array_parents = isset($element['#array_parents']) ? $element['#array_parents'] : array();
$array_parents[] = $key;
$element[$key]['#array_parents'] = $array_parents;
}
// Assign a decimal placeholder weight to preserve original array order.
if (!isset($element[$key]['#weight'])) {
$element[$key]['#weight'] = $count/1000;
}
else {
// If one of the child elements has a weight then we will need to sort
// later.
unset($element['#sorted']);
}
$element[$key] = form_builder($form_id, $element[$key], $form_state);
$count++;
}
// The #after_build flag allows any piece of a form to be altered
// after normal input parsing has been completed.
if (isset($element['#after_build']) && !isset($element['#after_build_done'])) {
foreach ($element['#after_build'] as $function) {
$element = $function($element, $form_state);
$element['#after_build_done'] = TRUE;
}
}
// Now that we've processed everything, we can go back to handle the funky
// Internet Explorer button-click scenario.
_form_builder_ie_cleanup($element, $form_state);
// If some callback set #cache, we need to flip a flag so later it
// can be found.
if (!empty($element['#cache'])) {
$form_state['cache'] = $element['#cache'];
}
// If there is a file element, we need to flip a flag so later the
// form encoding can be set.
if (isset($element['#type']) && $element['#type'] == 'file') {
$form_state['has_file_element'] = TRUE;
}
if (isset($element['#type']) && $element['#type'] == 'form') {
// We are on the top form.
// If there is a file element, we set the form encoding.
if (isset($form_state['has_file_element'])) {
$element['#attributes']['enctype'] = 'multipart/form-data';
}
// Update the copy of the complete form for usage in validation handlers.
$form_state['complete form'] = $element;
}
return $element;
}
?>Login or register to post comments 