Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1013
diff -u -r1.1013 common.inc
--- includes/common.inc	11 Oct 2009 06:05:53 -0000	1.1013
+++ includes/common.inc	13 Oct 2009 00:02:37 -0000
@@ -620,41 +620,57 @@
  * Drupal will ensure that messages set by drupal_set_message() and other
  * session data are written to the database before the user is redirected.
  *
- * This function ends the request; use it instead of a return in your menu callback.
+ * This function ends the request; use it instead of a return in your menu
+ * callback.
  *
  * @param $path
  *   A Drupal path or a full URL.
- * @param $query
- *   A query string component, if any.
- * @param $fragment
- *   A destination fragment identifier (named anchor).
- * @param $http_response_code
- *   Valid values for an actual "goto" as per RFC 2616 section 10.3 are:
- *   - 301 Moved Permanently (the recommended value for most redirects)
- *   - 302 Found (default in Drupal and PHP, sometimes used for spamming search
- *         engines)
- *   - 303 See Other
- *   - 304 Not Modified
- *   - 305 Use Proxy
- *   - 307 Temporary Redirect (alternative to "503 Site Down for Maintenance")
- *   Note: Other values are defined by RFC 2616, but are rarely used and poorly
- *   supported.
+ * @param $options
+ *   An associative array of additional options, with the following keys:
+ *     'query'
+ *       A query string to append to the link, or an array of query key/value
+ *       properties.
+ *     'fragment'
+ *       A fragment identifier (named anchor) to append to the link.
+ *       Do not include the '#' character.
+ *     'http_response_code' (default 302)
+ *       Valid values for an actual "goto" as per RFC 2616 section 10.3 are:
+ *       - 301 Moved Permanently (the recommended value for most redirects)
+ *       - 302 Found (default in Drupal and PHP, sometimes used for spamming
+ *             search engines)
+ *       - 303 See Other
+ *       - 304 Not Modified
+ *       - 305 Use Proxy
+ *       - 307 Temporary Redirect (alternative to "503 Site Down for
+ *             Maintenance")
+ *       Note: Other values are defined by RFC 2616, but are rarely used and
+ *       poorly supported.
  * @see drupal_get_destination()
  */
-function drupal_goto($path = '', array $query = array(), $fragment = NULL, $http_response_code = 302) {
+function drupal_goto($path = '', $options = array()) {
+  // Merge in default values without overwrite.
+  $options += array(
+    'query' => array(),
+    'fragment' => NULL,
+    'http_response_code' => 302,
+    'absolute' => TRUE,
+  );
+
   if (isset($_GET['destination'])) {
-    extract(drupal_parse_url(urldecode($_GET['destination'])));
+    // Pull in the information from $_GET and override the function arguments.
+    $destination = drupal_parse_url(urldecode($_GET['destination']));
+    $path = $destination['path'];
+    $options['query'] = $destination['query'];
+    $options['fragment'] = $destination['fragment'];
   }
 
-  $args = array(
-    'path' => &$path,
-    'query' => &$query,
-    'fragment' => &$fragment,
-    'http_response_code' => &$http_response_code,
-  );
+  // The $args array is only used so that $path and $options can be directly
+  // altered by reference without a PHP error.
+  $args = array('path' => &$path, 'options' => &$options);
+
   drupal_alter('drupal_goto', $args);
 
-  $url = url($path, array('query' => $query, 'fragment' => $fragment, 'absolute' => TRUE));
+  $url = url($path, $options);
 
   // Allow modules to react to the end of the page request before redirecting.
   // We do not want this while running update.php.
@@ -666,7 +682,7 @@
   // database before redirecting.
   drupal_session_commit();
 
-  header('Location: ' . $url, TRUE, $http_response_code);
+  header('Location: ' . $url, TRUE, $options['http_response_code']);
 
   // The "Location" header sends a redirect status code to the HTTP daemon. In
   // some cases this can be wrong, so we make sure none of the code below the
