meeting-room-booking-system / mrbs-code

MRBS application code
Other
124 stars 61 forks source link

Notice: Server failed to set locale to ["en-GB.8","en_GB.utf8"] for language tag 'en-GB'. in /app/mrbs/web/language.inc on line 256 #80

Closed yorkshire-pudding closed 1 year ago

yorkshire-pudding commented 1 year ago

Describe the bug At top of all screens is notice:

Notice: Server failed to set locale to ["en-GB.UTF-8","en_GB.UTF-8"] for language tag 'en-GB'. in /app/mrbs/web/language.inc on line 256

To Reproduce Steps to reproduce the behavior:

  1. Install in Lando (don't know if that has anything to do with it)
  2. Configure database connection
  3. Open in browser

Expected behavior Locale set properly, no "Notice" at top of page.

Screenshots image

$ locale
LANG=en_GB.utf8
LANGUAGE=
LC_CTYPE="en_GB.utf8"
LC_NUMERIC="en_GB.utf8"
LC_TIME="en_GB.utf8"
LC_COLLATE="en_GB.utf8"
LC_MONETARY="en_GB.utf8"
LC_MESSAGES="en_GB.utf8"
LC_PAPER="en_GB.utf8"
LC_NAME="en_GB.utf8"
LC_ADDRESS="en_GB.utf8"
LC_TELEPHONE="en_GB.utf8"
LC_MEASUREMENT="en_GB.utf8"
LC_IDENTIFICATION="en_GB.utf8"
LC_ALL=
$ locale -a
C
C.UTF-8
en_GB
en_GB.iso88591
en_GB.utf8
en_US.utf8
POSIX

Browser details (please complete the following information):

Server details (please complete the following information):

Additional context I did search to see if I could find anything and also found this old thread I copied, but slightly modified the test.php file:

test.php ```php \n"; echo '$aliased_header: '; var_dump($aliased_header); echo "
\n"; echo 'get_mrbs_locale(): '; $tmp = get_mrbs_locale($aliased_header); var_dump($tmp); echo "
\n"; echo '$override_locale: '; var_dump($override_locale); echo "
\n"; echo '$disable_automatic_language_changing: '; var_dump($disable_automatic_language_changing); echo "
\n"; echo '$default_language_tokens: '; var_dump($default_language_tokens); echo "
\n"; echo '$cli_language: '; var_dump($cli_language); echo "
\n"; echo 'Locale::acceptFromHttp(): '; $tmp = Locale::acceptFromHttp($aliased_header); var_dump($tmp); echo "
\n"; if (class_exists('\\Locale')) { echo '\Locale::acceptFromHttp(): '; $tmp = \Locale::acceptFromHttp($aliased_header); var_dump($tmp); echo "
\n"; } echo 'PHP_OS: '; var_dump(PHP_OS); echo "
\n"; echo 'System::getServerOs(): '; $tmp = System::getServerOs(); var_dump($tmp); echo "
\n"; echo '$original_locales: '; $original_locales = explode(';', setlocale(LC_ALL, 0)); var_dump($original_locales); echo "
\n"; foreach (array("en-GB", "en", "en-US") as $langtag) { echo "

$langtag

"; echo 'System::getOSlocale(): '; $tmp = System::getOSlocale($langtag); var_dump($tmp); echo "
\n"; } ```
Output ``` $server["HTTP_ACCEPT_LANGUAGE"]: string(26) "en-GB,en;q=0.9,en-US;q=0.8" $aliased_header: string(26) "en-GB,en;q=0.9,en-US;q=0.8" get_mrbs_locale(): string(5) "en-GB" $override_locale: string(0) "" $disable_automatic_language_changing: bool(false) $default_language_tokens: string(2) "en" $cli_language: string(2) "en" Locale::acceptFromHttp(): string(5) "en-GB" \Locale::acceptFromHttp(): string(5) "en_GB" PHP_OS: string(5) "Linux" System::getServerOs(): string(5) "linux" $original_locales: array(1) { [0]=> string(1) "C" } en-GB System::getOSlocale(): array(2) { [0]=> string(11) "en-GB.UTF-8" [1]=> string(11) "en_GB.UTF-8" } en System::getOSlocale(): array(3) { [0]=> string(8) "en.UTF-8" [1]=> string(11) "en-GB.UTF-8" [2]=> string(11) "en_GB.UTF-8" } en-US System::getOSlocale(): array(2) { [0]=> string(11) "en-US.UTF-8" [1]=> string(11) "en_US.UTF-8" } ```
campbell-m commented 1 year ago

Mmm. I think MRBS may have to try a variety of codeset suffixes. Before I make the change could you run the following test code on your system and post the output:

<?php
$locales = array('en_GB', 'en_GB.UTF-8', 'en_GB.utf-8', 'en_GB.utf8');
array_push($locales, $locales);

foreach ($locales as $locale)
{
  echo "Locale: " . json_encode($locale) . " Result: ";
  var_dump(setlocale(LC_ALL, $locale));
  echo "<br>\n";
}
yorkshire-pudding commented 1 year ago

Thanks. Here is the output:

Locale: "en_GB" Result: bool(false)
Locale: "en_GB.UTF-8" Result: bool(false)
Locale: "en_GB.utf-8" Result: bool(false)
Locale: "en_GB.utf8" Result: bool(false)
Locale: ["en_GB","en_GB.UTF-8","en_GB.utf-8","en_GB.utf8"] Result: bool(false)

Doesn't seem to like any of those. Strange

campbell-m commented 1 year ago

Try this (I've added some more locales):

<?php
$locales = array('en_GB', 'en_GB.UTF-8', 'en_GB.utf-8', 'en_GB.utf8', 'en-GB', 'en-GB.UTF-8', 'en-GB.utf-8', 'en-GB.utf8');
array_push($locales, $locales);

foreach ($locales as $locale)
{
  echo "Locale: " . json_encode($locale) . " Result: ";
  var_dump(setlocale(LC_ALL, $locale));
  echo "<br>\n";
}
yorkshire-pudding commented 1 year ago

Very odd. I would expect en_GB.utf8 to work:

Locale: "en_GB" Result: bool(false)
Locale: "en_GB.UTF-8" Result: bool(false)
Locale: "en_GB.utf-8" Result: bool(false)
Locale: "en_GB.utf8" Result: bool(false)
Locale: "en-GB" Result: bool(false)
Locale: "en-GB.UTF-8" Result: bool(false)
Locale: "en-GB.utf-8" Result: bool(false)
Locale: "en-GB.utf8" Result: bool(false)
Locale: ["en_GB","en_GB.UTF-8","en_GB.utf-8","en_GB.utf8","en-GB","en-GB.UTF-8","en-GB.utf-8","en-GB.utf8"] Result: bool(false)
campbell-m commented 1 year ago

What happens if you change LC_ALL to, say, LC_NUMERIC in the test program?

yorkshire-pudding commented 1 year ago

Same. Out of interest I added:

var_dump(setlocale(LC_ALL, 0));

That returns: string(1) "C" Same for LC_NUMERIC

Perhaps it is a Lando specific thing that doesn't allow locale to be set. I will investigate the lando side a bit more.

Right, this becomes a bit clearer. If I SSH into the lando app, then we get:

www-data@cde06cd5fc8e:/app$ locale -a
C
C.UTF-8
POSIX

So I then tried with 'C.UTF-8' and that works. Perhaps that is needed as a fallback for people using lando or other environments with limited locales? I will look to see if I can add locales into the lando recipe.

campbell-m commented 1 year ago

The code already falls back to 'C', but I've now added its UTF-8 variants as well in 91af94d.

yorkshire-pudding commented 1 year ago

That update doesn't, unfortunately stop the notice. I now get:

Notice: parseLocale: could not parse subtag 'c' in /app/mrbs/web/lib/MRBS/Locale.php on line 224 Notice: Server failed to set locale to ["c.UTF-8"] for language tag 'c'. in /app/mrbs/web/language.inc on line 257

I think that is because it happens after the error, so we still get the original notice, but now we can set the locale, we now get an error in Locale.php - I think this one is to do with the case - most languages are lower, but C is upper.

As setlocale can take an array, I think creating an array of the c options and merging to the end of $os_locale might make sense.

Once I do that (a rough and ready solution) then left with:

Notice: parseLocale: could not parse subtag 'c' in /app/mrbs/web/lib/MRBS/Locale.php on line 224

campbell-m commented 1 year ago

Mmmm, don't quite understand that. Are you using MRBS 1.11.0 or the latest development code from the main branch?

yorkshire-pudding commented 1 year ago

So slightly different line numbers than patched release, but there is no overall difference between the main branch which includes your latest commit and the release with a patch of the changes you committed to dev.

Notice: parseLocale: could not parse subtag 'c' in /app/mrbs-code/web/lib/MRBS/Locale.php on line 224 Notice: Server failed to set locale to ["c.UTF-8"] for language tag 'c'. in /app/mrbs-code/web/language.inc on line 259

campbell-m commented 1 year ago

Could you set $debug = true; in your MRBS config file please and it should generate a stack trace so I can work out how it got there? The debug output will appear in your browser.

yorkshire-pudding commented 1 year ago

I think I found what was causing the thing in Locale.php - in troubleshooting the previous error, I had tried adding:

$override_locale = "C";

into config and forgotten it was there. Once removed we are back to just:

Notice: Server failed to set locale to ["en-GB.UTF-8","en_GB.UTF-8"] for language tag 'en-GB'. in /app/mrbs-code/web/language.inc on line 259

If we look at the whole function:

https://github.com/meeting-room-booking-system/mrbs-code/blob/91af94d8e40366fb519f866592dc5d96fc575f8c/web/language.inc#L245-L266

we can see that it tries to set before hand on line 254 and that is what causes the notice:

https://github.com/meeting-room-booking-system/mrbs-code/blob/91af94d8e40366fb519f866592dc5d96fc575f8c/web/language.inc#L254

This is above line 261 where you added the new variants.

This might actually be desired behaviour because how many systems don't have the right locale? I do think this is a problem with Lando but not one I came across before. I note in the repo, there is actually a dockerfile that adds in the en_GB and en_US locales. As Lando is built on docker, I'm going to try and use this but I'm minded to close this now, and I'll ignore or try to get the dockerfile to work with Lando.

campbell-m commented 1 year ago

OK, glad it's solved.

yorkshire-pudding commented 1 year ago

Just in case anyone else comes across this issue with Lando, I adapted (through trial and error) the following lines in the docker file: https://github.com/meeting-room-booking-system/mrbs-code/blob/main/Dockerfile#L5-L8

What I now have in my Lando recipe is:

services:
  appserver:
    run_as_root:
      - apt-get update && apt-get install -y locales
      - sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen
      - sed -i 's/^# *\(en_GB.UTF-8\)/\1/' /etc/locale.gen
      - locale-gen 

This works and gets rid of the notice.