Issues

ZF-2908: ZF 1.5 no longer auto detecting browser language

Description

In ZF 1.0.4 I have the following code, it successfully detects browser language setting and applies the translation and will downgrade through the list of languages the browser sends. Since upgrading to ZF 1.5 this no longer works and always returns the last language loaded (in my case Spanish!) even though the browser is set to en.


    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $browserLocale = new Zend_Locale(Zend_Locale::BROWSER);
        Zend_Registry::set('browserLocale', $browserLocale->__toString());
        setcookie('lang', $browserLocale->__toString(), null, '/');

        $config = Zend_Registry::get('config');

        $translate = new Zend_Translate("csv", "languages" . DS . "en" . DS . "lang.en", "en");

        if (!empty($config->languages->lang)) {
            foreach ($config->languages->lang as $lang) {
                $translate->addTranslation("languages" . DS . $lang . DS . "lang." . $lang, $lang);
            }
        }

        if ($translate->isAvailable($browserLocale->__toString())) {
            //Zend_Registry::get('logger')->info("Setting language to " . $browserLocale);
            $locale = substr($browserLocale->__toString(), 0, 2);
        } else {
            //Zend_Registry::get('logger')->info("Language " . $browserLocale . " not found downgrading to " . $translate->getLocale());
            $locale = substr($translate->getLocale(), 0, 2);
        }

        Zend_Registry::set('translate', $translate);
        Zend_Registry::set('locale', $locale);
    }

Comments

With your code you set all languages manually. This is the reason why it does not work for you. The settings of your browser are ignored.

You have eighter to use "browser" or "auto" as locale to use the browser settings.

Also instead of adding each languages manually it is better to have this done automatically.

  • locale "browser" for detecting browser locale
  • use directory or file search to get rid of the multiple adding a single file and setting always a new language within there
  • or use setLocale to set the wished locale

all mentioned points are stated in the manual, just take a look

I have made the suggested changes to my code. I know have:


public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
      $locale = new Zend_Locale();
      $translate = new Zend_Translate('csv', 'languages', 'browser', array('scan'=>Zend_Translate::LOCALE_DIRECTORY));
      $translate->setLocale('browser');
     Zend_Registry::set('Zend_Translate', $translate);

If I don't use $translate->setLocale('browser'); it seems to display the values of the last language file loaded.

A couple of things to note:

1) My language files are stored like so:


languages
  -->en
    -->lang.en
  -->de
    -->lang.de
  -->fr
    -->lang.fr
etc.

2) If I set my browser to e.g. Cambodian(km) I will only see messageIds in my view. How do I get this to default or downgrade to English. In 1.0.4 using the addTranslation it use to downgrade through the available languages sent by the browser i.e. if I had km -> es -> en in my list it would display English.

Also, Zend_Translate is not available Zend_View_Helper_MyHelper via $this->translate, I get an undefined method. The docs seem to say that you can use $this->translate in helpers as long as you store $translate in the registry key Zend_Translate which I have done. $this->translate is available in script views i.e. index.phtml.

Sorry to be a pain!

Zend_Locale recognises the locale "browser"...

Zend_Translate does only recognise the "auto" locale which includes the "browser" locale. If you use "auto" then you do not need to set the locale afterwards... "auto" is also described in the manual for Zend_Translate.

As you can see by your structure you could also use search by filename as you have the locale present in it.

Related to "km"... of course... actually Zend_Translate is not able to do rerouting. There is a own issue for this improvement and this is no bug but an improvement. Actually you can do this manually by existing methods. See getList()... it returns all languages... you could then do an array_key_exists BUT you can not do this per message. And also your code is wrong in this case. When you have "fr" for example but only half of all strings translated also your code would not work !!! This is where the other issue comes in.

Related to Zend_View_Helper_MyHelper... this is not a failure from Zend_Translate... you should ask in the mailinglist as this is not an issue but a question of proper handling. And no you can not use it in "helpers" but in the view... you can use view helper in the view and not view helpers in other view helpers. Please ask in the mailinglist for the exact handling.

Many thanks for taking the time to respond, I really appreciate it. Off to the mailing lists I go :-)

All the best!

I'm assuming this fix is merged to the 1.5 release branch for release with 1.5.1. Please update JIRA if this is not the case.