summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2006-07-22 19:26:58 +0000
committerDries Buytaert <dries@buytaert.net>2006-07-22 19:26:58 +0000
commit69b484f634d861e401d520c17a253f8c4d13a790 (patch)
tree5f12ef9bb18806539684593d31ab229c2d2d267e
parent0c05ae7a030e5c944417ee715b638c9e0c456bd8 (diff)
downloadbrdo-69b484f634d861e401d520c17a253f8c4d13a790.tar.gz
brdo-69b484f634d861e401d520c17a253f8c4d13a790.tar.bz2
- Patch #74660 by Eaton: make drupal_get_form() more granular and improved the code comments.
-rw-r--r--includes/form.inc186
1 files changed, 137 insertions, 49 deletions
diff --git a/includes/form.inc b/includes/form.inc
index bf027bca3..9aae8e49a 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -69,6 +69,39 @@ function drupal_get_form($form_id, &$form, $callback = NULL) {
$form_submitted = FALSE;
$form_button_counter = array(0, 0);
+ $form = drupal_build_form($form_id, $form, $callback);
+
+ if (!empty($_POST['edit']) && (($_POST['edit']['form_id'] == $form_id) || ($_POST['edit']['form_id'] == $callback))) {
+ drupal_validate_form($form_id, $form, $callback);
+ // IE does not send a button value when there is only one submit button (and no non-submit buttons)
+ // and you submit by pressing enter.
+ // In that case we accept a submission without button values.
+ if (($form_submitted || (!$form_button_counter[0] && $form_button_counter[1])) && !form_get_errors()) {
+ $redirect = drupal_submit_form($form_id, $form, $callback);
+ drupal_redirect_form($form, $redirect);
+ }
+ }
+
+ $output = drupal_render_form($form_id, $form, $callback);
+ list($form_values, $form_submitted, $form_button_counter) = array_pop($saved_globals);
+ return $output;
+}
+
+/**
+ * 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.
+ * @param $callback
+ * An optional callback that will be used in addition to the form_id.
+ *
+ */
+function drupal_build_form($form_id, &$form, $callback = NULL) {
$form['#type'] = 'form';
if (isset($form['#token'])) {
// If the page cache is on and an anonymous user issues a GET request,
@@ -86,6 +119,7 @@ function drupal_get_form($form_id, &$form, $callback = NULL) {
$form['form_token'] = array('#type' => 'hidden', '#default_value' => md5(session_id() . $form['#token'] . variable_get('drupal_private_key', '')));
}
}
+
if (isset($form_id)) {
$form['form_id'] = array('#type' => 'hidden', '#value' => $form_id, '#id' => str_replace('_', '-', "edit-$form_id"));
}
@@ -121,57 +155,24 @@ function drupal_get_form($form_id, &$form, $callback = NULL) {
}
$form = form_builder($form_id, $form);
- if (!empty($_POST['edit']) && (($_POST['edit']['form_id'] == $form_id) || ($_POST['edit']['form_id'] == $callback))) {
- drupal_validate_form($form_id, $form, $callback);
- // IE does not send a button value when there is only one submit button (and no non-submit buttons)
- // and you submit by pressing enter.
- // In that case we accept a submission without button values.
- if (($form_submitted || (!$form_button_counter[0] && $form_button_counter[1])) && !form_get_errors()) {
- $redirect = drupal_submit_form($form_id, $form, $callback);
- if (isset($redirect)) {
- $goto = $redirect;
- }
- if (isset($form['#redirect'])) {
- $goto = $form['#redirect'];
- }
- if ($goto !== FALSE) {
- if (is_array($goto)) {
- call_user_func_array('drupal_goto', $goto);
- }
- elseif (!isset($goto)) {
- drupal_goto($_GET['q']);
- }
- else {
- drupal_goto($goto);
- }
- }
- }
- }
-
- // Don't override #theme if someone already set it.
- if (!isset($form['#theme'])) {
- if (theme_get_function($form_id)) {
- $form['#theme'] = $form_id;
- }
- elseif (theme_get_function($callback)) {
- $form['#theme'] = $callback;
- }
- }
-
- if (isset($form['#pre_render'])) {
- foreach ($form['#pre_render'] as $function) {
- if (function_exists($function)) {
- $function($form_id, $form);
- }
- }
- }
- $output = form_render($form);
- // Restore globals
- list($form_values, $form_submitted, $form_button_counter) = array_pop($saved_globals);
- return $output;
+ return $form;
}
+
+/**
+ * Validates user-submitted form data from a global variable using
+ * 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
+ * An associative array containing the structure of the form.
+ * @param $callback
+ * An optional callback that will be used in addition to the form_id.
+ *
+ */
function drupal_validate_form($form_id, $form, $callback = NULL) {
global $form_values;
static $validated_forms = array();
@@ -180,6 +181,8 @@ function drupal_validate_form($form_id, $form, $callback = NULL) {
return;
}
+ // If the session token was set by drupal_build_form(), ensure that it
+ // matches the current user's session
if (isset($form['#token'])) {
if ($form_values['form_token'] != md5(session_id() . $form['#token'] . variable_get('drupal_private_key', ''))) {
// setting this error will cause the form to fail validation
@@ -191,6 +194,22 @@ function drupal_validate_form($form_id, $form, $callback = NULL) {
$validated_forms[$form_id] = TRUE;
}
+/**
+ * Processes user-submitted form data from a global variable using
+ * the submit 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
+ * An associative array containing the structure of the form.
+ * @param $callback
+ * An optional callback that will be used in addition to the form_id.
+ * @return
+ * A string containing the path of the page to display when processing
+ * is complete.
+ *
+ */
function drupal_submit_form($form_id, $form, $callback = NULL) {
global $form_values;
$default_args = array($form_id, &$form_values);
@@ -210,6 +229,74 @@ function drupal_submit_form($form_id, $form, $callback = NULL) {
return $goto;
}
+/**
+ * Renders a structured form array into themed HTML.
+ *
+ * @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.
+ * @param $callback
+ * An optional callback that will be used in addition to the form_id.
+ * @return
+ * A string containing the path of the page to display when processing
+ * is complete.
+ *
+ */
+function drupal_render_form($form_id, &$form, $callback = NULL) {
+ // Don't override #theme if someone already set it.
+ if (!isset($form['#theme'])) {
+ if (theme_get_function($form_id)) {
+ $form['#theme'] = $form_id;
+ }
+ elseif (theme_get_function($callback)) {
+ $form['#theme'] = $callback;
+ }
+ }
+
+ if (isset($form['#pre_render'])) {
+ foreach ($form['#pre_render'] as $function) {
+ if (function_exists($function)) {
+ $function($form_id, $form);
+ }
+ }
+ }
+
+ $output = form_render($form);
+ return $output;
+}
+
+/**
+ * Redirect the user to a URL after a form has been processed.
+ *
+ * @param $form
+ * An associative array containing the structure of the form.
+ * @param $redirect
+ * An optional string containing the destination path to redirect
+ * to if none is specified by the form.
+ *
+ */
+function drupal_redirect_form($form, $redirect = NULL) {
+ if (isset($redirect)) {
+ $goto = $redirect;
+ }
+ if (isset($form['#redirect'])) {
+ $goto = $form['#redirect'];
+ }
+ if ($goto !== FALSE) {
+ if (is_array($goto)) {
+ call_user_func_array('drupal_goto', $goto);
+ }
+ elseif (!isset($goto)) {
+ drupal_goto($_GET['q']);
+ }
+ else {
+ drupal_goto($goto);
+ }
+ }
+}
+
function _form_validate($elements, $form_id = NULL) {
// Recurse through all children.
foreach (element_children($elements) as $key) {
@@ -324,7 +411,8 @@ function form_error(&$element, $message = '') {
* already have an assigned value.
*
* @param $form_id
- * A unique string identifying the form. Allows each form to be themed.
+ * 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.
*/