Same name and namespace in other branches
  1. 5.x includes/form.inc \drupal_prepare_form()
  2. 6.x includes/form.inc \drupal_prepare_form()

Prepares a structured form array.

Adds required elements, executes any hook_form_alter functions, and optionally inserts a validation token to prevent tampering.

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.

$form_state: A keyed array containing the current state of the form. Passed in here so that hook_form_alter() calls can use it, as well.

Related topics

7 calls to drupal_prepare_form()
drupal_build_form in includes/form.inc
Builds and process a form based on a form id.
drupal_form_submit in includes/form.inc
Retrieves, populates, and processes a form.
drupal_rebuild_form in includes/form.inc
Constructs a new $form from the information in $form_state.
FieldAttachOtherTestCase::testFieldAttachSubmit in modules/field/tests/field.test
Test field_attach_submit().
FormsElementsTableSelectFunctionalTest::formSubmitHelper in modules/simpletest/tests/form.test
Helper function for the option check test to submit a form while collecting errors.

... See full list

File

includes/form.inc, line 1007
Functions for form and batch generation and processing.

Code

function drupal_prepare_form($form_id, &$form, &$form_state) {
  global $user;
  $form['#type'] = 'form';
  $form_state['programmed'] = isset($form_state['programmed']) ? $form_state['programmed'] : FALSE;

  // Fix the form method, if it is 'get' in $form_state, but not in $form.
  if ($form_state['method'] == 'get' && !isset($form['#method'])) {
    $form['#method'] = 'get';
  }

  // Generate a new #build_id for this form, if none has been set already. The
  // form_build_id is used as key to cache a particular build of the form. For
  // multi-step forms, this allows the user to go back to an earlier build, make
  // changes, and re-submit.
  // @see drupal_build_form()
  // @see drupal_rebuild_form()
  if (!isset($form['#build_id'])) {
    $form['#build_id'] = 'form-' . drupal_random_key();
  }
  $form['form_build_id'] = array(
    '#type' => 'hidden',
    '#value' => $form['#build_id'],
    '#id' => $form['#build_id'],
    '#name' => 'form_build_id',
    // Form processing and validation requires this value, so ensure the
    // submitted form value appears literally, regardless of custom #tree
    // and #parents being set elsewhere.
    '#parents' => array(
      'form_build_id',
    ),
  );

  // Add a token, based on either #token or form_id, to any form displayed to
  // authenticated users. This ensures that any submitted form was actually
  // requested previously by the user and protects against cross site request
  // forgeries.
  // This does not apply to programmatically submitted forms. Furthermore, since
  // tokens are session-bound and forms displayed to anonymous users are very
  // likely cached, we cannot assign a token for them.
  // During installation, there is no $user yet.
  if (!empty($user->uid) && !$form_state['programmed']) {

    // Form constructors may explicitly set #token to FALSE when cross site
    // request forgery is irrelevant to the form, such as search forms.
    if (isset($form['#token']) && $form['#token'] === FALSE) {
      unset($form['#token']);
    }
    else {
      $form['#token'] = $form_id;
      $form['form_token'] = array(
        '#id' => drupal_html_id('edit-' . $form_id . '-form-token'),
        '#type' => 'token',
        '#default_value' => drupal_get_token($form['#token']),
        // Form processing and validation requires this value, so ensure the
        // submitted form value appears literally, regardless of custom #tree
        // and #parents being set elsewhere.
        '#parents' => array(
          'form_token',
        ),
      );
    }
  }
  if (isset($form_id)) {
    $form['form_id'] = array(
      '#type' => 'hidden',
      '#value' => $form_id,
      '#id' => drupal_html_id("edit-{$form_id}"),
      // Form processing and validation requires this value, so ensure the
      // submitted form value appears literally, regardless of custom #tree
      // and #parents being set elsewhere.
      '#parents' => array(
        'form_id',
      ),
    );
  }
  if (!isset($form['#id'])) {
    $form['#id'] = drupal_html_id($form_id);
  }
  $form += element_info('form');
  $form += array(
    '#tree' => FALSE,
    '#parents' => array(),
  );
  if (!isset($form['#validate'])) {

    // Ensure that modules can rely on #validate being set.
    $form['#validate'] = array();

    // Check for a handler specific to $form_id.
    if (function_exists($form_id . '_validate')) {
      $form['#validate'][] = $form_id . '_validate';
    }
    elseif (isset($form_state['build_info']['base_form_id']) && function_exists($form_state['build_info']['base_form_id'] . '_validate')) {
      $form['#validate'][] = $form_state['build_info']['base_form_id'] . '_validate';
    }
  }
  if (!isset($form['#submit'])) {

    // Ensure that modules can rely on #submit being set.
    $form['#submit'] = array();

    // Check for a handler specific to $form_id.
    if (function_exists($form_id . '_submit')) {
      $form['#submit'][] = $form_id . '_submit';
    }
    elseif (isset($form_state['build_info']['base_form_id']) && function_exists($form_state['build_info']['base_form_id'] . '_submit')) {
      $form['#submit'][] = $form_state['build_info']['base_form_id'] . '_submit';
    }
  }

  // If no #theme has been set, automatically apply theme suggestions.
  // theme_form() itself is in #theme_wrappers and not #theme. Therefore, the
  // #theme function only has to care for rendering the inner form elements,
  // not the form itself.
  if (!isset($form['#theme'])) {
    $form['#theme'] = array(
      $form_id,
    );
    if (isset($form_state['build_info']['base_form_id'])) {
      $form['#theme'][] = $form_state['build_info']['base_form_id'];
    }
  }

  // Invoke hook_form_alter(), hook_form_BASE_FORM_ID_alter(), and
  // hook_form_FORM_ID_alter() implementations.
  $hooks = array(
    'form',
  );
  if (isset($form_state['build_info']['base_form_id'])) {
    $hooks[] = 'form_' . $form_state['build_info']['base_form_id'];
  }
  $hooks[] = 'form_' . $form_id;
  drupal_alter($hooks, $form, $form_state, $form_id);
}