form.inc 125 KB
Newer Older
1
<?php
2 3
// $Id$

4
/**
5 6 7 8 9 10
 * @defgroup forms Form builder functions
 * @{
 * Functions that build an abstract representation of a HTML form.
 *
 * All modules should declare their form builder functions to be in this
 * group and each builder function should reference its validate and submit
11
 * functions using \@see. Conversely, validate and submit functions should
12
 * reference the form builder function using \@see. For examples, of this see
13
 * system_modules_uninstall() or user_pass(), the latter of which has the
14 15 16 17 18 19 20 21 22 23 24
 * following in its doxygen documentation:
 *
 * \@ingroup forms
 * \@see user_pass_validate().
 * \@see user_pass_submit().
 *
 * @} End of "defgroup forms".
 */

/**
 * @defgroup form_api Form generation
25
 * @{
26
 * Functions to enable the processing and display of HTML forms.
27
 *
28 29 30 31
 * Drupal uses these functions to achieve consistency in its form processing and
 * presentation, while simplifying code and reducing the amount of HTML that
 * must be explicitly generated by modules.
 *
32
 * The drupal_get_form() function handles retrieving and processing an HTML
33
 * form for modules automatically. For example:
34
 *
35
 * @code
36 37
 *   // Display the user registration form.
 *   $output = drupal_get_form('user_register_form');
38
 * @endcode
39 40
 *
 * Forms can also be built and submitted programmatically without any user input
41
 * using the drupal_form_submit() function.
42 43
 *
 * For information on the format of the structured arrays used to define forms,
44
 * and more detailed explanations of the Form API workflow, see the
45 46
 * @link http://api.drupal.org/api/file/developer/topics/forms_api_reference.html reference @endlink
 * and the @link http://api.drupal.org/api/file/developer/topics/forms_api.html quickstart guide. @endlink
47 48 49
 */

/**
50
 * Wrapper for drupal_build_form() for use when $form_state is not needed.
51 52
 *
 * @param $form_id
53 54 55 56 57 58
 *   The unique string identifying the desired form. If a function with that
 *   name exists, it is called to build the form array. Modules that need to
 *   generate the same form (or very similar forms) using different $form_ids
 *   can implement hook_forms(), which maps different $form_id values to the
 *   proper form constructor function. Examples may be found in node_forms(),
 *   search_forms(), and user_forms().
59
 * @param ...
60
 *   Any additional arguments are passed on to the functions called by
61 62 63
 *   drupal_get_form(), including the unique form constructor function. For
 *   example, the node_edit form requires that a node object is passed in here
 *   when it is called.
64
 * @return
65
 *   The form array.
66 67
 *
 * @see drupal_build_form()
68 69
 */
function drupal_get_form($form_id) {
70
  $form_state = array();
71 72

  $args = func_get_args();
73 74
  // Remove $form_id from the arguments.
  array_shift($args);
75
  $form_state['build_info']['args'] = $args;
76 77 78 79 80

  return drupal_build_form($form_id, $form_state);
}

/**
81
 * Build and process a form based on a form id.
82 83 84
 *
 * The form may also be retrieved from the cache if the form was built in a
 * previous page-load. The form is then passed on for processing, validation
85
 * and submission if there is proper input.
86 87 88 89 90 91 92 93 94 95
 *
 * @param $form_id
 *   The unique string identifying the desired form. If a function with that
 *   name exists, it is called to build the form array. Modules that need to
 *   generate the same form (or very similar forms) using different $form_ids
 *   can implement hook_forms(), which maps different $form_id values to the
 *   proper form constructor function. Examples may be found in node_forms(),
 *   search_forms(), and user_forms().
 * @param &$form_state
 *   An array which stores information about the form. This is passed as a
96
 *   reference so that the caller can use it to examine what in the form changed
97 98 99
 *   when the form submission process is complete. Furthermore, it may be used
 *   to store information related to the processed data in the form, which will
 *   persist across page requests when the 'cache' or 'rebuild' flag is set.
100 101
 *   The following parameters may be set in $form_state to affect how the form
 *   is rendered:
102 103 104 105 106 107 108
 *   - build_info: A keyed array of build information that is necessary to
 *     rebuild the form from cache when the original context may no longer be
 *     available:
 *     - args: An array of arguments to pass to the form builder.
 *     - file: An optional include file that contains the form and is
 *       automatically loaded by form_get_cache(). Defaults to the current menu
 *       router item's 'file' definition, if existent.
109 110 111 112 113 114 115 116 117 118 119
 *   - rebuild: Normally, after the entire form processing is completed and
 *     submit handlers ran, a form is considered to be done and
 *     drupal_redirect_form() will redirect the user to a new page using a GET
 *     request (so a browser refresh does not re-submit the form). However, if
 *     'rebuild' has been set to TRUE, then a new copy of the form is
 *     immediately built and sent to the browser; instead of a redirect. This is
 *     used for multi-step forms, such as wizards and confirmation forms. Also,
 *     if a form validation handler has set 'rebuild' to TRUE and a validation
 *     error occurred, then the form is rebuilt prior to being returned,
 *     enabling form elements to be altered, as appropriate to the particular
 *     validation error.
120 121 122 123 124 125 126 127
 *   - input: An array of input that corresponds to $_POST or $_GET, depending
 *     on the 'method' chosen (see below).
 *   - method: The HTTP form method to use for finding the input for this form.
 *     May be 'post' or 'get'. Defaults to 'post'. Note that 'get' method
 *     forms do not use form ids so are always considered to be submitted, which
 *     can have unexpected effects. The 'get' method should only be used on
 *     forms that do not change data, as that is exclusively the domain of post.
 *   - no_redirect: If set to TRUE the form will NOT perform a drupal_goto(),
128 129 130 131 132
 *     even if 'redirect' is set.
 *   - cache: If set to TRUE the original, unprocessed form structure will be
 *     cached, which allows to rebuild the entire form from cache.
 *   - no_cache: If set to TRUE the form will NOT be cached, even if 'cache' is
 *     set.
133 134 135 136 137 138 139 140 141
 *   - always_process: If TRUE and the method is GET, a form_id is not
 *     necessary. This should only be used on RESTful GET forms that do NOT
 *     write data, as this could lead to security issues. It is useful so that
 *     searches do not need to have a form_id in their query arguments to
 *     trigger the search.
 *   - must_validate: Ordinarily, a form is only validated once but there are
 *     times when a form is resubmitted internally and should be validated
 *     again. Setting this to TRUE will force that to happen. This is most
 *     likely to occur during AHAH or AJAX operations.
142 143 144 145
 *   - temporary: An array holding temporary data accessible during the current
 *     page request only. It may be used to temporary save any data that doesn't
 *     need to or shouldn't be cached during the whole form workflow, e.g. data
 *     that needs to be accessed during the current form build process only.
146 147 148 149
 *   - wrapper_callback: Modules that wish to pre-populate certain forms with
 *     common elements, such as back/next/save buttons in multi-step form
 *     wizards, may define a form builder function name that returns a form
 *     structure, which is passed on to the actual form builder function.
150 151 152 153
 *     Such implementations may either define the 'wrapper_callback' via
 *     hook_forms() or have to invoke drupal_build_form() (instead of
 *     drupal_get_form()) on their own in a custom menu callback to prepare
 *     $form_state accordingly.
154 155 156
 *   Further $form_state properties controlling the redirection behavior after
 *   form submission may be found in drupal_redirect_form().
 *
157 158
 * @return
 *   The rendered form or NULL, depending upon the $form_state flags that were set.
159 160
 *
 * @see drupal_redirect_form()
161 162 163 164 165 166 167 168 169
 */
