Your IP : 172.28.240.42


Current Path : /var/www/html/clients/td-teplouchet.ru/old/sites/all/modules/globalredirect/
Upload File :
Current File : /var/www/html/clients/td-teplouchet.ru/old/sites/all/modules/globalredirect/globalredirect.module

<?php

/**
 * @file
 * The Global Redirect module redirects for all paths which have aliases but
 * are not using the aliases which reduces the risk of duplicate content.
 */

/**
 * Implements hook_help().
 */
function globalredirect_help($path, $arg) {
  switch ($path) {
    case 'admin/help#globalredirect':
      return t('This module will do a 301 redirect for all nodes which have an alias but are not using that alias.');
  }
}

/**
 * Implements hook_init().
 */
function globalredirect_init() {
  global $language;

  /**
   * 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;
    }
  }

  // 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']);
  }

  // Get the query string parameters. If none set, set to NULL
  $query_string = drupal_get_query_parameters();
  if (empty($query_string)) {
    $query_string = NULL;
  }

  // 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,
  );

  // 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\/([0-9]+)$/', $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 Content Translation module is enabled then check the path is correct.
  if ($settings['language_redirect'] && module_exists('translation') && preg_match('/node\/([0-9]+)(\/.+|)$/', $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);
        }
        // If there is no translation, change the language to fit the content
        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
    if (str_replace($prefix . $alias, '', $request_path) != '/' || $settings['deslash']) {
      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);
  }

  // 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)));
  }
}

/**
 * A wrapper for drupal_goto() that does not pass through if $path is an
 * external URL.
 */
function globalredirect_goto($path = '', array $options = array(), $http_response_code = 301) {
  if (!globalredirect_url_is_external($path)) {
    return drupal_goto($path, $options, $http_response_code);
  }
}

/**
 * Check if a path is external (e.g. http://example.com).
 *
 * This is a simple copy of url_is_external() which if given an URL with an
 * invalid protocal will return FALSE, an undesired value. This function will
 * return TRUE given an URL with an invalid protocol.
 */
function globalredirect_url_is_external($path) {
  $colonpos = strpos($path, ':');
  return $colonpos !== FALSE && !preg_match('![/?#]!', drupal_substr($path, 0, $colonpos));
}

/**
 * Implements hook_menu().
 */
function globalredirect_menu() {
  $items['admin/config/system/globalredirect'] = array(
    'title' => 'Global Redirect',
    'description' => 'Chose which features you would like enabled for Global Redirect',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('globalredirect_settings'),
    'access arguments' => array('administer site configuration'),
    'file' => 'globalredirect.admin.inc',
  );

  return $items;
}

/**
 * Internal function to determine if GlobalRedirect is active.
 * Several rules have to be checked prior to execution, such as an empty post array,
 * the site must be online and we cannot be running in CLI mode (eg Drush).
 */
function _globalredirect_is_active($settings) {
  /**
   * We need to do a test to make sure we only clean up URL's for the main
   * request. This stops modules such as the Ad Module which had its own script
   * in its folder doing a bootstrap which invoked hook_init() and caused some
   * banners to get "cleaned up"
   *
   * @see http://drupal.org/node/205810
   * @see http://drupal.org/node/278615
   */
  if ($_SERVER['SCRIPT_NAME'] != $GLOBALS['base_path'] . 'index.php') {
    return FALSE;
  }

  /**
   * If this is a command line request (Drush, etc), skip processing.
   */
  if (drupal_is_cli()) {
    return FALSE;
  }

  /**
   * If the site is in offline mode there is little point doing any of this as
   * you might end up redirecting to a 503.
   */
  if (variable_get('site_offline', 0) == 1) {
    return FALSE;
  }

  /**
   * If there is something posted, GlobalRedirect is not active
   */
  if (!empty($_POST)) {
    return FALSE;
  }

  /**
   * If drupal_get_path_alias isn't preset, GlobalRedirect is not active
   */
  if (!function_exists('drupal_get_path_alias')) {
    return FALSE;
  }

  /**
   * If menu_check is enabled AND the menu_get_item function is missing,
   * GlobalRedirect is disabled.
   */
  if ($settings['menu_check'] && !function_exists('menu_get_item')) {
    return FALSE;
  }

  /**
   * If we're going to ignore the admin path, return false.
   * This is added to allow people to continue to get to the 'admin*' paths,
   * even if the module is misbehaving.
   */
  if ($settings['ignore_admin_path'] && (arg(0) == 'admin' || arg(0) == 'batch')) {
    return FALSE;
  }

  /**
   * We seem to have passed all the tests - let say we're active
   */
  return TRUE;
}

/**
 * Return the settings with any defaults mapped over the top
 */
function _globalredirect_get_settings($default_only = FALSE) {
  $defaults = array(
    'deslash' => 1,
    'nonclean_to_clean' => 1,
    'trailing_zero' => 0,
    'menu_check' => 0,
    'case_sensitive_urls' => 1,
    'language_redirect' => 0,
    'canonical' => 0,
    'content_location_header' => 0,
    'term_path_handler' => 1,
    'frontpage_redirect' => 1,
    'ignore_admin_path' => 1,
  );

  if ($default_only) {
    return $defaults;
  }

  return variable_get('globalredirect_settings', array()) + $defaults;
}


/**
 * globalredirect_request_path() is borrowed from request_uri(), but it only ltrim's..
 */
function globalredirect_request_path() {
  if (request_uri()) {
    if (isset($_REQUEST['q'])) {
      $path = $_REQUEST['q'];
    }
    else {
      // This is a request using a clean URL. Extract the path from REQUEST_URI.
      $request_path = strtok(request_uri(), '?');
      $base_path_len = drupal_strlen(rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/'));
      // Unescape and strip $base_path prefix, leaving q without a leading slash.
      $path = drupal_substr(urldecode($request_path), $base_path_len + 1);
    }
  }
  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 = ltrim($path, '/');

  return $path;
}