You are here

context_redirect.module in Context Redirect 6

Same filename and directory in other branches
  1. 7 context_redirect.module

Provides a context reaction that redirects the user.

File

context_redirect.module
View source
<?php

/**
 * @file
 * Provides a context reaction that redirects the user.
 */

/**
 * Implements hook_ctools_plugin_api().
 */
function context_redirect_ctools_plugin_api($module, $api) {
  if ($module == 'context' && $api == 'plugins') {
    return array(
      'version' => 3,
    );
  }
}

/**
 * Implements hook_context_plugins().
 */
function context_redirect_context_plugins() {
  $plugins = array();
  $plugins['context_redirect_reaction'] = array(
    'handler' => array(
      'path' => drupal_get_path('module', 'context_redirect'),
      'file' => 'context_redirect_reaction.inc',
      'class' => 'context_redirect_reaction',
      'parent' => 'context_reaction',
    ),
  );
  return $plugins;
}

/**
 * Implements hook_context_registry().
 */
function context_redirect_context_registry() {
  $registry['reactions'] = array(
    'context_redirect' => array(
      'title' => t('Context redirect'),
      'plugin' => 'context_redirect_reaction',
    ),
  );
  return $registry;
}

/**
 * Implements hook_context_page_reaction().
 */
function context_redirect_context_page_reaction() {
  if ($plugin = context_get_plugin('reaction', 'context_redirect')) {
    $plugin
      ->execute();
  }
}

/**
 * Backports of Drupal core utility functions.
 */

/**
 * Backport of drupal_valid_path() from Drupal 7.
 */
function context_redirect_valid_path($path) {
  global $menu_admin;

  // We indicate that a menu administrator is running the menu access check.
  $menu_admin = TRUE;
  if ($path == '<front>' || context_redirect_url_is_external($path)) {
    $item = array(
      'access' => TRUE,
    );
  }
  elseif ($dynamic_allowed && preg_match('/\\/\\%/', $path)) {

    // Path is dynamic (ie 'user/%'), so check directly against menu_router
    // table.
    if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(
      ':path' => $path,
    ))
      ->fetchAssoc()) {
      $item['link_path'] = $form_item['link_path'];
      $item['link_title'] = $form_item['link_title'];
      $item['external'] = FALSE;
      $item['options'] = '';
      _menu_link_translate($item);
    }
  }
  else {
    $item = menu_get_item($path);
  }
  $menu_admin = FALSE;
  return $item && $item['access'];
}

/**
 * Backport of request_path() from Drupal 7.
 */
function context_redirect_request_path() {
  static $path;
  if (isset($path)) {
    return $path;
  }
  if (isset($_GET['q']) && is_string($_GET['q'])) {

    // This is a request with a ?q=foo/bar query string. $_GET['q'] is
    // overwritten in drupal_path_initialize(), but request_path() is called
    // very early in the bootstrap process, so the original value is saved in
    // $path and returned in later calls.
    $path = $_GET['q'];
  }
  elseif (isset($_SERVER['REQUEST_URI'])) {

    // This request is either a clean URL, or 'index.php', or nonsense.
    // Extract the path from REQUEST_URI.
    $request_path = strtok($_SERVER['REQUEST_URI'], '?');
    $base_path_len = strlen(rtrim(dirname($_SERVER['SCRIPT_NAME']), '\\/'));

    // Unescape and strip $base_path prefix, leaving q without a leading slash.
    $path = substr(urldecode($request_path), $base_path_len + 1);

    // If the path equals the script filename, either because 'index.php' was
    // explicitly provided in the URL, or because the server added it to
    // $_SERVER['REQUEST_URI'] even when it wasn't provided in the URL (some
    // versions of Microsoft IIS do this), the front page should be served.
    if ($path == basename($_SERVER['PHP_SELF'])) {
      $path = '';
    }
  }
  else {

    // This is the front page.
    $path = '';
  }

  // Under certain conditions Apache's RewriteRule directive prepends the value
  // assigned to $_GET['q'] with a slash. Moreover we can always have a trailing
  // slash in place, hence we need to normalize $_GET['q'].
  $path = trim($path, '/');
  return $path;
}