function drupal_build_form($form_id, &$form_state) {
  // Ensure some defaults; if already set they will not be overridden.
  $form_state += form_state_defaults();

  if (!isset($form_state['input'])) {
    $form_state['input'] = $form_state['method'] == 'get' ? $_GET : $_POST;
  }

170 171 172 173 174 175
  if (isset($_SESSION['batch_form_state'])) {
    // We've been redirected here after a batch processing : the form has
    // already been processed, so we grab the post-process $form_state value
    // and move on to form display. See _batch_finished() function.
    $form_state = $_SESSION['batch_form_state'];
    unset($_SESSION['batch_form_state']);
176 177
  }
  else {
178
    // If the incoming input contains a form_build_id, we'll check the
179 180 181 182
    // cache for a copy of the form in question. If it's there, we don't
    // have to rebuild the form to proceed. In addition, if there is stored
    // form_state data from a previous step, we'll retrieve it so it can
    // be passed on to the form processing code.
183
    if (isset($form_state['input']['form_id']) && $form_state['input']['form_id'] == $form_id && !empty($form_state['input']['form_build_id'])) {
184 185
      $form_build_id = $form_state['input']['form_build_id'];
      $form = form_get_cache($form_build_id, $form_state);
186 187
    }

188 189 190 191
    // If the previous bit of code didn't result in a populated $form
    // object, we're hitting the form for the first time and we need
    // to build it from scratch.
    if (!isset($form)) {
192 193
      // Record the filepath of the include file containing the original form,
      // so the form builder callbacks can be loaded when the form is being
194
      // rebuilt from cache on a different path (such as 'system/ajax').
195 196
      // @see form_get_cache()
      // menu_get_item() is not available at installation time.
197
      if (!isset($form_state['build_info']['file']) && !defined('MAINTENANCE_MODE')) {
198 199
        $item = menu_get_item();
        if (!empty($item['file'])) {
200
          $form_state['build_info']['file'] = $item['file'];
201 202 203
        }
      }

204 205 206 207
      $form = drupal_retrieve_form($form_id, $form_state);
      $form_build_id = 'form-' . md5(uniqid(mt_rand(), TRUE));
      $form['#build_id'] = $form_build_id;

208 209 210 211 212
      // 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';
      }

213
      drupal_prepare_form($form_id, $form, $form_state);
214 215
      // Store a copy of the unprocessed form to cache in case
      // $form_state['cache'] is set.
216
      $original_form = $form;
217
    }
218

219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    // Now that we know we have a form, we'll process it (validating,
    // submitting, and handling the results returned by its submission
    // handlers. Submit handlers accumulate data in the form_state by
    // altering the $form_state variable, which is passed into them by
    // reference.
    drupal_process_form($form_id, $form, $form_state);
  }

  // Most simple, single-step forms will be finished by this point --
  // drupal_process_form() usually redirects to another page (or to
  // a 'fresh' copy of the form) once processing is complete. If one
  // of the form's handlers has set $form_state['redirect'] to FALSE,
  // the form will simply be re-rendered with the values still in its
  // fields.
  //
234 235 236 237
  // If $form_state['rebuild'] has been set and the form has been submitted, we
  // know that we're in a multi-part process of some sort and the form's
  // workflow is not complete. We need to construct a fresh copy of the form,
  // passing in the latest $form_state in addition to any other variables passed
238
  // into drupal_get_form().
239
  if ($form_state['rebuild'] && $form_state['submitted'] && !form_get_errors()) {
240
    $form = drupal_rebuild_form($form_id, $form_state);
241
  }
242 243 244 245 246 247 248 249 250 251 252 253 254 255
  // After processing the form, the form builder or a #process callback may
  // have set $form_state['cache'] to indicate that the original form and the
  // $form_state shall be cached. But the form may only be cached if the
  // special 'no_cache' property is not set to TRUE and we are not rebuilding.
  elseif (isset($form_build_id) && $form_state['cache'] && empty($form_state['no_cache'])) {
    // Cache the original, unprocessed form upon initial build of the form.
    if (isset($original_form)) {
      form_set_cache($form_build_id, $original_form, $form_state);
    }
    // After processing a cached form, only update the cached form state.
    else {
      form_set_cache($form_build_id, NULL, $form_state);
    }
  }
