Issues

ZF-5863: Setting default locale does not work

Issue Type: Bug Created: 2009-02-23T05:55:08.000+0000 Last Updated: 2009-02-25T03:35:17.000+0000 Status: Resolved Fix version(s): - 1.7.6 (02/Mar/09)

Reporter: Ashley Kitson (akzincdig) Assignee: Thomas Weidner (thomas) Tags: - Zend_Locale

Related issues: Attachments:

Description

According to the documentation (example 29.9) we should be able to set an override for the locale. The following code will not work as expected;

if (intval($appCfg->overideLocale) == 1) { $l = new Zend_Locale($appCfg->locale); Zend_Registry::set('Zend_Locale', $l); } else { Zend_Locale::setDefault($appCfg->locale); } $l2 = new Zend_Locale(); Zend_Debug::dump($l2);

If I set my browser (firefox) to use 'fr' but set $appCfg->locale = 'en' and $appCfg->overideLocale = 1 I would expect $l2 to be 'en', but it isn't . It is 'fr'

If I step through Zend_Locale::_prepareLocale() the following lines at line 878 in ZF 1.7.2:

        if (is_array($locale) === true) {
            $locale = key($locale);
        }

will return 'fr' for the call to $l2 = new Zend_Locale(); because the locale array has 'fr' as the highest 'quality' i.e 1, where as 'en' although first in the array has a quality of 0.7. Nowhere is the Zend_Registry interrogated for a default locale value.

I have placed this code before any use of Zend_locale is made in the rest of the application.

Am I missing something or is this a real bug?

Regards

Comments

Posted by Thomas Weidner (thomas) on 2009-02-23T13:47:01.000+0000

I am sure the component works as defined. Can you give HTTP_ACCEPT_LANGUAGE for the cases and the result/taken locale ?

To note: According to manual the default locale is used when no known locale can be found.

Also to note: Locales are not taken according to their position, but according to their quality, which is defined from 1 to be best and 0.1 to be least.

Posted by Ashley Kitson (akzincdig) on 2009-02-23T23:48:13.000+0000

Thomas

HTTP_ACCEPT_LANGUAGE = fr,en;q=0.7,en-us;q=0.3

Section 29.1.8 of the manual says "Zend Framework allows the usage of an application wide locale. You simply set an instance of Zend_Locale to the registry with the key 'Zend_Locale'. Then this instance will be used within all locale aware classes of Zend Framework. This way you set one locale within your registry and then you can forget about setting it again. It will automatically be used in all other classes. See the below example for the right usage: "

It then gives the example, from which my code is based.

I understand the point about locales being taken according to their quality. My point is that the predefined locale set into the registry is never taken into account. If I hack Zend_Locale and put in

if ($locale === null &&Zend_Registry::isRegistered('Zend_Locale')) { $locale = Zend_Registry::get('Zend_Locale')->toString(); }

at about line 855 in _prepareLocale() then I get the expected result, i.e the value set in the registry.

I don't think this is a complete answer because I'm not sure that Zend_Translate is always getting its locale from the same place. The point is, I need to be able to force the application to use the locale I set irrespective of any browser set locale and that isn't working. It is far too tedious to go through the entire codebase and set the locale every time I use Zend_Date, Zend_Translate etc etc.

Posted by Thomas Weidner (thomas) on 2009-02-24T00:01:56.000+0000

You said that you set "fr" for your browser... from your returned HTTP* I see that you've set "fr", "en" and "en_US" to be accepted. In your case the used locale could be "fr" or "en".

Only when your user requests another locale like "hu", the default locale would come in place. The manual clearly states this: The last sentence of the default locale chapter reads: {quote}In the case that no locale can be detected, automatically the locale de will be used. Otherwise, the detected locale will be used.{quote}

To your second point: {quote}The point is, I need to be able to force the application to use the locale I set irrespective of any browser set locale and that isn't working.{quote} It is...

Reading the manual: {quote}Zend Framework allows the usage of an application wide locale. You simply set an instance of Zend_Locale to the registry with the key 'Zend_Locale'. Then this instance will be used within all locale aware classes of Zend Framework. This way you set one locale within your registry and then you can forget about setting it again. It will automatically be used in all other classes.{quote}

A application wide locale has nothing to do with a default fallback locale.

Posted by Ashley Kitson (akzincdig) on 2009-02-24T00:34:29.000+0000

I would humbly submit that the application wide locale I am setting is NOT being used by all other classes.

I have translation strings in my application for English and French. In this particular situation, I never want the French translation being used, only the English ones. i.e the site must be mono-lingual. However, if I set an application wide locale as discussed above, the system will still pick up the browser set locale (fr in this example) and translate into that language. That is not in my opinion using an application wide locale, but falling back to a default if translations are not available for the browser locale.

I do understand the difference between application wide locale and a default fallback locale. Zend uses Zend_Locale::setDefault() to set the default fallback locale. That is not what I am trying to do in this particular case.

Currently the only way I can see of getting around this problem is to remove all the French translation strings and set a default fallback locale.

Posted by Thomas Weidner (thomas) on 2009-02-24T01:18:15.000+0000

