Set language/currency by geoip help

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
9 years ago
I need to automatically set the users language/currency based on their location. Ive been playing with nop default behaviour plus a few modifications but nothing seems to work correctly.

Ive been using the "Automatically detect language: " feature in the general/common config section.
Ive then used advice from https://www.nopcommerce.com/boards/t/20157/change-the-language-and-the-currency-at-the-same-time.aspx to automatically set the currency based on the language.

i.e.
public ActionResult SetLanguage(int langid, string returnUrl = "")
{
  var language = _languageService.GetLanguageById(langid);
  if (language != null && language.Published)
  {
      _workContext.WorkingLanguage = language;
  }
etc....

1. Even though language is being set, currency isnt. My language is being set as GB, but currency remain as US $ (default). IF I then manually chnage language it correctly sets currency.
This leads me to beleive that "public ActionResult SetLanguage" is not fired within the logic used to "Automatically detect language:".
Where is this logic?


2. "Automatically detect language: " by users browser settings rather than IP
Im a little surprised NOP uses this method, because users (including myself) are notorious for leaving it as the default US.
Isnt it much better to do this via IP?

I can see from posts like https://www.nopcommerce.com/boards/t/23221/change-language-by-visitor-ip.aspx that NOP has geocoding abilities so what is the reason for  not using this method?

Finally https://www.nopcommerce.com/boards/t/23221/change-language-by-visitor-ip.aspx is a little incomplete, does anyone with an understanding of the architechure have advice on how best to implement automatic language/currency setting based on IP?

Note it needs to:
1. Initially auto detect based on location
2. Still allow the user to manually select by changing thr flags.

Any help much appreciated

Thanks
John
9 years ago
For anyone interested this seems to work.

\trunk\Presentation\Nop.Web.Framework\WebWorkContext.cs

/// <summary>
/// Get or set current user working currency
/// </summary>
public virtual Currency WorkingCurrency
{
    get
    {
  if (_cachedCurrency != null)
      return _cachedCurrency;
  
  //return primary store currency when we're in admin area/mode
  if (this.IsAdmin)
  {
      var primaryStoreCurrency =  _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId);
      if (primaryStoreCurrency != null)
    return primaryStoreCurrency;
  }

  // # CUSTOM ###############
  // Set currency based on working language
  Currency currency = null;
  Language language = null;
  
  // Get language from cache, or working context
  language = _cachedLanguage ?? EngineContext.Current.Resolve<IWorkContext>().WorkingLanguage;

  // Check we got one
  if (language != null)
  {
      var currencyId = 1;
      // Hard code currencies based on language, we can DB later if we need to
      switch (language.Id)
      {
    case 1: // US
        currencyId = 1;
        break;
    case 2: // GB
        currencyId = 3;
        break;
    case 3: // AU
        currencyId = 2;
        break;
      }

      // Get currwncy
      currency = _currencyService.GetCurrencyById(currencyId);
  }
  // Default to standard NOP behaviour if language still null
  else
  {
      var allCurrencies = _currencyService.GetAllCurrencies(storeId: _storeContext.CurrentStore.Id);
      //find current customer language
      var currencyId = this.CurrentCustomer.GetAttribute<int>(SystemCustomerAttributeNames.CurrencyId,
    _genericAttributeService, _storeContext.CurrentStore.Id);
      currency = allCurrencies.FirstOrDefault(x => x.Id == currencyId);
      if (currency == null)
      {
    //it not specified, then return the first (filtered by current store) found one
    currency = allCurrencies.FirstOrDefault();
      }
      if (currency == null)
      {
    //it not specified, then return the first found one
    currency = _currencyService.GetAllCurrencies().FirstOrDefault();
      }
  }
  // # END CUSTOM ###############

  //cache
  _cachedCurrency = currency;
  return _cachedCurrency;
    }
    set
    {
  var currencyId = value != null ? value.Id : 0;
  _genericAttributeService.SaveAttribute(this.CurrentCustomer,
      SystemCustomerAttributeNames.CurrencyId,
      currencyId, _storeContext.CurrentStore.Id);

  //reset cache
  _cachedCurrency = null;
    }
}
9 years ago
I should clarify the above code sets currency based on language.

In terms of setting language based on IP rather than browser setting the same file is the place to start.
In "public virtual Language WorkingLanguage" we have "detectedLanguage = GetLanguageFromBrowserSettings();" so presumably we would override this with our geoip function.

I'll have a play with this and update if seems useful.
7 years ago
The above solution depends on browser language setting(i.e. User side setting). I am not sure but default browser language setting (United States - English) and many people won't change it. So this won't work in country like India.

Is there any other solution?
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.