256

257 258
  // Don't override #theme if someone already set it.
  if (!isset($form['#theme'])) {
259
    drupal_theme_initialize();
260 261 262 263 264
    $registry = theme_get_registry();
    if (isset($registry[$form_id])) {
      $form['#theme'] = $form_id;
    }
  }
265

266
  return $form;
267
}
268

269 270 271 272 273
/**
 * Retrieve default values for the $form_state array.
 */
function form_state_defaults() {
  return array(
274 275
    'rebuild' => FALSE,
    'redirect' => NULL,
276 277
    'build_info' => array('args' => array()),
    'temporary' => array(),
278 279
    'submitted' => FALSE,
    'programmed' => FALSE,
280 281
    'cache'=> FALSE,
    'method' => 'post',
282
    'groups' => array(),
283 284 285
  );
}

286
/**
287
 * Retrieves a form, caches it and processes it again.
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
 *
 * If your AHAH callback simulates the pressing of a button, then your AHAH
 * callback will need to do the same as what drupal_get_form would do when the
 * button is pressed: get the form from the cache, run drupal_process_form over
 * it and then if it needs rebuild, run drupal_rebuild_form over it. Then send
 * back a part of the returned form.
 * $form_state['clicked_button']['#array_parents'] will help you to find which
 * part.
 *
 * @param $form_id
 *   The unique string identifying the desired form. If a function
 *   with that name exists, it is called to build the form array.
 *   Modules that need to generate the same form (or very similar forms)
 *   using different $form_ids can implement hook_forms(), which maps
 *   different $form_id values to the proper form constructor function. Examples
 *   may be found in node_forms(), search_forms(), and user_forms().
 * @param $form_state
305
 *   A keyed array containing the current state of the form.
306 307 308 309 310 311 312
 * @param $form_build_id
 *   If the AHAH callback calling this function only alters part of the form,
 *   then pass in the existing form_build_id so we can re-cache with the same
 *   csid.
 * @return
 *   The newly built form.
 */
313
function drupal_rebuild_form($form_id, &$form_state, $form_build_id = NULL) {
314 315 316 317 318 319 320
  // AJAX and other contexts may call drupal_rebuild_form() even when
  // $form_state['rebuild'] isn't set, but _form_builder_handle_input_element()
  // needs to distinguish a rebuild from an initial build in order to process
  // user input correctly. Form constructors and form processing functions may
  // also need to handle a rebuild differently than an initial build.
  $form_state['rebuild'] = TRUE;

321
  $form = drupal_retrieve_form($form_id, $form_state);
322 323 324

  if (!isset($form_build_id)) {
    // We need a new build_id for the new version of the form.
325
    $form_build_id = 'form-' . md5(mt_rand());
326 327 328 329
  }
  $form['#build_id'] = $form_build_id;
  drupal_prepare_form($form_id, $form, $form_state);

330
  if (empty($form_state['no_cache'])) {
331 332 333 334 335
    // We cache the form structure so it can be retrieved later for validation.
    // If $form_state['storage'] is populated, we also cache it so that it can
    // be used to resume complex multi-step processes.
    form_set_cache($form_build_id, $form, $form_state);
  }
336

337 338
  // Clear out all group associations as these might be different when
  // re-rendering the form.
339 340
  $form_state['groups'] = array();

341 342 343
  // Do not call drupal_process_form(), since it would prevent the rebuilt form
  // to submit.
  $form = form_builder($form_id, $form, $form_state);
344 345 346
  return $form;
}

347 348 349 350
/**
 * Fetch a form from cache.
 */
function form_get_cache($form_build_id, &$form_state) {
351
  if ($cached = cache_get('form_' . $form_build_id, 'cache_form')) {
352
    $form = $cached->data;
353

354 355
    global $user;
    if ((isset($form['#cache_token']) && drupal_valid_token($form['#cache_token'])) || (!isset($form['#cache_token']) && !$user->uid)) {
356 357
      if ($cached = cache_get('form_state_' . $form_build_id, 'cache_form')) {
        // Re-populate $form_state for subsequent rebuilds.
358
        $form_state = $cached->data + $form_state;
359 360 361 362 363 364

        // If the original form is contained in an include file, load the file.
        // @see drupal_build_form()
        if (!empty($form_state['build_info']['file']) && file_exists($form_state['build_info']['file'])) {
          require_once DRUPAL_ROOT . '/' . $form_state['build_info']['file'];
        }
365 366
      }
      return $form;
367 368 369 370 371
    }
  }
}

/**
372
 * Store a form in the cache.
373 374
 */
function form_set_cache($form_build_id, $form, $form_state) {
375 376
  // 6 hours cache life time for forms should be plenty.
  $expire = 21600;
377 378 379 380 381 382 383

  // Cache form structure.
  if (isset($form)) {
    if ($GLOBALS['user']->uid) {
      $form['#cache_token'] = drupal_get_token();
    }
    cache_set('form_' . $form_build_id, $form, 'cache_form', REQUEST_TIME + $expire);
384
  }
385 386

  // Cache form state.
387
  if ($data = array_diff_key($form_state, array_flip(form_state_keys_no_cache()))) {
388
    cache_set('form_state_' . $form_build_id, $data, 'cache_form', REQUEST_TIME + $expire);
389 390 391
  }
}

392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
/**
 * Returns an array of $form_state keys that shouldn't be cached.
 */
function form_state_keys_no_cache() {
  return array(
    // Public properties defined by form constructors and form handlers.
    'always_process',
    'cache',
    'no_cache',
    'must_validate',
    'rebuild',
    'redirect',
    'no_redirect',
    'temporary',
    // Internal properties defined by form processing.
    'buttons',
    'clicked_button',
    'complete form',
    'groups',
    'input',
    'method',
    'submit_handlers',
    'submitted',
    'validate_handlers',
    'values',
  );
}