/**
 * Backport of url_is_external() from Drupal 7.
 */
function context_redirect_url_is_external($path) {
  $colonpos = strpos($path, ':');

  // Avoid calling drupal_strip_dangerous_protocols() if there is any
  // slash (/), hash (#) or question_mark (?) before the colon (:)
  // occurrence - if any - as this would clearly mean it is not a URL.
  return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && context_redirect_strip_dangerous_protocols($path) == $path;
}

/**
 * Backport of drupal_get_query_parameters() from Drupal 7.
 */
function context_redirect_get_query_parameters(array $query = NULL, array $exclude = array(
  'q',
), $parent = '') {

  // Set defaults, if none given.
  if (!isset($query)) {
    $query = $_GET;
  }

  // If $exclude is empty, there is nothing to filter.
  if (empty($exclude)) {
    return $query;
  }
  elseif (!$parent) {
    $exclude = array_flip($exclude);
  }
  $params = array();
  foreach ($query as $key => $value) {
    $string_key = $parent ? $parent . '[' . $key . ']' : $key;
    if (isset($exclude[$string_key])) {
      continue;
    }
    if (is_array($value)) {
      $params[$key] = context_redirect_get_query_parameters($value, $exclude, $string_key);
    }
    else {
      $params[$key] = $value;
    }
  }
  return $params;
}

/**
 * Backport of drupal_strip_dangerous_protocols() from Drupal 7.
 */
function context_redirect_strip_dangerous_protocols($uri) {
  static $allowed_protocols;
  if (!isset($allowed_protocols)) {
    $allowed_protocols = array_flip(variable_get('filter_allowed_protocols', array(
      'ftp',
      'http',
      'https',
      'irc',
      'mailto',
      'news',
      'nntp',
      'rtsp',
      'sftp',
      'ssh',
      'tel',
      'telnet',
      'webcal',
    )));
  }

  // Iteratively remove any invalid protocol found.
  do {
    $before = $uri;
    $colonpos = strpos($uri, ':');
    if ($colonpos > 0) {

      // We found a colon, possibly a protocol. Verify.
      $protocol = substr($uri, 0, $colonpos);

      // If a colon is preceded by a slash, question mark or hash, it cannot
      // possibly be part of the URL scheme. This must be a relative URL, which
      // inherits the (safe) protocol of the base document.
      if (preg_match('![/?#]!', $protocol)) {
        break;
      }

      // Check if this is a disallowed protocol. Per RFC2616, section 3.2.3
      // (URI Comparison) scheme comparison must be case-insensitive.
      if (!isset($allowed_protocols[strtolower($protocol)])) {
        $uri = substr($uri, $colonpos + 1);
      }
    }
  } while ($before != $uri);
  return $uri;
}

/**
 * Backport of _external_url_is_local() from Drupal 8.
 */
function context_redirect_external_url_is_local($url) {
  $url_parts = parse_url($url);
  $base_host = parse_url($GLOBALS['base_url'], PHP_URL_HOST);

  // When comparing base paths, we need a trailing slash to make sure a
  // partial URL match isn't occuring. Since base_path() always returns with
  // a trailing slash, we don't need to add the trailing slash here.
  return $url_parts['host'] == $base_host && stripos($url_parts['path'], base_path()) === 0;
}

Functions

Namesort descending Description
context_redirect_context_page_reaction Implements hook_context_page_reaction().
context_redirect_context_plugins Implements hook_context_plugins().
context_redirect_context_registry Implements hook_context_registry().
context_redirect_ctools_plugin_api Implements hook_ctools_plugin_api().
context_redirect_external_url_is_local Backport of _external_url_is_local() from Drupal 8.
context_redirect_get_query_parameters Backport of drupal_get_query_parameters() from Drupal 7.
context_redirect_request_path Backport of request_path() from Drupal 7.
context_redirect_strip_dangerous_protocols Backport of drupal_strip_dangerous_protocols() from Drupal 7.
context_redirect_url_is_external Backport of url_is_external() from Drupal 7.
context_redirect_valid_path Backport of drupal_valid_path() from Drupal 7.