From 1f50d1d6fe01db1d6fbe40be774f4300ae8624fa Mon Sep 17 00:00:00 2001
From: Ian Thomas <ian.thomas@tuidev.com>
Date: Wed, 20 Nov 2013 13:24:14 +0000
Subject: [PATCH] Add support for tokens in redirect_url

---
 includes/webform.pages.inc |  2 +-
 webform.module             | 77 +++++++++++++++++++++++++++++++++++++---------
 2 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/includes/webform.pages.inc b/includes/webform.pages.inc
index bfa0a38..23e76a3 100644
--- a/includes/webform.pages.inc
+++ b/includes/webform.pages.inc
@@ -64,7 +64,7 @@ function webform_configure_form($form, &$form_state, $node) {
     '#type' => 'item',
     '#title' => t('Redirection location'),
     '#theme' => 'webform_advanced_redirection_form',
-    '#description' => t('Choose where to redirect the user upon successful submission.') . ' ' . t('The <em>Custom URL</em> option supports Webform token replacements.') . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
+    '#description' => t('Choose where to redirect the user upon successful submission.') . ' ' . t('The <em>Custom URL</em> option supports token replacements for query string values.') . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
   );
   $form['submission']['redirection']['redirect']= array(
     '#type' => 'radios',
diff --git a/webform.module b/webform.module
index 9e30e9b..156e121 100644
--- a/webform.module
+++ b/webform.module
@@ -3023,13 +3023,6 @@ function webform_client_form_submit($form, &$form_state) {
   $confirmation = strlen(trim(strip_tags($node->webform['confirmation']))) ? $node->webform['confirmation'] : '';
   $confirmation = webform_replace_tokens($confirmation, $node, $submission, NULL, TRUE);
 
-  // Clean up the redirect URL and filter it for webform tokens.
-  $redirect_url = trim($node->webform['redirect_url']);
-  $redirect_url = webform_replace_tokens($redirect_url, $node, $submission);
-
-  // Remove the domain name from the redirect.
-  $redirect_url = preg_replace('/^' . preg_quote($GLOBALS['base_url'], '/') . '\//', '', $redirect_url);
-
   // Check confirmation and redirect_url fields.
   $message = NULL;
   $redirect = NULL;
@@ -3043,22 +3036,32 @@ function webform_client_form_submit($form, &$form_state) {
   elseif (!empty($form_state['values']['details']['finished'])) {
     $message = t('Submission updated.');
   }
-  elseif ($redirect_url == '<none>') {
+  elseif ($node->webform['redirect_url'] == '<none>') {
     $redirect = NULL;
   }
-  elseif ($redirect_url == '<confirmation>') {
+  elseif ($node->webform['redirect_url'] == '<confirmation>') {
     $query = array('sid' => $sid);
     if ((int) $user->uid === 0) {
       $query['token'] = md5($submission->submitted . $submission->sid . drupal_get_private_key());
     }
     $redirect = array('node/' . $node->nid . '/done', array('query' => $query));
   }
-  elseif (valid_url($redirect_url, TRUE)) {
-    $redirect = $redirect_url;
-    $external_url = TRUE;
-  }
-  elseif ($redirect_url && strpos($redirect_url, 'http') !== 0) {
-    $redirect = $redirect_url;
+  else {
+    // Clean up the redirect URL, filter it for tokens and remove the domain name.
+    $redirect_url = trim($node->webform['redirect_url']);
+    $redirect_url = webform_replace_query_string_tokens($redirect_url, $node, $submission);
+    $redirect_url = preg_replace('/^' . preg_quote($GLOBALS['base_url'], '/') . '\//', '', $redirect_url);
+
+    // $redirect_url is an absolute, external URL
+    if (valid_url($redirect_url, TRUE)) {
+      $redirect = $redirect_url;
+      $external_url = TRUE;
+    }
+    elseif ($redirect_url && strpos($redirect_url, 'http') !== 0) {
+      // Pass URL as an array so we support a query string and/or fragment.
+      $parsed_url = drupal_parse_url($redirect_url);
+      $redirect = array('path' => $parsed_url['path'], $parsed_url);
+    }
   }
 
   // Show a message if manually set.
@@ -3537,6 +3540,50 @@ function webform_replace_tokens($string, $node = NULL, $submission = NULL, $emai
 }
 
 /**
+ * Replace tokens entered as query string values in a URL.
+ *
+ * @param string $redirect_url
+ *   The redirect URL, with everything other than tokens already url encoded.
+ * @param $node
+ *   If replacing node-level tokens, the node for which tokens will be created.
+ * @param $submission
+ *   If replacing submission-level tokens, the submission for which tokens will
+ *   be created.
+ * @param $email
+ *   If replacing tokens within the context of an e-mail, the Webform e-mail
+ *   settings array.
+ * @param $sanitize
+ *   Boolean value indicating if the results will be displayed as HTML output.
+ *   This will be passed to token_replace(). If FALSE, the contents returned
+ *   will be unsanitized. This will also result in all Webform submission tokens
+ *   being returned as plain-text, without HTML markup, in preparation for
+ *   e-mailing or other text-only purposes (default values, etc.)
+ * @return string
+ *   The parsed and url encoded URL
+ */
+function webform_replace_query_string_tokens($redirect_url, $node = NULL, $submission = NULL, $email = NULL, $sanitize = FALSE) {
+  $token_data = array();
+  if ($node) {
+    $token_data['node'] = $node;
+  }
+  if ($submission) {
+    $token_data['webform-submission'] = $submission;
+  }
+  if ($email) {
+    $token_data['webform-email'] = $email;
+  }
+
+  $parsed_redirect_url = drupal_parse_url($redirect_url);
+  if (!empty($parsed_redirect_url['query'])) {
+    foreach ($parsed_redirect_url['query'] as $key => $value) {
+      $parsed_redirect_url['query'][$key] = token_replace($value, $token_data, array('clear' => true, 'sanitize' => $sanitize));
+    }
+    $redirect_url = url($parsed_redirect_url['path'], $parsed_redirect_url);
+  }
+  return $redirect_url;
+}
+
+/**
  * Replace tokens in descriptions and sanitize according to Webform settings.
  */
 function webform_filter_descriptions($string, $node = NULL, $submission = NULL) {
-- 
1.7.11.msysgit.0