420
/**
421
 * Retrieves a form using a form_id, populates it with $form_state['values'],
422 423 424 425 426 427 428 429
 * processes it, and returns any validation errors encountered. This
 * function is the programmatic counterpart to drupal_get_form().
 *
 * @param $form_id
 *   The unique string identifying the desired form. If a function
 *   with that name exists, it is called to build the form array.
 *   Modules that need to generate the same form (or very similar forms)
 *   using different $form_ids can implement hook_forms(), which maps
430
 *   different $form_id values to the proper form constructor function. Examples
431
 *   may be found in node_forms(), search_forms(), and user_forms().
432
 * @param $form_state
433 434 435 436 437 438 439
 *   A keyed array containing the current state of the form. Most important is
 *   the $form_state['values'] collection, a tree of data used to simulate the
 *   incoming $_POST information from a user's form submission. If a key is not
 *   filled in $form_state['values'], then the default value of the respective
 *   element is used. To submit an unchecked checkbox or other control that
 *   browsers submit by not having a $_POST entry, include the key, but set the
 *   value to NULL.
440
 * @param ...
441
 *   Any additional arguments are passed on to the functions called by
442
 *   drupal_form_submit(), including the unique form constructor function.
443 444
 *   For example, the node_edit form requires that a node object be passed
 *   in here when it is called.
445 446
 * For example:
 *
447
 * @code
448
 * // register a new user
449 450 451
 * $form_state = array();
 * $form_state['values']['name'] = 'robo-user';
 * $form_state['values']['mail'] = 'robouser@example.com';
452 453
 * $form_state['values']['pass']['pass1'] = 'password';
 * $form_state['values']['pass']['pass2'] = 'password';
454
 * $form_state['values']['op'] = t('Create new account');
455
 * drupal_form_submit('user_register_form', $form_state);
456 457
 *
 * // Create a new node
458
 * $form_state = array();
459
 * module_load_include('inc', 'node', 'node.pages');
460
 * $node = array('type' => 'story');
461 462 463
 * $form_state['values']['title'] = 'My node';
 * $form_state['values']['body'] = 'This is the body text!';
 * $form_state['values']['name'] = 'robo-user';
464
 * $form_state['values']['op'] = t('Save');
465
 * drupal_form_submit('story_node_form', $form_state, (object)$node);
466
 * @endcode
467
 */
468
function drupal_form_submit($form_id, &$form_state) {
469
  if (!isset($form_state['build_info']['args'])) {
470 471 472
    $args = func_get_args();
    array_shift($args);
    array_shift($args);
473
    $form_state['build_info']['args'] = $args;
474
  }
475 476
  // Merge in default values.
  $form_state += form_state_defaults();
Dries's avatar
Dries committed
477

478 479 480
  $form = drupal_retrieve_form($form_id, $form_state);
  $form_state['input'] = $form_state['values'];
  $form_state['programmed'] = TRUE;
481 482
  // Programmed forms are always submitted.
  $form_state['submitted'] = TRUE;
483

484 485
  drupal_prepare_form($form_id, $form, $form_state);
  drupal_process_form($form_id, $form, $form_state);
486 487
}

488 489 490 491 492 493 494 495
/**
 * Retrieves the structured array that defines a given form.
 *
 * @param $form_id
 *   The unique string identifying the desired form. If a function
 *   with that name exists, it is called to build the form array.
 *   Modules that need to generate the same form (or very similar forms)
 *   using different $form_ids can implement hook_forms(), which maps
496
 *   different $form_id values to the proper form constructor function.
497 498
 * @param $form_state
 *   A keyed array containing the current state of the form.
499
 * @param ...
500 501
 *   Any additional arguments needed by the unique form constructor
 *   function. Generally, these are any arguments passed into the
502
 *   drupal_get_form() or drupal_form_submit() functions after the first
503 504 505
 *   argument. If a module implements hook_forms(), it can examine
 *   these additional arguments and conditionally return different
 *   builder functions as well.
506
 */
507
function drupal_retrieve_form($form_id, &$form_state) {
508
  $forms = &drupal_static(__FUNCTION__);
509

510
  // We save two copies of the incoming arguments: one for modules to use
511
  // when mapping form ids to constructor functions, and another to pass to
512
  // the constructor function itself.
513
  $args = $form_state['build_info']['args'];
514 515 516

  // We first check to see if there's a function named after the $form_id.
  // If there is, we simply pass the arguments on to it to get the form.
517
  if (!function_exists($form_id)) {
518
    // In cases where many form_ids need to share a central constructor function,
519
    // such as the node editing form, modules can implement hook_forms(). It
520
    // maps one or more form_ids to the correct constructor functions.
521 522 523 524 525 526 527 528 529
    //
    // We cache the results of that hook to save time, but that only works
    // for modules that know all their form_ids in advance. (A module that
    // adds a small 'rate this comment' form to each comment in a list
    // would need a unique form_id for each one, for example.)
    //
    // So, we call the hook if $forms isn't yet populated, OR if it doesn't
    // yet have an entry for the requested form_id.
    if (!isset($forms) || !isset($forms[$form_id])) {
530
      $forms = module_invoke_all('forms', $form_id, $args);
531 532 533 534 535 536 537 538
    }
    $form_definition = $forms[$form_id];
    if (isset($form_definition['callback arguments'])) {
      $args = array_merge($form_definition['callback arguments'], $args);
    }
    if (isset($form_definition['callback'])) {
      $callback = $form_definition['callback'];
    }
539 540 541 542 543
    // In case $form_state['wrapper_callback'] is not defined already, we also
    // allow hook_forms() to define one.
    if (!isset($form_state['wrapper_callback']) && isset($form_definition['wrapper_callback'])) {
      $form_state['wrapper_callback'] = $form_definition['wrapper_callback'];
    }
544
  }
545

546 547 548 549 550 551
  $form = array();
  // We need to pass $form_state by reference in order for forms to modify it,
  // since call_user_func_array() requires that referenced variables are passed
  // explicitly.
  $args = array_merge(array($form, &$form_state), $args);

552 553 554 555 556 557 558 559
  // When the passed $form_state (not using drupal_get_form()) defines a
  // 'wrapper_callback', then it requests to invoke a separate (wrapping) form
  // builder function to pre-populate the $form array with form elements, which
  // the actual form builder function ($callback) expects. This allows for
  // pre-populating a form with common elements for certain forms, such as
  // back/next/save buttons in multi-step form wizards.
  // @see drupal_build_form()
  if (isset($form_state['wrapper_callback']) && function_exists($form_state['wrapper_callback'])) {
560 561 562
    $form = call_user_func_array($form_state['wrapper_callback'], $args);
    // Put the prepopulated $form into $args.
    $args[0] = $form;
563
  }
564

565 566
  // If $callback was returned by a hook_forms() implementation, call it.
  // Otherwise, call the function named after the form id.
567
  $form = call_user_func_array(isset($callback) ? $callback : $form_id, $args);
568
  $form['#form_id'] = $form_id;
569

570
  return $form;
571 572 573
}

