domain_301_redirect.module in Domain 301 Redirect 7
Same filename and directory in other branches
This module allows you to 301 redirect all domains to one specific domain.
File
domain_301_redirect.moduleView source
<?php
/**
* @file
* This module allows you to 301 redirect all domains to one specific domain.
*/
/**
* Implements hook_help().
*/
function domain_301_redirect_help($path, $arg) {
switch ($path) {
case 'admin/config/search/domain_301_redirect':
case 'admin/help#domain_301_redirect':
return t('The Domain 301 Redirect module allows sites to 301 redirect to a domain that is marked as the main domain. This means you can have all subdomains and other domains 301 redirect to a domain that you choose as the main domain. This provides great SEO benefit.');
}
}
/**
* Implements hook_menu().
*/
function domain_301_redirect_menu() {
$items = array();
$items['admin/config/search/domain_301_redirect'] = array(
'title' => 'Domain 301 Redirect',
'description' => 'Manage domain 301 redirection.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'domain_301_redirect_admin_form',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer site configuration',
),
'file' => 'domain_301_redirect.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items['domain_301_redirect_check'] = array(
'title' => 'Domain 301 Redirect Check',
'description' => 'Checks that the main domain listed actually points to the same site.',
'page callback' => 'domain_301_redirect_check',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implements hook_permission().
*/
function domain_301_redirect_permission() {
return array(
'bypass domain 301 redirect' => array(
'title' => t('Bypass domain 301 redirect'),
'description' => t('If this permission is set, the user will not be 301 redirected if the domain does not match the main domain.'),
),
);
}
/**
* Implements hook_init().
*/
function domain_301_redirect_init() {
// Don't redirect when using drush
if (!drupal_is_cli()) {
$domain_301_redirect_enabled = variable_get('domain_301_redirect_enabled', FALSE);
$domain_301_redirect_domain = variable_get('domain_301_redirect_domain', '');
// If redirection is enabled and a redirect domain is configured, proceed.
if ($domain_301_redirect_enabled && !empty($domain_301_redirect_domain)) {
if (!preg_match('|^https?://|', $domain_301_redirect_domain)) {
$domain_301_redirect_domain = 'http://' . $domain_301_redirect_domain;
}
$domain_parts = parse_url($domain_301_redirect_domain);
$parsed_domain = $domain_parts['host'];
$parsed_domain .= !empty($domain_parts['port']) ? ':' . $domain_parts['port'] : '';
// If we're not on the same host, the user has access and this page isn't
// an exception, redirect.
if ($parsed_domain != $_SERVER['HTTP_HOST'] && !user_access('bypass domain 301 redirect') && domain_301_redirect_may_redirect() && !domain_301_redirect_global_exclude()) {
drupal_goto($domain_301_redirect_domain . request_uri(), array(), 301);
}
}
}
}
/**
* Determines if a page is configured to redirect.
*
* Uses logic copied from block.module to handle either all pages except those
* listed or all pages listed.
*/
function domain_301_redirect_may_redirect() {
$applicability = (int) variable_get('domain_301_redirect_applicability');
if ($pages = trim((string) variable_get('domain_301_redirect_pages'))) {
// Convert path to lowercase. This allows comparison of the same path
// with different case. Ex: /Page, /page, /PAGE.
$pages = drupal_strtolower($pages);
// Convert the Drupal path to lowercase and get the aliased version of it.
$current_path = drupal_strtolower(current_path());
$aliased_path = drupal_strtolower(drupal_get_path_alias($current_path));
// Compare the lowercase internal and lowercase path alias (if any).
$page_match = drupal_match_path($aliased_path, $pages);
if ($aliased_path != $current_path) {
$page_match = $page_match || drupal_match_path($current_path, $pages);
}
// When $applicability has a value of 0 (BLOCK_VISIBILITY_NOTLISTED),
// the redirect is applied on all pages except those listed in $pages.
// When set to 1 (BLOCK_VISIBILITY_LISTED), it is applied only on those
// pages listed in $pages.
$page_match = !($applicability xor $page_match);
}
elseif ($applicability == BLOCK_VISIBILITY_LISTED) {
$page_match = FALSE;
}
else {
$page_match = TRUE;
}
return $page_match;
}
/**
* Checks if the current path has been globally excluded from redirects.
*
* @return bool
* TRUE if excluded, otherwise FALSE.
*/
function domain_301_redirect_global_exclude() {
$cid = 'domain_301_redirect:global_exclude';
if ($cache = cache_get($cid)) {
$exclusions = $cache->data;
}
else {
$exclusions = module_invoke_all('domain_301_redirect_exclude');
drupal_alter('domain_301_redirect_exclude', $exclusions);
// We need these as a \n-separated string for drupal_match_path.
$exclusions = drupal_strtolower(implode("\n", array_map('trim', $exclusions)));
cache_set($cid, $exclusions);
}
// Convert the Drupal path to lowercase and get the aliased version of it.
$current_path = drupal_strtolower(current_path());
$aliased_path = drupal_strtolower(drupal_get_path_alias($current_path));
// Compare the lowercase internal and lowercase path alias (if any).
$page_match = drupal_match_path($aliased_path, $exclusions);
if ($aliased_path != $current_path) {
$page_match = $page_match || drupal_match_path($current_path, $exclusions);
}
return $page_match;
}
/**
* Implements hook_cron().
*/
function domain_301_redirect_cron() {
$check_period = variable_get('domain_301_redirect_check_period', 60 * 60 * 3);
$last_checked = variable_get('domain_301_redirect_last_checked', 0);
$enabled = variable_get('domain_301_redirect_enabled', FALSE);
$reenable = variable_get('domain_301_redirect_check_reenable', TRUE);
$disabled_by_check = variable_get('domain_301_redirect_disabled_by_check', FALSE);
// If the redirect is enabled (or has been previously disabled) and we are
// checking for domain availability on cron, then attempt to request the test
// url using the redirect domain.
if (($enabled || $disabled_by_check && $reenable) && !empty($check_period) && $last_checked < time() - $check_period) {
$domain = variable_get('domain_301_redirect_domain', '');
if (!preg_match('|^https?://|', $domain)) {
$domain = 'http://' . $domain;
}
$domain_parts = parse_url($domain);
$domain = $domain_parts['scheme'] . '://' . $domain_parts['host'];
if (!domain_301_redirect_check_domain($domain)) {
variable_set('domain_301_redirect_enabled', 0);
variable_set('domain_301_redirect_disabled_by_check', TRUE);
watchdog('Domain 301 Redirect', 'The domain %domain no longer points to this site. Domain 301 redirection was disabled.', array(
'%domain' => $domain,
), WATCHDOG_ERROR);
}
else {
watchdog('Domain 301 Redirect', 'Domain 301 redirect check passed.');
// If the redirect was disabled by cron, and it has now passed, re-enable it.
if (!$enabled && $reenable && $disabled_by_check) {
variable_set('domain_301_redirect_enabled', 1);
variable_set('domain_301_redirect_disabled_by_check', FALSE);
watchdog('Domain 301 Redirect', 'The domain %domain has become available again. Domain 301 redirection was re-enabled.', array(
'%domain' => $domain,
), WATCHDOG_ERROR);
}
}
variable_set('domain_301_redirect_last_checked', time());
}
}
/**
* Checks if a domain actually points to this site.
*
* @param string $domain
* The domain to be checked.
*
* @return bool
* Returns TRUE if the domain passes the check. FALSE otherwise.
*/
function domain_301_redirect_check_domain($domain) {
if (!empty($domain)) {
$retries = variable_get('domain_301_redirect_domain_check_retries', 3);
// Try to contact the redirect domain, if this fails, retry N times after a pause.
for ($i = 1; $i <= $retries; $i++) {
$time = time();
$hash = drupal_hmac_base64('domain_301_redirect_check_domain', $time . drupal_get_private_key() . drupal_get_hash_salt());
$result = drupal_http_request($domain . '/domain_301_redirect_check/' . $time);
if (!empty($result) && $result->data == $hash) {
return TRUE;
}
elseif ($i < $retries) {
// Pause between retries.
sleep(10);
}
}
}
return FALSE;
}
/**
* Menu callback item domain_301_redirect_check().
*
* This callback prints out a validation hash string and then terminates the
* script.
*/
function domain_301_redirect_check($time = NULL) {
global $conf;
$conf['cache'] = FALSE;
echo $time && time() - $time < 60 ? drupal_hmac_base64('domain_301_redirect_check_domain', $time . drupal_get_private_key() . drupal_get_hash_salt()) : '';
exit;
}
Functions
Name | Description |
---|---|
domain_301_redirect_check | Menu callback item domain_301_redirect_check(). |
domain_301_redirect_check_domain | Checks if a domain actually points to this site. |
domain_301_redirect_cron | Implements hook_cron(). |
domain_301_redirect_global_exclude | Checks if the current path has been globally excluded from redirects. |
domain_301_redirect_help | Implements hook_help(). |
domain_301_redirect_init | Implements hook_init(). |
domain_301_redirect_may_redirect | Determines if a page is configured to redirect. |
domain_301_redirect_menu | Implements hook_menu(). |
domain_301_redirect_permission | Implements hook_permission(). |