Not entirely sure what exactly is the issue, here, but in my installation, I encounter the following problem.

Every one of my content pages has an English and a Dutch version, and I'm using pathauto.

Let's say the English version of my 'Home'-page's clean url is "/home", while the actual url is "/node/23".

The Dutch version sits at "/nl/home", its actual url being "/node/22".

Logically, the redirect would happen to "/nl/home", but instead, "/nl/node/23" is returned, a url that probably shouldn't actually exist, but displays the English content instead of the Dutch content.

Am I just doing this wrong?

Comments

Gabriel R.’s picture

I had this before using ip2locale. I sure hope there is a clean solution.

paulhudson’s picture

Version: 6.x-1.x-dev » 6.x-1.0-beta1
Component: Miscellaneous » Code
Category: support » bug
Priority: Normal » Major
Status: Active » Needs review

Hi,

Among other things:

I think drupal_get_path_alias() required the path of the translation node not the current node - therefore we get the correct alias as they are probably different???

Also, $prefix seems to normally have a value so I needed to add an elseif to the switch... not sure I understand the logic here...

Here's the modified function:

/**
 * Implementation of hook_boot().
 */
function ip2locale_boot() {

  /**
   * If the site is in offline 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 (variable_get('ip2locale_redirect_mode', IP2LOCALE_FIRST_REQUEST_ONLY) == IP2LOCALE_FIRST_REQUEST_ONLY) {
    /**
     * We only want to act if the user comes to the page from an external site/direct hit
     */
    if (strpos($_SERVER['HTTP_REFERER'], $_SERVER['SERVER_NAME'])) return FALSE;
  }
  
  // Load in supporting code.
  // This is needed so that module_load_include can be used (this is used in some of the backends).
  require_once './includes/common.inc'; 
  
  // Attempt to register backends
  drupal_load('module', 'geoip');
  drupal_load('module', 'ip2cc');
  drupal_load('module', 'uc_ip2country');
	drupal_load('module', 'translation');
	drupal_load('module', 'node');
  
  // Get the users language code from their session if it exists
  if ((variable_get('ip2locale_debug', FALSE) && $_GET['ip2locale_debug']) || !$_SESSION['ip2locale_lc']) {
    // Work out the the users language code based on their IP address.
    $ip = ip2locale_ip_address();
    $lc = $_SESSION['ip2locale_lc'] = ip2locale_get_locale($ip);
  }
  else {
    $lc = $_SESSION['ip2locale_lc'];
  }
	
  /**
   * Couldn't work out the users country so we bail.
   */
  if (!$lc) return FALSE;
  
  drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH); // load in the code required to deal with paths properly
  drupal_bootstrap(DRUPAL_BOOTSTRAP_LANGUAGE); // load in the code required to deal with languages
  
  // get the current language
  global $language;

  // Get the Query String (minus the 'q'). If none set, set to NULL
  $query_string = drupal_query_string_encode($_GET, array('q'));
  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('prefix' => '');
  if (function_exists('language_url_rewrite')) {
    // Note that language_url_rewrite() takes path (by reference) as the first argument but does not use it at all
    $path = $_REQUEST['q'];
    language_url_rewrite($path, $options);

  }
  $prefix = rtrim($options['prefix'], '/');
  
	
  // Find an alias (if any) for the request
	// 1. get avalible translation nid's
	// 2. load the appropriate translation node alias for drupal_goto 
	
	$tnid = arg(1);
	
	$translations = translation_node_get_translations($tnid);

	if ($translations){
		$alias = drupal_get_path_alias('node/'.$translations[$lc]->nid, $lc);
	} else {
		$alias = drupal_get_path_alias($_GET['q'], $language->language);
	}

	if ($prefix && $alias) {
		$prefix .= '/';

	}

	
  // redirect the user to a language specific version if
  // 1. the country code maps to an enabled language
  // 2. the country code is not the active language
  // 3. the user has not asked for a specific, prefixed version of a page
  $languages = language_list('enabled');
  
  foreach ($languages[1] as $lang) {
    
    switch (variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE)) {
      case LANGUAGE_NEGOTIATION_DOMAIN:
        if (($lc == $lang->language) && ($language->language != $lc) && !$prefix) {
          $redirect = $lang->domain? $lang->domain .'/'. $alias : $alias;
					
        } elseif (($lc == $lang->language) && ($language->language != $lc) && $prefix) {
          $redirect = $lang->domain? $lang->domain .'/'. $alias : $alias;
        }
        break;
				
      default:
        if (($lc == $lang->language) && ($language->language != $lc) && !$prefix) {
          $redirect = $lang->prefix? $lang->prefix .'/'. $alias : $alias;
					
        } elseif (($lc == $lang->language) && ($language->language != $lc) && $prefix) {
          $redirect = $lang->prefix? $lang->prefix .'/'. $alias : $alias;
        }
    }

    if ($redirect) {

      if (variable_get('ip2locale_debug', FALSE)) {
        drupal_set_message('IP to Locale debug... Redirecting to: '. $redirect);
      }
      drupal_load('module', 'filter'); // this is needed to use drupal_goto, since it uses url() which requires access to filter_xss_bad_protocol()
      drupal_goto($redirect, $query_string, NULL, 303);
    }
  }
}

Please play around with this... I'm not using it on a production site so not fully testing it. Let me know if there's something stupid with the code and I'll try to sort it.

Paul

m.sant’s picture

Version: 6.x-1.0-beta1 » 6.x-1.x-dev
Status: Needs review » Needs work

I tried the proposed changes but it didn't work.

With the last development version I get the following error messages:
Notice: Undefined index: q in .../sites/all/modules/ip2locale/ip2locale.module on line 211
Notice: Undefined variable: redirect in .../sites/all/modules/ip2locale/ip2locale.module on line 251

I have the same behaviour also if I disable the clean urls.

Regards,
Marco

mrfelton’s picture

Status: Needs work » Fixed

Please try with the latest code in git.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.