/**
574 575
 * Processes a form submission.
 *
576 577 578 579 580
 * This function is the heart of form API. The form gets built, validated and in
 * appropriate cases, submitted.
 *
 * @param $form_id
 *   The unique string identifying the current form.
581 582
 * @param $form
 *   An associative array containing the structure of the form.
583 584
 * @param $form_state
 *   A keyed array containing the current state of the form. This
Dries's avatar
Dries committed
585
 *   includes the current persistent storage data for the form, and
586 587 588
 *   any data passed along by earlier steps when displaying a
 *   multi-step form. Additional information, like the sanitized $_POST
 *   data, is also accumulated here.
589
 */
590 591 592
function drupal_process_form($form_id, &$form, &$form_state) {
  $form_state['values'] = array();

593 594 595 596 597 598 599 600 601 602 603 604 605
  // With $_GET, these forms are always submitted if requested.
  if ($form_state['method'] == 'get' && !empty($form_state['always_process'])) {
    if (!isset($form_state['input']['form_build_id'])) {
      $form_state['input']['form_build_id'] = $form['#build_id'];
    }
    if (!isset($form_state['input']['form_id'])) {
      $form_state['input']['form_id'] = $form_id;
    }
    if (!isset($form_state['input']['form_token']) && isset($form['#token'])) {
      $form_state['input']['form_token'] = drupal_get_token($form['#token']);
    }
  }

606
  // Build the form.
607
  $form = form_builder($form_id, $form, $form_state);
608 609 610

  // Only process the input if we have a correct form submission.
  if ($form_state['process_input']) {
611 612
    drupal_validate_form($form_id, $form, $form_state);

613
    // drupal_html_id() maintains a cache of element IDs it has seen,
614
    // so it can prevent duplicates. We want to be sure we reset that
615
    // cache when a form is processed, so scenarios that result in
616 617
    // the form being built behind the scenes and again for the
    // browser don't increment all the element IDs needlessly.
618
    drupal_static_reset('drupal_html_id');
619

620 621
    if ($form_state['submitted'] && !form_get_errors() && !$form_state['rebuild']) {
      // Execute form submit handlers.
622 623 624 625 626
      form_execute_handlers('submit', $form, $form_state);

      // We'll clear out the cached copies of the form and its stored data
      // here, as we've finished with them. The in-memory copies are still
      // here, though.
627
      if (variable_get('cache', CACHE_DISABLED) == CACHE_DISABLED && !empty($form_state['values']['form_build_id'])) {
628 629
        cache_clear_all('form_' . $form_state['values']['form_build_id'], 'cache_form');
        cache_clear_all('storage_' . $form_state['values']['form_build_id'], 'cache_form');
630 631 632
      }

      // If batches were set in the submit handlers, we process them now,
633 634
      // possibly ending execution. We make sure we do not react to the batch
      // that is already being processed (if a batch operation performs a
635
      // drupal_form_submit).
636
      if ($batch =& batch_get() && !isset($batch['current_set'])) {
637
        // The batch uses its own copies of $form and $form_state for
638
        // late execution of submit handlers and post-batch redirection.
639 640
        $batch['form'] = $form;
        $batch['form_state'] = $form_state;
641
        $batch['progressive'] = !$form_state['programmed'];
642
        batch_process();
643 644 645 646
        // Execution continues only for programmatic forms.
        // For 'regular' forms, we get redirected to the batch processing
        // page. Form redirection will be handled in _batch_finished(),
        // after the batch is processed.
647
      }
648

649 650 651
      // Set a flag to indicate the the form has been processed and executed.
      $form_state['executed'] = TRUE;

652 653
      // Redirect the form based on values in $form_state.
      drupal_redirect_form($form_state);
654 655 656 657 658 659 660 661 662 663 664 665 666 667
    }
  }
}

/**
 * Prepares a structured form array by adding required elements,
 * executing any hook_form_alter functions, and optionally inserting
 * a validation token to prevent tampering.
 *
 * @param $form_id
 *   A unique string identifying the form for validation, submission,
 *   theming, and hook_form_alter functions.
 * @param $form
 *   An associative array containing the structure of the form.
668 669 670
 * @param $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.
671
 */
