You are here

function purl_goto in Persistent URL 6

Same name and namespace in other branches
  1. 7 purl.module \purl_goto()

An alternative implementation of drupal_goto() that allows PURL modifiers to be added or removed from the destination URL. You provide a drupal path ('node/43') and a persistent url modifier (provider/id pair) and purl_goto will determine the correct location to use. The 'disable' flag may also be used to drop any purl modifiers from the redirect.

The code below is nearly identical to drupal_goto(), except that it passes an $options array to url().

File

./purl.module, line 630

Code

function purl_goto($path = '', $options = array(), $http_response_code = 302) {
  $options = !is_array($options) ? array() : $options;
  $options['absolute'] = TRUE;
  if (isset($_REQUEST['destination'])) {
    extract(parse_url(urldecode($_REQUEST['destination'])));
  }
  else {
    if (isset($_REQUEST['edit']['destination'])) {
      extract(parse_url(urldecode($_REQUEST['edit']['destination'])));
    }
  }
  $url = url($path, $options);

  // purl_goto() EJECTOR:
  //
  // Under certain circumstances, (e.g. a modifier being stale or deleted from
  // the DB), purl_goto() can be left hanging in an infinite redirect loop. We
  // can detect this by comparing the current URL with a rewritten URL. If they
  // are identical, we are entering a loop.
  if (isset($options['purl'])) {
    $current_url = url($_GET['q'], array(
      'absolute' => TRUE,
      'query' => drupal_query_string_encode($_GET, array(
        'q',
      )),
    ));
    if ($url == $current_url) {
      watchdog('purl', 'Infinite redirect prevented.', array(), WATCHDOG_INFO);
      return;
    }
  }

  // Remove newlines from the URL to avoid header injection attacks.
  $url = str_replace(array(
    "\n",
    "\r",
  ), '', $url);

  // Allow modules to react to the end of the page request before redirecting.
  // We do not want this while running update.php.
  if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
    module_invoke_all('exit', $url);
  }

  // Even though session_write_close() is registered as a shutdown function, we
  // need all session data written to the database before redirecting.
  session_write_close();
  header('Location: ' . $url, TRUE, $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
  // drupal_goto() call gets executed upon redirection.
  exit;
}