codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.38k stars 1.9k forks source link

Bug: Localization not working/being ignored for 404 page #5261

Closed twrschm closed 3 years ago

twrschm commented 3 years ago

When trying to show a 404 error via $routes->set404Override(), language lines are always rendered in the locale set in App.php, ignoring the language set via $this->request->setLocale(<language>). Therefore, creating multiple localizations for this page isn't possible. Interesting fact: Using $this->request->getLocale() works properly and shows the expected locale.

CodeIgniter 4 version CodeIgniter 4.1.4

Expected behavior, and steps to reproduce if appropriate Expected behavior: Whenever the locale is changed by $this->request->setLocale(<language>), the 404 page should use this locale as well.

Steps to reproduce:

  1. Change the current language globally to a different language than set in the App.php, using $this->request->setLocale() (e.g. in initController() or in the custom controller for the 404 page).

  2. Create a custom 404 page and set it as 404 override in Routes.php, e.g.: $routes->set404Override('App\Controllers\Pages\Errors::notFound');

  3. Call a non-existent page to trigger the 404 error page

  4. All language variables used in the 404 template will be rendered in the default language set in App.php

twrschm commented 3 years ago

Another interesting behaivour: It seems that the locale is displayed correctly whenever the requested page starts with a number (0-9), e.g. https://example.com/1234test

When trying to view an page starting with a letter, e.g. https://example.com/test1234, the language is set to the config default.

kenjis commented 3 years ago

When 404 route, system/Exceptions/PageNotFoundException.php calls lang(). At this point, the locale is en, so created a Language with the locale en.

Screenshot 2021-11-01 13 29 08

When not 404 route, lang() is called after changing the locale. So created a Language with the changed locale.

Screenshot 2021-11-01 13 29 45

kenjis commented 3 years ago

@twrschm The workaround is to set Language::$locale.

<?php

namespace App\Controllers;

use Config\Services;

class Errors extends BaseController
{
    public function show404()
    {
        $this->request->setLocale('ja');
        $locale = $this->request->getLocale();

        // workaround
        Services::language()->setLocale($locale);

        echo $locale .': '. lang('Security.disallowedAction');
    }
}
twrschm commented 3 years ago

@kenjis Thanks a lot for your reply! I will try your solution and get back to you again! 👍

twrschm commented 3 years ago

@kenjis Thanks a lot for your reply! I will try your solution and get back to you again! 👍

Seems to work fine for me; thanks again for your support & adding the fix!