672
function drupal_prepare_form($form_id, &$form, &$form_state) {
673 674
  global $user;

675
  $form['#type'] = 'form';
676
  $form_state['programmed'] = isset($form_state['programmed']) ? $form_state['programmed'] : FALSE;
677

678 679 680 681 682 683 684 685 686
  if (isset($form['#build_id'])) {
    $form['form_build_id'] = array(
      '#type' => 'hidden',
      '#value' => $form['#build_id'],
      '#id' => $form['#build_id'],
      '#name' => 'form_build_id',
    );
  }

687 688 689 690
  // 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.
691
  if (isset($form['#token'])) {
692
    if ($form['#token'] === FALSE || $user->uid == 0 || $form_state['programmed']) {
693
      unset($form['#token']);
694
    }
695
    else {
696
      $form['form_token'] = array('#type' => 'token', '#default_value' => drupal_get_token($form['#token']));
697
    }
698
  }
699
  elseif (isset($user->uid) && $user->uid && !$form_state['programmed']) {
700 701
    $form['#token'] = $form_id;
    $form['form_token'] = array(
702
      '#id' => drupal_html_id('edit-' . $form_id . '-form-token'),
703 704 705 706 707
      '#type' => 'token',
      '#default_value' => drupal_get_token($form['#token']),
    );
  }

708
  if (isset($form_id)) {
709 710 711
    $form['form_id'] = array(
      '#type' => 'hidden',
      '#value' => $form_id,
712
      '#id' => drupal_html_id("edit-$form_id"),
713
    );
714
  }
715
  if (!isset($form['#id'])) {
716
    $form['#id'] = drupal_html_id($form_id);
717
  }
718

719
  $form += element_info('form');
720
  $form += array('#tree' => FALSE, '#parents' => array());
721

Dries's avatar
Dries committed
722
  if (!isset($form['#validate'])) {
723
    if (function_exists($form_id . '_validate')) {
724
      $form['#validate'] = array($form_id . '_validate');
Dries's avatar
Dries committed
725 726 727
    }
  }

728
  if (!isset($form['#submit'])) {
729
    if (function_exists($form_id . '_submit')) {
730
      // We set submit here so that it can be altered.
731
      $form['#submit'] = array($form_id . '_submit');
Dries's avatar
Dries committed
732 733 734
    }
  }

735 736 737 738 739
  // Invoke hook_form_FORM_ID_alter() implementations.
  drupal_alter('form_' . $form_id, $form, $form_state);

  // Invoke hook_form_alter() implementations.
  drupal_alter('form', $form, $form_state, $form_id);
740 741
}

742 743

/**
744
 * Validates user-submitted form data from the $form_state using
745 746 747 748 749 750
 * the validate functions defined in a structured form array.
 *
 * @param $form_id
 *   A unique string identifying the form for validation, submission,
 *   theming, and hook_form_alter functions.
 * @param $form
751 752 753 754 755 756 757
 *   An associative array containing the structure of the form, which is passed
 *   by reference. Form validation handlers are able to alter the form structure
 *   (like #process and #after_build callbacks during form building) in case of
 *   a validation error. If a validation handler alters the form structure, it
 *   is responsible for validating the values of changed form elements in
 *   $form_state['values'] to prevent form submit handlers from receiving
 *   unvalidated values.
758 759 760 761 762 763 764 765 766 767
 * @param $form_state
 *   A keyed array containing the current state of the form. The current
 *   user-submitted data is stored in $form_state['values'], though
 *   form validation functions are passed an explicit copy of the
 *   values for the sake of simplicity. Validation handlers can also
 *   $form_state to pass information on to submit handlers. For example:
 *     $form_state['data_for_submision'] = $data;
 *   This technique is useful when validation requires file parsing,
 *   web service requests, or other expensive requests that should
 *   not be repeated in the submission step.
768
 */
769
function drupal_validate_form($form_id, &$form, &$form_state) {
770
  $validated_forms = &drupal_static(__FUNCTION__, array());
771

772
  if (isset($validated_forms[$form_id]) && empty($form_state['must_validate'])) {
773 774
    return;
  }
775

776
  // If the session token was set by drupal_prepare_form(), ensure that it
777
  // matches the current user's session.
778
  if (isset($form['#token'])) {
779
    if (!drupal_valid_token($form_state['values']['form_token'], $form['#token'])) {
780
      // Setting this error will cause the form to fail validation.
781
      form_set_error('form_token', t('Validation error, please try again. If this error persists, please contact the site administrator.'));
782 783 784
    }
  }

785
  _form_validate($form, $form_state, $form_id);
786
  $validated_forms[$form_id] = TRUE;
787 788
}

789
/**
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
 * Redirects the user to a URL after a form has been processed.
 *
 * After a form was executed, the data in $form_state controls whether the form
 * is redirected. By default, we redirect to a new destination page. The path of
 * the destination page can be set in $form_state['redirect']. If that is not
 * set, the user is redirected to the current page to display a fresh,
 * unpopulated copy of the form.
 *
 * There are several triggers that may prevent a redirection though:
 * - If $form_state['redirect'] is FALSE, a form builder function or form
 *   validation/submit handler does not want a user to be redirected, which
 *   means that drupal_goto() is not invoked. For most forms, the redirection
 *   logic will be the same regardless of whether $form_state['redirect'] is
 *   undefined or FALSE. However, in case it was not defined and the current
 *   request contains a 'destination' query string, drupal_goto() will redirect
 *   to that given destination instead. Only setting $form_state['redirect'] to
 *   FALSE will prevent any redirection.
 * - If $form_state['no_redirect'] is TRUE, then the callback that originally
 *   built the form explicitly disallows any redirection, regardless of the
 *   redirection value in $form_state['redirect']. For example, ajax_get_form()
 *   defines $form_state['no_redirect'] when building a form in an AJAX
 *   callback to prevent any redirection. $form_state['no_redirect'] should NOT
 *   be altered by form builder functions or form validation/submit handlers.
 * - If $form_state['programmed'] is TRUE, the form submission was usually
 *   invoked via drupal_form_submit(), so any redirection would break the script
 *   that invoked drupal_form_submit().
816
 * - If $form_state['rebuild'] is TRUE, the form needs to be rebuilt without
817
 *   redirection.
818
 *
819 820 821 822 823
 * @param $form_state
 *   A keyed array containing the current state of the form.
 *
 * @see drupal_process_form()
 * @see drupal_build_form()
824
 */
