summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/ajax.inc2
-rw-r--r--includes/batch.inc27
-rw-r--r--includes/common.inc17
-rw-r--r--includes/form.inc102
4 files changed, 85 insertions, 63 deletions
diff --git a/includes/ajax.inc b/includes/ajax.inc
index 478adf572..6bfd86d77 100644
--- a/includes/ajax.inc
+++ b/includes/ajax.inc
@@ -184,7 +184,7 @@ function ajax_get_form() {
}
// Since some of the submit handlers are run, redirects need to be disabled.
- $form['#redirect'] = FALSE;
+ $form_state['no_redirect'] = TRUE;
// The form needs to be processed; prepare for that by setting a few internal
// variables.
diff --git a/includes/batch.inc b/includes/batch.inc
index b136ac999..5fe876f9d 100644
--- a/includes/batch.inc
+++ b/includes/batch.inc
@@ -426,29 +426,24 @@ function _batch_finished() {
if ($_batch['progressive']) {
// Revert the 'destination' that was saved in batch_process().
if (isset($_batch['destination'])) {
- $_REQUEST['destination'] = $_batch['destination'];
+ $_GET['destination'] = $_batch['destination'];
}
// Determine the target path to redirect to.
- if (isset($_batch['form_state']['redirect'])) {
- $redirect = $_batch['form_state']['redirect'];
- }
- elseif (isset($_batch['redirect'])) {
- $redirect = $_batch['redirect'];
- }
- else {
- $redirect = $_batch['source_page'];
+ if (!isset($_batch['form_state']['redirect'])) {
+ if (isset($_batch['redirect'])) {
+ $_batch['form_state']['redirect'] = $_batch['redirect'];
+ }
+ else {
+ $_batch['form_state']['redirect'] = $_batch['source_page'];
+ }
}
// Use drupal_redirect_form() to handle the redirection logic.
- $form = isset($batch['form']) ? $batch['form'] : array();
- if (empty($_batch['form_state']['rebuild']) && empty($_batch['form_state']['storage'])) {
- drupal_redirect_form($form, $redirect);
- }
+ drupal_redirect_form($_batch['form_state']);
- // We get here if $form['#redirect'] was FALSE, or if the form is a
- // multi-step form. We save the final $form_state value to be retrieved
- // by drupal_get_form(), and redirect to the originating page.
+ // If no redirection happened, save the final $form_state value to be
+ // retrieved by drupal_get_form() and redirect to the originating page.
$_SESSION['batch_form_state'] = $_batch['form_state'];
drupal_goto($_batch['source_page']);
}
diff --git a/includes/common.inc b/includes/common.inc
index 2fee010a4..479d0952e 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -364,8 +364,8 @@ function drupal_query_string_encode($query, $exclude = array(), $parent = '') {
* @see drupal_goto()
*/
function drupal_get_destination() {
- if (isset($_REQUEST['destination'])) {
- return 'destination=' . urlencode($_REQUEST['destination']);
+ if (isset($_GET['destination'])) {
+ return 'destination=' . urlencode($_GET['destination']);
}
else {
// Use $_GET here to retrieve the original path in source form.
@@ -418,9 +418,8 @@ function drupal_get_destination() {
* @see drupal_get_destination()
*/
function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) {
-
- if (isset($_REQUEST['destination'])) {
- extract(parse_url(urldecode($_REQUEST['destination'])));
+ if (isset($_GET['destination'])) {
+ extract(parse_url(urldecode($_GET['destination'])));
}
$args = array(
@@ -471,8 +470,8 @@ function drupal_not_found() {
watchdog('page not found', check_plain($_GET['q']), NULL, WATCHDOG_WARNING);
// Keep old path for reference, and to allow forms to redirect to it.
- if (!isset($_REQUEST['destination'])) {
- $_REQUEST['destination'] = $_GET['q'];
+ if (!isset($_GET['destination'])) {
+ $_GET['destination'] = $_GET['q'];
}
$path = drupal_get_normal_path(variable_get('site_404', ''));
@@ -502,8 +501,8 @@ function drupal_access_denied() {
watchdog('access denied', check_plain($_GET['q']), NULL, WATCHDOG_WARNING);
// Keep old path for reference, and to allow forms to redirect to it.
- if (!isset($_REQUEST['destination'])) {
- $_REQUEST['destination'] = $_GET['q'];
+ if (!isset($_GET['destination'])) {
+ $_GET['destination'] = $_GET['q'];
}
$path = drupal_get_normal_path(variable_get('site_403', ''));
diff --git a/includes/form.inc b/includes/form.inc
index 30df84c54..d92e2a7ee 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -122,8 +122,13 @@ function drupal_get_form($form_id) {
* structure, which is passed on to the actual form builder function.
* Such forms cannot use drupal_get_form() and need to prepare $form_state
* on their own.
+ * Further $form_state properties controlling the redirection behavior after
+ * form submission may be found in drupal_redirect_form().
+ *
* @return
* The rendered form or NULL, depending upon the $form_state flags that were set.
+ *
+ * @see drupal_redirect_form()
*/
function drupal_build_form($form_id, &$form_state) {
// Ensure some defaults; if already set they will not be overridden.
@@ -503,6 +508,8 @@ function drupal_retrieve_form($form_id, &$form_state) {
}
/**
+ * Processes a form submission.
+ *
* This function is the heart of form API. The form gets built, validated and in
* appropriate cases, submitted.
*
@@ -579,20 +586,8 @@ function drupal_process_form($form_id, &$form, &$form_state) {
// Set a flag to indicate the the form has been processed and executed.
$form_state['executed'] = TRUE;
- // The form is executed. By default, we're finished now and redirect to a
- // new destination page. The path of the destination page can be set in
- // $form['#redirect'] or $form_state['redirect']. If neither of the two is
- // set, the user is redirect to the current page, which means a fresh,
- // unpopulated copy of the form.
- // Redirection is skipped, though, if
- // - the form was called by drupal_form_submit(),
- // - the form has to be rebuilt because either $form_state['rebuild'] was
- // set to TRUE or $form_state['storage'] was populated by a submit handler.
- // - $form_state['no_redirect'] is set to TRUE,
- // - $form_state['redirect'] or $form['#redirect'] is set to FALSE.
- if (!$form_state['programmed'] && empty($form_state['rebuild']) && empty($form_state['storage']) && empty($form_state['no_redirect'])) {
- drupal_redirect_form($form, $form_state['redirect']);
- }
+ // Redirect the form based on values in $form_state.
+ drupal_redirect_form($form_state);
}
}
}
@@ -732,33 +727,67 @@ function drupal_validate_form($form_id, $form, &$form_state) {
}
/**
- * Redirect the user to a URL after a form has been processed.
+ * 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().
+ * - If $form_state['rebuild'] is TRUE or $form_state['storage'] is populated,
+ * the form is most probably a multi-step form and needs to be rebuilt without
+ * redirection.
*
- * @param $form
- * An associative array containing the structure of the form.
- * @param $redirect
- * An optional value containing the destination path to redirect
- * to if none is specified by the form.
+ * @param $form_state
+ * A keyed array containing the current state of the form.
+ *
+ * @see drupal_process_form()
+ * @see drupal_build_form()
*/
-function drupal_redirect_form($form, $redirect = NULL) {
- $goto = NULL;
- if (isset($redirect)) {
- $goto = $redirect;
+function drupal_redirect_form($form_state) {
+ // Skip redirection for form submissions invoked via drupal_form_submit().
+ if (!empty($form_state['programmed'])) {
+ return;
}
- if ($goto !== FALSE && isset($form['#redirect'])) {
- $goto = $form['#redirect'];
+ // Skip redirection for multi-step forms.
+ if (!empty($form_state['rebuild']) || !empty($form_state['storage'])) {
+ return;
+ }
+ // Skip redirection if it was explicitly disallowed.
+ if (!empty($form_state['no_redirect'])) {
+ return;
}
- if (!isset($goto) || ($goto !== FALSE)) {
- if (isset($goto)) {
- if (is_array($goto)) {
- call_user_func_array('drupal_goto', $goto);
+ // 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']);
}
else {
// 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';
- $function($goto);
+ $function($form_state['redirect']);
}
}
drupal_goto($_GET['q']);
@@ -2922,12 +2951,11 @@ function batch_process($redirect = NULL, $url = NULL) {
$batch += $process_info;
if ($batch['progressive']) {
- // Clear the way for the drupal_goto redirection to the batch processing
- // page, by saving and unsetting the 'destination' if any, on both places
- // drupal_goto looks for it.
- if (isset($_REQUEST['destination'])) {
- $batch['destination'] = $_REQUEST['destination'];
- unset($_REQUEST['destination']);
+ // Clear the way for the drupal_goto() redirection to the batch processing
+ // page, by saving and unsetting the 'destination', if there is any.
+ if (isset($_GET['destination'])) {
+ $batch['destination'] = $_GET['destination'];
+ unset($_GET['destination']);
}
// Initiate db storage in order to get a batch id. We have to provide