Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP 8.x intl incompatibility: failback C locale with en_US #2044

Merged
merged 2 commits into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion application/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ function format_date($date, $time = true, $intl = true)
return $date->format($format);
}
$formatter = new IntlDateFormatter(
setlocale(LC_TIME, 0),
get_locale(LC_TIME),
IntlDateFormatter::LONG,
$time ? IntlDateFormatter::LONG : IntlDateFormatter::NONE
);
Expand Down Expand Up @@ -503,3 +503,23 @@ function exception2text(Throwable $e): string
{
return $e->getMessage() . PHP_EOL . $e->getFile() . $e->getLine() . PHP_EOL . $e->getTraceAsString();
}

/**
* Get the current locale, overrides 'C' locale which is no longer compatible with PHP-intl
*
* @param int $category Category of the locale (LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_ALL)
*
* @return string|false The locale, or false if not found.
*
* @see https://github.com/php/php-src/issues/12561
*/
function get_locale(int $category = LC_CTYPE)
{
$locale = setlocale($category, 0);

if ($locale === 'C' || startsWith($locale, 'C.')) {
$locale = 'en_US.utf8'; // failback
}

return $locale;
}
2 changes: 1 addition & 1 deletion application/front/controller/visitor/FeedController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ protected function processRequest(string $feedType, Request $request, Response $
}

// Generate data.
$this->container->feedBuilder->setLocale(strtolower(setlocale(LC_COLLATE, 0)));
$this->container->feedBuilder->setLocale(strtolower(get_locale(LC_COLLATE)));
$this->container->feedBuilder->setHideDates($this->container->conf->get('privacy.hide_timestamps', false));
$this->container->feedBuilder->setUsePermalinks(
null !== $request->getParam('permalinks') || !$this->container->conf->get('feed.rss_permalinks')
Expand Down
2 changes: 1 addition & 1 deletion application/http/HttpUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function get_http_response(
'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:45.0)'
. ' Gecko/20100101 Firefox/45.0';
$acceptLanguage =
substr(setlocale(LC_COLLATE, 0), 0, 2) . ',en-US;q=0.7,en;q=0.3';
substr(get_locale(LC_COLLATE), 0, 2) . ',en-US;q=0.7,en;q=0.3';
$maxRedirs = 3;

if (!function_exists('curl_init')) {
Expand Down
2 changes: 1 addition & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
autoLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']);
}

new Languages(setlocale(LC_MESSAGES, 0), $conf);
new Languages(get_locale(LC_MESSAGES), $conf);

$conf->setEmpty('general.timezone', date_default_timezone_get());
$conf->setEmpty('general.title', t('Shared bookmarks on ') . escape(index_url($_SERVER)));
Expand Down
28 changes: 14 additions & 14 deletions tests/languages/de/UtilsDeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function testIntlDateFormatter()
*/
public function testDateFormat()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('de-de');
$date = DateTime::createFromFormat('Ymd_His', '20170102_201112');
$this->assertRegExp('/2\. Januar 2017 (um )?20:11:12 GMT\+0?3(:00)?/', format_date($date, true, true));
Expand All @@ -32,7 +32,7 @@ public function testDateFormat()
*/
public function testDateFormatNoTime()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('de-de');
$date = DateTime::createFromFormat('Ymd_His', '20170102_201112');
$this->assertRegExp('/2\. Januar 2017/', format_date($date, false, true));
Expand Down Expand Up @@ -62,10 +62,10 @@ public function testDateFormatDefaultNoTime()
*/
public function testAutoLocaleValid()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'en-us';
autoLocale($header);
$this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -75,10 +75,10 @@ public function testAutoLocaleValid()
*/
public function testAutoLocaleValidAlternative()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'en_US.UTF-8';
autoLocale($header);
$this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -88,10 +88,10 @@ public function testAutoLocaleValidAlternative()
*/
public function testAutoLocaleMultipleFirstValid()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'en-us,de-de';
autoLocale($header);
$this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -101,10 +101,10 @@ public function testAutoLocaleMultipleFirstValid()
*/
public function testAutoLocaleMultipleSecondAvailable()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'mgg_IN,fr-fr';
autoLocale($header);
$this->assertEquals('fr_FR.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('fr_FR.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -114,9 +114,9 @@ public function testAutoLocaleMultipleSecondAvailable()
*/
public function testAutoLocaleBlank()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('');
$this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.UTF-8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -126,9 +126,9 @@ public function testAutoLocaleBlank()
*/
public function testAutoLocaleUnavailable()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('mgg_IN');
$this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.UTF-8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand Down
28 changes: 14 additions & 14 deletions tests/languages/en/UtilsEnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function testIntlDateFormatter()
*/
public function testDateFormat()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('en_US.UTF-8');
$date = DateTime::createFromFormat('Ymd_His', '20170102_201112');
$this->assertRegExp('/January 2, 2017 (at )?8:11:12 PM GMT\+0?3(:00)?/', format_date($date, true, true));
Expand All @@ -32,7 +32,7 @@ public function testDateFormat()
*/
public function testDateFormatNoTime()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('en_US.UTF-8');
$date = DateTime::createFromFormat('Ymd_His', '20170102_201112');
$this->assertRegExp('/January 2, 2017/', format_date($date, false, true));
Expand Down Expand Up @@ -62,10 +62,10 @@ public function testDateFormatDefaultNoTime()
*/
public function testAutoLocaleValid()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'de-de';
autoLocale($header);
$this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('de_DE.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -75,10 +75,10 @@ public function testAutoLocaleValid()
*/
public function testAutoLocaleValidAlternative()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'de_de.UTF8';
autoLocale($header);
$this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('de_DE.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -88,10 +88,10 @@ public function testAutoLocaleValidAlternative()
*/
public function testAutoLocaleMultipleFirstValid()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'de-de;en-us';
autoLocale($header);
$this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('de_DE.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -101,10 +101,10 @@ public function testAutoLocaleMultipleFirstValid()
*/
public function testAutoLocaleMultipleSecondAvailable()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'mgg_IN,fr-fr';
autoLocale($header);
$this->assertEquals('fr_FR.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('fr_FR.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -114,9 +114,9 @@ public function testAutoLocaleMultipleSecondAvailable()
*/
public function testAutoLocaleBlank()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('');
$this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.UTF-8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -126,9 +126,9 @@ public function testAutoLocaleBlank()
*/
public function testAutoLocaleUnavailable()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('mgg_IN');
$this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.UTF-8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand Down
28 changes: 14 additions & 14 deletions tests/languages/fr/UtilsFrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function testIntlDateFormatter()
*/
public function testDateFormat()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('fr-fr');
$date = DateTime::createFromFormat('Ymd_His', '20170102_201112');
$this->assertRegExp('/2 janvier 2017 (à )?20:11:12 UTC\+0?3(:00)?/', format_date($date));
Expand All @@ -32,7 +32,7 @@ public function testDateFormat()
*/
public function testDateFormatNoTime()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('fr-fr');
$date = DateTime::createFromFormat('Ymd_His', '20170102_201112');
$this->assertRegExp('/2 janvier 2017/', format_date($date, false, true));
Expand Down Expand Up @@ -62,10 +62,10 @@ public function testDateFormatDefaultNoTime()
*/
public function testAutoLocaleValid()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'de-de';
autoLocale($header);
$this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('de_DE.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -75,10 +75,10 @@ public function testAutoLocaleValid()
*/
public function testAutoLocaleValidAlternative()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'de_de.UTF8';
autoLocale($header);
$this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('de_DE.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -88,10 +88,10 @@ public function testAutoLocaleValidAlternative()
*/
public function testAutoLocaleMultipleFirstValid()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'de-de;en-us';
autoLocale($header);
$this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('de_DE.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -101,10 +101,10 @@ public function testAutoLocaleMultipleFirstValid()
*/
public function testAutoLocaleMultipleSecondAvailable()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
$header = 'mgg_IN,de-de';
autoLocale($header);
$this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0));
$this->assertEquals('de_DE.utf8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -114,9 +114,9 @@ public function testAutoLocaleMultipleSecondAvailable()
*/
public function testAutoLocaleBlank()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('');
$this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.UTF-8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand All @@ -126,9 +126,9 @@ public function testAutoLocaleBlank()
*/
public function testAutoLocaleUnavailable()
{
$current = setlocale(LC_ALL, 0);
$current = get_locale(LC_ALL);
autoLocale('mgg_IN');
$this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0));
$this->assertEquals('en_US.UTF-8', get_locale(LC_ALL));

setlocale(LC_ALL, $current);
}
Expand Down