825 826 827 828
function drupal_redirect_form($form_state) {
  // Skip redirection for form submissions invoked via drupal_form_submit().
  if (!empty($form_state['programmed'])) {
    return;
829
  }
830 831
  // Skip redirection if rebuild is activated.
  if (!empty($form_state['rebuild'])) {
832 833 834 835 836
    return;
  }
  // Skip redirection if it was explicitly disallowed.
  if (!empty($form_state['no_redirect'])) {
    return;
837
  }
838 839 840 841 842
  // Only invoke drupal_goto() if redirect value was not set to FALSE.
  if (!isset($form_state['redirect']) || $form_state['redirect'] !== FALSE) {
    if (isset($form_state['redirect'])) {
      if (is_array($form_state['redirect'])) {
        call_user_func_array('drupal_goto', $form_state['redirect']);
843 844
      }
      else {
845 846 847 848
        // This function can be called from the installer, which guarantees
        // that $redirect will always be a string, so catch that case here
        // and use the appropriate redirect function.
        $function = drupal_installation_attempted() ? 'install_goto' : 'drupal_goto';
849
        $function($form_state['redirect']);
850 851 852 853
      }
    }
    drupal_goto($_GET['q']);
  }
854 855
}

856 857 858 859 860 861 862
/**
 * Performs validation on form elements. First ensures required fields are
 * completed, #maxlength is not exceeded, and selected options were in the
 * list of options given to the user. Then calls user-defined validators.
 *
 * @param $elements
 *   An associative array containing the structure of the form.
863 864 865 866 867 868 869 870 871 872
 * @param $form_state
 *   A keyed array containing the current state of the form. The current
 *   user-submitted data is stored in $form_state['values'], though
 *   form validation functions are passed an explicit copy of the
 *   values for the sake of simplicity. Validation handlers can also
 *   $form_state to pass information on to submit handlers. For example:
 *     $form_state['data_for_submision'] = $data;
 *   This technique is useful when validation requires file parsing,
 *   web service requests, or other expensive requests that should
 *   not be repeated in the submission step.
873 874 875 876
 * @param $form_id
 *   A unique string identifying the form for validation, submission,
 *   theming, and hook_form_alter functions.
 */
877
function _form_validate(&$elements, &$form_state, $form_id = NULL) {
878 879
  // Also used in the installer, pre-database setup.
  $t = get_t();
880

881 882 883
  // Recurse through all children.
  foreach (element_children($elements) as $key) {
    if (isset($elements[$key]) && $elements[$key]) {
884
      _form_validate($elements[$key], $form_state);
885 886
    }
  }
887
  // Validate the current input.
888
  if (!isset($elements['#validated']) || !$elements['#validated']) {
889
    if (isset($elements['#needs_validation'])) {
890 891 892 893
      // Make sure a value is passed when the field is required.
      // A simple call to empty() will not cut it here as some fields, like
      // checkboxes, can return a valid value of '0'. Instead, check the
      // length if it's a string, and the item count if it's an array.
894 895 896
      // An unchecked checkbox has a #value of numeric 0, different than string
      // '0', which could be a valid value.
      if ($elements['#required'] && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0) || $elements['#value'] === 0)) {
Dries's avatar
Dries committed
897
        form_error($elements, $t('!name field is required.', array('!name' => $elements['#title'])));
898
      }
899

900 901
      // Verify that the value is not longer than #maxlength.
      if (isset($elements['#maxlength']) && drupal_strlen($elements['#value']) > $elements['#maxlength']) {
902
        form_error($elements, $t('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'], '%max' => $elements['#maxlength'], '%length' => drupal_strlen($elements['#value']))));
903 904
      }

905
      if (isset($elements['#options']) && isset($elements['#value'])) {
906 907 908 909 910 911 912 913 914 915
        if ($elements['#type'] == 'select') {
          $options = form_options_flatten($elements['#options']);
        }
        else {
          $options = $elements['#options'];
        }
        if (is_array($elements['#value'])) {
          $value = $elements['#type'] == 'checkboxes' ? array_keys(array_filter($elements['#value'])) : $elements['#value'];
          foreach ($value as $v) {
            if (!isset($options[$v])) {
916
              form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));
917
              watchdog('form', 'Illegal choice %choice in !name element.', array('%choice' => $v, '!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']), WATCHDOG_ERROR);
918
            }
919 920
          }
        }
921
        elseif (!isset($options[$elements['#value']])) {
922
          form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));
923
          watchdog('form', 'Illegal choice %choice in %name element.', array('%choice' => $elements['#value'], '%name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']), WATCHDOG_ERROR);
924
        }
925 926 927
      }
    }

928
    // Call user-defined form level validators.
929 930 931 932 933 934 935
    if (isset($form_id)) {
      form_execute_handlers('validate', $elements, $form_state);
    }
    // Call any element-specific validators. These must act on the element
    // #value data.
    elseif (isset($elements['#element_validate'])) {
      foreach ($elements['#element_validate'] as $function) {
936
        if (function_exists($function))  {
937
          $function($elements, $form_state, $form_state['complete form']);
938 939 940
        }
      }
    }
941
    $elements['#validated'] = TRUE;
942 943 944
  }
}

945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961
/**
 * A helper function used to execute custom validation and submission
 * handlers for a given form. Button-specific handlers are checked
 * first. If none exist, the function falls back to form-level handlers.
 *
 * @param $type
 *   The type of handler to execute. 'validate' or 'submit' are the
 *   defaults used by Form API.
 * @param $form
 *   An associative array containing the structure of the form.
 * @param $form_state
 *   A keyed array containing the current state of the form. If the user
 *   submitted the form by clicking a button with custom handler functions
 *   defined, those handlers will be stored here.
 */