You are speaking of problems with Zend_Locale, but in your above text you note that you have problems with translation.

In no one of your example I can see how you are using Zend_Translate.

Looking at Zend_Translate you will note that in several lines it calls

<pre class="highlight">
to get the locale to use.

And the first lines within this method read:



    if ($locale === null) {
        require_once 'Zend/Registry.php';
        if (Zend_Registry::isRegistered('Zend_Locale')) {
            $locale = Zend_Registry::get('Zend_Locale');
        }
    }

Only when the registry is not set, it degrades to the detection routines.

{quote}I do understand the difference between application wide locale and a default fallback locale. Zend uses Zend\_Locale::setDefault() to set the default fallback locale. That is not what I am trying to do in this particular case.{quote}

Why are you then discussing this point when you know that this not the problem in your case as it's not used ? ;-)

{quote}Currently the only way I can see of getting around this problem is to remove all the French translation strings and set a default fallback locale.{quote}

Use application wide locale as described within the manual. Check if the registry is really set to the expected value within the bootstrap or, if it's not available when calling Zend\_Translate.

 

 

Posted by Thomas Weidner (thomas) on 2009-02-24T01:20:21.000+0000

Degrading priority from Critical to Major as this is a user handling problem and not a bug for the next release.

 

 

Posted by Ashley Kitson (akzincdig) on 2009-02-24T01:45:38.000+0000

Thomas

I didn't look in Zend\_Translate because I took for granted that when the manual says that Zend\_Locale is used by _all_ locale aware parts of ZF I was expecting it to do just that. Silly me :-)

And findLocale() doesn't exist in Zend\_Locale (or indeed anywhere), at least not in the V1.7.2 library I am using. So which version are you talking about?

Zend\_Locale::\_prepareLocale() doesn't check the registry either.

 

 

Posted by Thomas Weidner (thomas) on 2009-02-24T04:34:24.000+0000

{quote}I didn't look in Zend\_Translate because I took for granted that when the manual says that Zend\_Locale is used by all locale aware parts of ZF I was expecting it to do just that.{quote}

It is. But when you have problems with Zend\_Translate you should look at Zend\_Translate and not at Zend\_Locale. Writing an issue for another component is not really helpfull as several facts are missing ;-)

{quote}And findLocale() doesn't exist in Zend\_Locale (or indeed anywhere), at least not in the V1.7.2 library I am using. So which version are you talking about?{quote}

As you are referring to the manual I am also referring to the release the manual was written for. This is actually 1.7.5... you noted that you are using ZF 1.7.2 in your comment.

As this code and the related sentence / section in the manual was added 18.Jan. it's in release 1.7.4. 1.7.2 simply doesn't have this method.

Please update to 1.7.4 or the actual 1.7.5. There should be no BC breaks when you are already on 1.7.2 (there are no in I18N) as these are mini releases.

Waiting for your reply

 

 

Posted by Ashley Kitson (akzincdig) on 2009-02-24T04:49:32.000+0000

OK Thomas, I'll go grab 1.7.5 and try again. I did indicate that this was an issue in 1.7.2 in the bug report though

I'll put the system through a test cycle and see if I get different results. Thanks.

 

 

Posted by Thomas Weidner (thomas) on 2009-02-24T04:56:50.000+0000

Yes, you have :-)

But the manual is for the actual release, and of course problems told in the past are already solved. I don't know if this is the case for this issue, but as the code differs I expect so.

 

 

Posted by Ashley Kitson (akzincdig) on 2009-02-24T05:44:09.000+0000

Using ZF 1.7.5

require\_once 'Zend/Loader.php'; Zend\_Loader::registerAutoload(); $l1 = new Zend\_Locale('en\_GB'); Zend\_Registry::set('Zend\_Locale', $l1); $l2 = new Zend\_Locale();

result: HTTP\_ACCEPT\_LANGUAGE = fr,en;q=0.7,en-us;q=0.3 result: $l1 = 'en\_GB' result: $l2 = 'fr'

Therefore setting an application wide locale is _not_ working as documented.

I'll test the Zend\_Translate functionality and report any issues separately

 

 

Posted by Ashley Kitson (akzincdig) on 2009-02-24T05:53:30.000+0000

The fix for it is to do exactly what has been done in findLocale() in \_prepareLocale() and check the registry if the $locale parameter is null

 

 

Posted by Thomas Weidner (thomas) on 2009-02-24T06:56:48.000+0000

When you register Zend\_Locale this locale is used for other components like Zend\_Translate, Zend\_Currency and so on.

Creating a new locale object means that you create a new instance. A new instance does not use previous stored values as you should get the registry in this case when you want to have the stored object from before. A new locale does ALWAYS use autodetection on browser/system when you do not give a locale.

This is expected, documented and wished behaviour.

As stated in the manual calling new Zend\_Locale() returns the browser-environment locales. What you suggests is not a fix but a feature change which would result in a BC break.

Only because something does not work as you expected it does not mean that there is a failure. ;-) Normally there is a reason for it.

 

 

Posted by Thomas Weidner (thomas) on 2009-02-25T03:34:01.000+0000

Closing as non-issue

 

 

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts