Skip to content

Commit

Permalink
PHP 8.x intl incompatiblity: failback C locale with en_US
Browse files Browse the repository at this point in the history
PHP 8.2.13 and 8.1.26 introduced another error preventing the CI to pass
with default POSIX locale. We now have a wrapper to get the locale and
replace C with a valid locale.

@see php/php-src#12561

Fixes shaarli#2029
  • Loading branch information
ArthurHoaro committed Nov 25, 2023
1 parent 60bc06a commit 78d9d9f
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 46 deletions.
24 changes: 23 additions & 1 deletion application/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,12 @@ 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
);
var_dump('$formatter');
var_dump($formatter);
$formatter->setTimeZone($date->getTimezone());

return $formatter->format($date);
Expand Down Expand Up @@ -503,3 +505,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

0 comments on commit 78d9d9f

Please sign in to comment.