function form_execute_handlers($type, &$form, &$form_state) {
  $return = FALSE;
962
  // If there was a button pressed, use its handlers.
963 964
  if (isset($form_state[$type . '_handlers'])) {
    $handlers = $form_state[$type . '_handlers'];
965
  }
966
  // Otherwise, check for a form-level handler.
967 968
  elseif (isset($form['#' . $type])) {
    $handlers = $form['#' . $type];
969 970 971 972 973 974
  }
  else {
    $handlers = array();
  }

  foreach ($handlers as $function) {
975
    if (function_exists($function))  {
976 977
      // Check to see if a previous _submit handler has set a batch, but
      // make sure we do not react to a batch that is already being processed
978
      // (for instance if a batch operation performs a drupal_form_submit()).
979
      if ($type == 'submit' && ($batch =& batch_get()) && !isset($batch['current_set'])) {
980 981 982
        // Some previous _submit handler has set a batch. We store the call
        // in a special 'control' batch set, for execution at the correct
        // time during the batch processing workflow.
983
        $batch['sets'][] = array('form_submit' => $function);
984 985
      }
      else {
986
        $function($form, $form_state);
987 988 989 990 991 992 993
      }
      $return = TRUE;
    }
  }
  return $return;
}

994
/**
995
 * Files an error against a form element.
996 997 998 999 1000 1001 1002 1003 1004
 *
 * @param $name
 *   The name of the form element. If the #parents property of your form
 *   element is array('foo', 'bar', 'baz') then you may set an error on 'foo'
 *   or 'foo][bar][baz'. Setting an error on 'foo' sets an error for every
 *   element where the #parents array starts with 'foo'.
 * @param $message
 *   The error message to present to the user.
 * @return
1005 1006
 *   Return value is for internal use only. To get a list of errors, use 
 *   form_get_errors() or form_get_error().
1007
 */
1008 1009
function form_set_error($name = NULL, $message = '') {
  $form = &drupal_static(__FUNCTION__, array());
1010 1011
  if (isset($name) && !isset($form[$name])) {
    $form[$name] = $message;
1012 1013 1014
    if ($message) {
      drupal_set_message($message, 'error');
    }
1015 1016 1017 1018
  }
  return $form;
}

1019 1020 1021 1022 1023 1024 1025
/**
 * Clear all errors against all form elements made by form_set_error().
 */
function form_clear_error() {
  drupal_static_reset('form_set_error');
}

1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
/**
 * Return an associative array of all errors.
 */
function form_get_errors() {
  $form = form_set_error();
  if (!empty($form)) {
    return $form;
  }
}

/**
 * Return the error message filed against the form with the specified name.
 */
function form_get_error($element) {
  $form = form_set_error();
  $key = $element['#parents'][0];
  if (isset($form[$key])) {
    return $form[$key];
  }
  $key = implode('][', $element['#parents']);
  if (isset($form[$key])) {
    return $form[$key];
  }
}

1051 1052 1053
/**
 * Flag an element as having an error.
 */
1054
function form_error(&$element, $message = '') {
1055
  form_set_error(implode('][', $element['#parents']), $message);
1056 1057 1058
}

/**
1059
 * Walk through the structured form array, adding any required
1060
 * properties to each element and mapping the incoming input
1061 1062
 * data to the proper elements. Also, execute any #process handlers
 * attached to a specific element.
1063 1064
 *
 * @param $form_id
1065 1066
 *   A unique string identifying the form for validation, submission,
 *   theming, and hook_form_alter functions.
1067 1068
 * @param $element
 *   An associative array containing the structure of the current element.
1069 1070 1071 1072 1073
 * @param $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.
1074
 */
1075
function form_builder($form_id, $element, &$form_state) {
1076
  // Initialize as unprocessed.
1077
  $element['#processed'] = FALSE;
1078

1079
  // Use element defaults.
1080
  if (isset($element['#type']) && ($info = element_info($element['#type']))) {
1081 1082 1083 1084
    // Overlay $info onto $element, retaining preexisting keys in $element.
    $element += $info;
    $element['#defaults_loaded'] = TRUE;
  }
1085 1086 1087 1088
  // Assign basic defaults common for all form elements.
  $element += array(
    '#required' => FALSE,
    '#attributes' => array(),
1089
    '#title_display' => 'before',
1090
  );
1091 1092 1093

  // Special handling if we're on the top level form element.
  if (isset($element['#type']) && $element['#type'] == 'form') {
1094
    if (!empty($element['#https']) && variable_get('https', FALSE) &&
1095
        !url_is_external($element['#action'])) {
1096 1097 1098 1099 1100 1101
      global $base_root;

      // Not an external URL so ensure that it is secure.
      $element['#action'] = str_replace('http://', 'https://', $base_root) . $element['#action'];
    }

1102 1103 1104 1105 1106 1107 1108 1109 1110 1111
    // 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;
1112
    }
1113 1114
  }

1115
  if (!isset($element['#id'])) {
1116
    $element['#id'] = drupal_html_id('edit-' . implode('-', $element['#parents']));
1117
  }
1118 1119 1120
  // Handle input elements.
  if (!empty($element['#input'])) {
    _form_builder_handle_input_element($form_id, $element, $form_state);
1121
  }
1122 1123
  // Allow for elements to expand to multiple elements, e.g., radios,
  // checkboxes and files.
1124 1125
  if (isset($element['#process']) && !$element['#processed']) {
    foreach ($element['#process'] as $process) {
1126
      if (function_exists($process)) {
1127
        $element = $process($element, $form_state, $form_state['complete form']);
1128 1129
      }
    }
1130
    $element['#processed'] = TRUE;
1131
  }
1132

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

1136
  // Recurse through all child elements.
1137
  $count = 0;
1138
  foreach (element_children($element) as $key) {
1139
    // Don't squash an existing tree value.
1140