CRM_Core_I18n::setLocale() - Fix bug with repeated usage
Overview
--------
Suppose you use `setLocale()` to change back and forth between languages, e.g.
```php
/*1*/ $i18n->setLocale('en_US'); echo ts('Yes');
/*2*/ $i18n->setLocale('fr_FR'); echo ts('Yes');
/*3*/ $i18n->setLocale('de_DE'); echo ts('Yes');
/*4*/ $i18n->setLocale('en_US'); echo ts('Yes');
/*5*/ $i18n->setLocale('fr_FR'); echo ts('Yes');
/*6*/ $i18n->setLocale('de_DE'); echo ts('Yes');
```
This fixes a bug with that use-case.
For more detailed example/reproduction, see https://gist.github.com/totten/
de0dc9add8dee3956ecad29ec0906cc3 -
specifically variant 2.
Before
------
There is a leak which causes mistranslations.
After
-----
You can freely switch between instances of `CRM_Core_I18n`.
Technical Details
-----------------
(1) I'm using a default configuration, wherein `CIVICRM_GETTEXT_NATIVE` is not
set... so it uses phpgettext.
(2) As you use multiple locales, `CRM_Core_I18n::singleton()` constructs
multiple instances of `CRM_Core_I18n` (one for each locale; this despite the
misnomer of `singleton`). `singleton()` always returns the instance indicated
by the active locale (as directed by `global $tsLocale`).
The problem: if you call `$enUS->setPhpGettextLocale('fr_FR')`, then future
requests for American English will actually return French. Similarly, if
you call `$frFR->setPhpGettextLocale('de_DE')`, then future requests for
French will actually return German.