Search code examples
phpcakephpphp-5.6cakephp-3.6

i18n::setLocale cakephp 3.6


In a CakePHP 3.6 application, I have the following in beforeFilter method of AppController:

public function beforeFilter(Event $event)
{
    parent::beforeFilter($event);

    $lang = $this->request->getQuery('lang');

    if(!empty($lang) && in_array($lang, ['en_US', 'fr_CA'])) {

        I18n::setLocale($lang);
        
        return $this->redirect($this->referer());
    }
}

In my default.ctp Layout I have links to change the language when they are clicked on like this:

<ul>
    <li><a href="<?= $this->Url->build(['?' => ['lang' => 'fr_CA']]); ?>">FR</a></li>
    <li><a href="<?= $this->Url->build(['?' => ['lang' => 'en_US']]); ?>">EN</a></li>
</ul>

And finally in the display action of PagesController I have the following:

public function display(...$path)
{
    // Other non-related codes....

    $locale = I18n::getLocale();

    $this->set(compact('locale'));
}

But the locale variable in my views still stays at en_US even if I clicked on the FR link which sent lang parameter equal to fr_CA. Is it because of the redirect that I lost my locale? If so, how can I conserve my locale after sending my lang parameter?

I removed the redirect, now the value of locale in Pages Controller is the right one, but as soon as I access another page (like about page or something from Pages controller), the value of locale goes back to en_US. So what is really the point of I18n::setLocale in CakePHP 3.6 if the value is lost when we navigate to other areas of the sites? So we have to constantly keep calling it for it to work?


Solution

  • CakePHP does not store locale information between requests. If you want the locale to persist for user, you should store it somewhere (session, cookies, param in url, part of url patch, user record in db...), and retrieve it on every new request (for example in initialize() of your AppController) and set it.

    You can also use Locale Selector Filter, which will choose locale based on request data.