function globalredirect_init in Global Redirect 7
Same name and namespace in other branches
- 5 globalredirect.module \globalredirect_init()
- 6 globalredirect.module \globalredirect_init()
Implements hook_init().
File
- ./
globalredirect.module, line 22 - The Global Redirect module redirects for all paths which have aliases but are not using the aliases which reduces the risk of duplicate content.
Code
function globalredirect_init() {
global $language;
require_once DRUPAL_ROOT . '/includes/locale.inc';
/**
* Get the settings.
*/
$settings = _globalredirect_get_settings();
// If GlobalRedirect is inactive (for any of the reasons listed in
// _globalredirect_is_active()) then skip the rest of the function.
if (!_globalredirect_is_active($settings)) {
return FALSE;
}
// If menu checking is enabled, do the check. Note: Feature disabled by default.
if ($settings['menu_check']) {
// Check the access on the current path, return FALSE if access not
// allowed. This stops redirection for paths without access permission.
$item = menu_get_item();
if (!$item['access']) {
return FALSE;
}
}
// Get the query string parameters. If none set, set to NULL.
$query_string = drupal_get_query_parameters();
if (empty($query_string)) {
$query_string = NULL;
}
// Store the destination from the $_GET as, if we leave it in, drupal_goto()
// will go to that instead.
if (isset($_GET['destination'])) {
$destination = $_GET['destination'];
unset($_GET['destination']);
}
// Establish the language prefix that should be used, ie. the one that
// drupal_goto() would use
$options = array(
'fragment' => '',
'query' => $query_string,
'absolute' => FALSE,
'alias' => FALSE,
'prefix' => '',
'external' => FALSE,
'globalredirect' => TRUE,
);
// Get the request path. We cannot use request_path() as it uses a completely trimmed path.
// We need just left trimmed.
$request_path = globalredirect_request_path();
// Allow Drupal to rewrite the URL
// Most commonly this will be used to invoke locale_language_url_rewrite_url().
// Via the locale_url_outbound_alter() implementation of hook_url_outbound_alter().
// NOTE: We use $request_path here as current_path() is $_GET['q'] which gets
// altered by core, whereas $request_path is untouched
drupal_alter('url_outbound', $request_path, $options, $request_path);
// Extract the prefix from the options.
$prefix = rtrim($options['prefix'], '/');
// Do a check if this is a front page
if (drupal_is_front_page()) {
// If frontpage redirection is disabled, halt here
if (!$settings['frontpage_redirect']) {
return;
}
// Redirect if the current request does not refer to the front page in the
// configured fashion (with or without a prefix)
if ($request_path != $prefix) {
drupal_goto('', $options, 301);
}
elseif ($settings['nonclean_to_clean'] && (bool) variable_get('clean_url', 0) && (strpos(request_uri(), '?q=') || strpos(request_uri(), 'index.php'))) {
drupal_goto('', $options, 301);
}
// If we've got to this point then we're on a front page with a VALID
// request path (such as a language-prefix front page such as '/de')
return;
}
// Get the current page - it's already "deslashed"
$current_path = current_path();
// Optional stripping of "/0". Disabled by default.
switch ($settings['trailing_zero']) {
case 2:
// If 'taxonomy/term/*' only. If not, break out.
if (drupal_substr($current_path, 0, 14) != 'taxonomy/term/') {
break;
}
// If it is, fall through to general trailing zero method
case 1:
// If last 2 characters of URL are /0 then trim them off
if (drupal_substr($current_path, -2) == '/0') {
$current_path = drupal_substr($current_path, 0, -2);
}
}
// If the feature is enabled, check and redirect taxonomy/term/* requests to their proper handler defined by hook_term_path().
if ($settings['term_path_handler'] && module_exists('taxonomy') && preg_match('`^taxonomy/term/(\\d+)$`', $current_path, $matches)) {
// So the feature is enabled, as is taxonomy module and the current request is a taxonomy term page.
// NOTE: This will only match taxonomy term pages WITHOUT a depth modifier
$term = taxonomy_term_load($matches[1]);
// Get the term path for this term (handler is defined in the vocab table under module). If it differs from the request, then redirect.
if (!empty($term) && ($term_path = entity_uri('taxonomy_term', $term)) && $term_path['path'] != $current_path) {
$current_path = $term_path['path'];
if (isset($options['query'])) {
$options['query'] = array_merge($options['query'], $term_path['options']['query']);
}
elseif (isset($term_path['options']['query'])) {
$options['query'] = $term_path['options']['query'];
}
}
}
// If Content Translation module is enabled then check the path is correct.
if ($settings['language_redirect'] && module_exists('translation') && preg_match('/node\\/([0-9]+)(\\/view|)$/', $current_path, $matches)) {
switch (variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX)) {
case LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX:
// Check if there's a translation for the current language of the requested node...
// $matches[0] is the entire matches path from above
$node_translations = translation_path_get_translations($matches[0]);
// If there is, go to the translation.
if (!empty($node_translations[$language->language]) && $node_translations[$language->language] != $matches[0]) {
globalredirect_goto($node_translations[$language->language], $options);
}
else {
$node = node_load($matches[1]);
// Check the node has a language set, that it isn't "NONE" (und) and that it dosn't match the site's current language
if (isset($node->language) && $node->language != LANGUAGE_NONE && $node->language != $language->language) {
$all_languages = language_list();
// TODO: Is it possible to get here with a node in a language not in $all_languages?
// Change the global $language's prefix, to make drupal_goto()
// follow the proper prefix
$options['language'] = $language = $all_languages[$node->language];
globalredirect_goto('node/' . $node->nid . $matches[2], $options);
}
}
break;
case LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN:
// Let's check is there other languages on site.
$all_languages = language_list();
if (count($all_languages) > 1) {
foreach ($all_languages as $l => $lang) {
// Only test for languages other than the current one.
if ($lang->language != $language->language) {
$alias = drupal_get_path_alias($current_path, $lang->language);
// There is a matching language for this alias
if ($alias != $current_path) {
if (isset($lang->domain)) {
drupal_goto($lang->domain . '/' . $alias, $options, 301);
}
break;
}
}
}
}
break;
}
}
// Find an alias (if any) for the request
$langcode = isset($options['language']->language) ? $options['language']->language : '';
$alias = drupal_get_path_alias($current_path, $langcode);
// Modules may alter outbound links by reference
drupal_alter('url_outbound', $alias, $options, $current_path);
// If we have a prefix AND an alias, we need to make sure the prefix end with
// a slash
if ($prefix && $alias) {
$prefix .= '/';
}
// Alias case sensitivity check.
// NOTE: This has changed. In D6 the $alias matched the request (in terms of
// case). However in D7 $alias is already a true alias (accurate in case),
// and therefore not the "true" request. So, if the alias and the request
// path are case-insensitive the same then, if case sensitive URL's are
// enabled, the alias SHOULD be the accurate $alias from above, otherwise it
// should be the request_path().
// TODO: Test if this breaks the language checking above!
if (strcasecmp($alias, request_path()) == 0) {
// The alias and the request are identical (case insensitive)... Therefore...
$alias = $settings['case_sensitive_urls'] ? $alias : request_path();
}
// Compare the request to the alias. This also works as a 'deslashing'
// agent. If we have a language prefix then prefix the alias
if ($request_path != $prefix . $alias) {
// If it's not just a slash or user has deslash on, redirect, but avoid
// redirecting to a directory if we are only deslashing, as apache mod_dir
// can cause an infinite loop.
if (str_replace($prefix . $alias, '', $request_path) != '/' || $settings['deslash'] && !is_dir($alias)) {
globalredirect_goto($alias, $options);
}
}
// If no alias was returned, the final check is to direct non-clean to
// clean - if clean is enabled
if ($settings['nonclean_to_clean'] && (bool) variable_get('clean_url', 0) && strpos(request_uri(), '?q=')) {
globalredirect_goto($current_path, $options);
}
// If on a comment path, try to redirect to the associate node
if ($settings['comment_to_node'] && module_exists('comment') && preg_match('/comment\\/(?P<cid>[0-9]+)$/', $current_path, $matches)) {
$cid = $matches['cid'];
// Code "borrowed" from comment_permalink($cid)
if (($comment = comment_load($cid)) && ($node = node_load($comment->nid))) {
// Find the current display page for this comment.
$page = comment_get_display_page($comment->cid, $node->type);
// If it's more than 0, set the query string parameter
// TODO - maintain other params?!
if ($page > 0) {
$options['query']['page'] = $page;
}
// Add the fragment to the comment anchor
$options['fragment'] = 'comment-' . $comment->cid;
// Redirect to the node, with the comment querystring/fragment.
globalredirect_goto('node/' . $node->nid, $options);
}
}
// Restore the destination from earlier so its available in other places.
if (isset($destination)) {
$_GET['destination'] = $destination;
}
// Add the canonical link to the head of the document if desired.
// TODO - The Canonical already gets set by Core for node page views... See http://api.drupal.org/api/function/node_page_view/7
if ($settings['canonical']) {
drupal_add_html_head_link(array(
'rel' => 'canonical',
'href' => url(drupal_is_front_page() ? '<front>' : $request_path, array(
'absolute' => TRUE,
'query' => $query_string,
)),
));
}
// Add the Content-Location header to the page
if ($settings['content_location_header']) {
drupal_add_http_header('Content-Location', url(drupal_is_front_page() ? '<front>' : $request_path, array(
'absolute' => TRUE,
'query' => $query_string,
)));
}
}