Files
PhpSpreadsheet/tests/PhpSpreadsheetTests/Shared/StringHelperLocale2Test.php
T
oleibman 31174c1c90 Set All Locale Variables at Once in a Threadsafe Manner
Fix #954, which went stale 6 years ago and which I have now reopened. The `setLocale` method in `Calculation` and `Settings` does not affect the 3 localizable properties in `StringHelper` - `currencyCode`, `decimalSeparator`, and `thousandsSeparator`. One way to work around this problem is to set those properties separately; this is probably how most people handle it. Another way is to call Php's own `setlocale` function; this does not require any foreknowledge of what the values need to be, but it comes with baggage (data is maintained at process level rather than thread level), so its use is discouraged.

This PR adds a new `setLocale` method to `StringHelper`. It sets the 3 properties and the `Calculation` language all at once. It depends on the `Intl` extension, which is a recommendation but not a formal requirement for PhpSpreadsheet; the method will return `false` if `Intl` is not available or it thinks the supplied locale is not valid.
2025-12-25 19:24:44 -08:00

68 lines
2.2 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Shared;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class StringHelperLocale2Test extends TestCase
{
private Spreadsheet $spreadsheet;
protected function tearDown(): void
{
StringHelper::setLocale(null);
$this->spreadsheet->disconnectWorksheets();
unset($this->spreadsheet);
}
#[DataProvider('providerIntlLocales')]
public function testIntlLocales(bool|string $expectedResult, string $expectedTrue, ?string $locale): void
{
$this->spreadsheet = new Spreadsheet();
$number = 12345.67;
$numberFormat = '[$]#,##0.0';
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([[$number]]);
$sheet->getStyle('A1')->getNumberFormat()
->setFormatCode($numberFormat);
$success = StringHelper::setLocale($locale);
if ($success === false) {
self::assertFalse($expectedResult);
} else {
$result = $sheet->getCell('A1')->getFormattedValue();
self::assertSame($expectedResult, $result);
self::assertSame($expectedTrue, Calculation::getTRUE());
}
}
/**
* The data here are somewhat volatile.
* They may change with any new release of ICU.
*/
public static function providerIntlLocales(): array
{
$nbsp = "\u{A0}";
$nnbsp = "\u{202F}";
$rsquo = "\u{2019}";
return [
[false, 'TRUE', 'unknownlocale'],
["¤12{$nbsp}345,7", 'SANT', 'sv'],
['$12,345.7', 'TRUE', 'en_US'],
'lowercase country' => ["€12{$nnbsp}345,7", 'VRAI', 'fr_fr'],
'reset if locale is null' => ['$12,345.7', 'TRUE', null],
["CHF12{$rsquo}345.7", 'VERO', 'it_CH'],
'ignore utf-8' => ['د.ك.‏12٬345٫7', 'TRUE', 'ar_KW.UTF-8'],
'non-Latin' => ["₽12{$nbsp}345,7", 'ИСТИНА', 'ru_ru'],
];
}
}