You are here

function form_builder in Drupal 5

Same name and namespace in other branches
  1. 4 includes/form.inc \form_builder()
  2. 6 includes/form.inc \form_builder()
  3. 7 includes/form.inc \form_builder()

Adds some required properties to each form element, which are used internally in the form API. This function also automatically assigns the value property from the $edit array, provided the element doesn't already have an assigned value.

Parameters

$form_id: A unique string identifying the form for validation, submission, theming, and hook_form_alter functions.

$form: An associative array containing the structure of the form.

Related topics

2 calls to form_builder()
drupal_prepare_form in includes/form.inc
Prepares a structured form array by adding required elements, executing any hook_form_alter functions, and optionally inserting a validation token to prevent tampering.
upload_js in modules/upload/upload.module
Menu-callback for JavaScript-based uploads.

File

includes/form.inc, line 648

Code

function form_builder($form_id, $form) {
  global $form_values, $form_submitted, $form_button_counter;

  // Initialize as unprocessed.
  $form['#processed'] = FALSE;

  /* Use element defaults */
  if (!empty($form['#type']) && ($info = _element_info($form['#type']))) {

    // Overlay $info onto $form, retaining preexisting keys in $form.
    $form += $info;
  }
  if (isset($form['#input']) && $form['#input']) {
    if (!isset($form['#name'])) {
      $name = array_shift($form['#parents']);
      $form['#name'] = $name;
      if ($form['#type'] == 'file') {

        // To make it easier to handle $_FILES in file.inc, we place all
        // file fields in the 'files' array. Also, we do not support
        // nested file names.
        $form['#name'] = 'files[' . $form['#name'] . ']';
      }
      elseif (count($form['#parents'])) {
        $form['#name'] .= '[' . implode('][', $form['#parents']) . ']';
      }
      array_unshift($form['#parents'], $name);
    }
    if (!isset($form['#id'])) {
      $form['#id'] = form_clean_id('edit-' . implode('-', $form['#parents']));
    }
    if (isset($form['#disabled']) && $form['#disabled']) {
      $form['#attributes']['disabled'] = 'disabled';
    }
    if (!isset($form['#value']) && !array_key_exists('#value', $form)) {
      if ($form['#programmed'] || (!isset($form['#access']) || $form['#access']) && isset($form['#post']) && (isset($form['#post']['form_id']) && $form['#post']['form_id'] == $form_id)) {
        $edit = $form['#post'];
        foreach ($form['#parents'] as $parent) {
          $edit = isset($edit[$parent]) ? $edit[$parent] : NULL;
        }
        if (!$form['#programmed'] || isset($edit)) {
          switch ($form['#type']) {
            case 'checkbox':
              $form['#value'] = !empty($edit) ? $form['#return_value'] : 0;
              break;
            case 'select':
              if (isset($form['#multiple']) && $form['#multiple']) {
                if (isset($edit) && is_array($edit)) {
                  $form['#value'] = drupal_map_assoc($edit);
                }
                else {
                  $form['#value'] = array();
                }
              }
              elseif (isset($edit)) {
                $form['#value'] = $edit;
              }
              break;
            case 'textfield':
              if (isset($edit)) {

                // Equate $edit to the form value to ensure it's marked for
                // validation.
                $edit = str_replace(array(
                  "\r",
                  "\n",
                ), '', $edit);
                $form['#value'] = $edit;
              }
              break;
            case 'token':
              $form['#value'] = (string) $edit;
              break;
            default:
              if (isset($edit)) {
                $form['#value'] = $edit;
              }
          }

          // Mark all posted values for validation.
          if (isset($form['#value']) && $form['#value'] === $edit || isset($form['#required']) && $form['#required']) {
            $form['#needs_validation'] = TRUE;
          }
        }
      }
      if (!isset($form['#value'])) {
        $function = $form['#type'] . '_value';
        if (function_exists($function)) {
          $function($form);
        }
        else {
          $form['#value'] = isset($form['#default_value']) ? $form['#default_value'] : '';
        }
      }
    }
    if (isset($form['#executes_submit_callback'])) {

      // Count submit and non-submit buttons.
      $form_button_counter[$form['#executes_submit_callback']]++;

      // See if a submit button was pressed.
      if (isset($form['#post'][$form['#name']]) && $form['#post'][$form['#name']] == $form['#value']) {
        $form_submitted = $form_submitted || $form['#executes_submit_callback'];

        // In most cases, we want to use form_set_value() to manipulate the
        // global variables. In this special case, we want to make sure that
        // the value of this element is listed in $form_variables under 'op'.
        $form_values[$form['#name']] = $form['#value'];
      }
    }
  }

  // Allow for elements to expand to multiple elements, e.g., radios,
  // checkboxes and files.
  if (isset($form['#process']) && !$form['#processed']) {
    foreach ($form['#process'] as $process => $args) {
      if (function_exists($process)) {
        $args = array_merge(array(
          $form,
        ), array(
          $edit,
        ), $args);
        $form = call_user_func_array($process, $args);
      }
    }
    $form['#processed'] = TRUE;
  }

  // Set the $form_values key that gets passed to validate and submit.
  // We call this after #process gets called so that #process has a
  // chance to update #value if desired.
  if (isset($form['#input']) && $form['#input']) {
    form_set_value($form, $form['#value']);
  }

  // We start off assuming all form elements are in the correct order.
  $form['#sorted'] = TRUE;

  // Recurse through all child elements.
  $count = 0;
  foreach (element_children($form) as $key) {
    $form[$key]['#post'] = $form['#post'];
    $form[$key]['#programmed'] = $form['#programmed'];

    // Don't squash an existing tree value.
    if (!isset($form[$key]['#tree'])) {
      $form[$key]['#tree'] = $form['#tree'];
    }

    // Deny access to child elements if parent is denied.
    if (isset($form['#access']) && !$form['#access']) {
      $form[$key]['#access'] = FALSE;
    }

    // Don't squash existing parents value.
    if (!isset($form[$key]['#parents'])) {

      // Check to see if a tree of child elements is present. If so,
      // continue down the tree if required.
      $form[$key]['#parents'] = $form[$key]['#tree'] && $form['#tree'] ? array_merge($form['#parents'], array(
        $key,
      )) : array(
        $key,
      );
    }

    // Assign a decimal placeholder weight to preserve original array order.
    if (!isset($form[$key]['#weight'])) {
      $form[$key]['#weight'] = $count / 1000;
    }
    else {

      // If one of the child elements has a weight then we will need to sort
      // later.
      unset($form['#sorted']);
    }
    $form[$key] = form_builder($form_id, $form[$key]);
    $count++;
  }
  if (isset($form['#after_build']) && !isset($form['#after_build_done'])) {
    foreach ($form['#after_build'] as $function) {
      if (function_exists($function)) {
        $form = $function($form, $form_values);
      }
    }
    $form['#after_build_done'] = TRUE;
  }
  return $form;
}