Skip to content
This repository has been archived by the owner on Apr 28, 2024. It is now read-only.

Commit

Permalink
Release 4.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
lcharette authored Apr 29, 2020
2 parents 9f2e255 + eafcaaf commit 3cc5509
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 37 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ composer.lock
.php_cs.cache
_meta
.serenata
.vscode
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
sudo: false
dist: xenial
language: php

Expand All @@ -8,9 +7,6 @@ php:
- 7.3
- 7.4

matrix:
fast_finish: true

cache:
directories:
- $HOME/.composer/cache
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [4.4.1]
- Throws an exception if `translate` placeholder are not numeric or array.
- Fix issue with numeric placeholder with non plural keys. See [userfrosting#1090](https://github.com/userfrosting/UserFrosting/issues/1090#issuecomment-620832985).

## [4.4.0]
Complete rewrite of the Translator.

Expand All @@ -23,7 +27,7 @@ All methods of the `Translator` are the same for backward compatibility. The onl
- `@PLURAL_RULE` special key removed. Use the Locale configuration file (`locale.yaml`) `plural_rule` attribute instead.
- Translator can't load multiple locale anymore. Use the Locale configuration file `parents` attribute instead.

See updated [documentation](README.md) for more details on how to use the new Translator, Locale and Dictionary.
See updated [documentation](README.md) for more details on how to use the new Translator, Locale and Dictionary.

## [4.3.0]
- Dropping support for PHP 5.6 & 7.0
Expand Down Expand Up @@ -57,6 +61,7 @@ See updated [documentation](README.md) for more details on how to use the new Tr
## 4.0.0
- Initial release

[4.4.1]: https://github.com/userfrosting/i18n/compare/4.4.0...4.4.1
[4.4.0]: https://github.com/userfrosting/i18n/compare/4.3.0...4.4.0
[4.3.0]: https://github.com/userfrosting/i18n/compare/4.2.1...4.3.0
[4.2.1]: https://github.com/userfrosting/i18n/compare/4.2.0...4.2.1
Expand Down
3 changes: 3 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
parameters:
level: max
treatPhpDocTypesAsCertain: false
60 changes: 28 additions & 32 deletions src/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,17 @@ public function getLocale(): LocaleInterface
*
* Return the $messageKey if not match is found
*
* @param string $messageKey The id of the message id to translate. can use dot notation for array
* @param array|int $placeholders An optional hash of placeholder names => placeholder values to substitute (default : [])
* @param string $messageKey The id of the message id to translate. can use dot notation for array
* @param mixed[]|int $placeholders An optional hash of placeholder names => placeholder values to substitute (default : [])
*
* @return string The translated message.
*/
public function translate(string $messageKey, $placeholders = []): string
{
if (!is_numeric($placeholders) && !is_array($placeholders)) {
throw new \InvalidArgumentException('Placeholders must be array or numeric value.');
}

// Get the correct message from the specified key
$message = $this->getMessageFromKey($messageKey, $placeholders);

Expand All @@ -100,8 +104,8 @@ public function translate(string $messageKey, $placeholders = []): string
* Go throught all registered language keys avaiable and find the correct
* one to use, using the placeholders to select the correct plural form.
*
* @param string $messageKey The key to find the message for
* @param array|int $placeholders Passed by reference, since plural placeholder will be added for later processing
* @param string $messageKey The key to find the message for
* @param mixed[]|int $placeholders Passed by reference, since plural placeholder will be added for later processing
*
* @return string The message string
*/
Expand Down Expand Up @@ -176,7 +180,7 @@ protected function getMessageFromKey(string $messageKey, &$placeholders): string
* Return the plural key from a translation array.
* If no plural key is defined in the `@PLURAL` instruction of the message array, we fallback to the default one.
*
* @param array $messageArray
* @param mixed[] $messageArray
*
* @return string
*/
Expand All @@ -192,14 +196,14 @@ protected function getPluralKey(array $messageArray): string
/**
* Return the plural value, aka the nummber to display, from the placeholder values.
*
* @param array|int $placeholders Placeholder
* @param string $pluralKey The plural key, for key => value match
* @param mixed[]|int $placeholders Placeholder
* @param string $pluralKey The plural key, for key => value match
*
* @return int|null The number, null if not found
*/
protected function getPluralValue($placeholders, string $pluralKey): ?int
{
if (isset($placeholders[$pluralKey])) {
if (is_array($placeholders) && isset($placeholders[$pluralKey])) {
return (int) $placeholders[$pluralKey];
}

Expand All @@ -215,8 +219,8 @@ protected function getPluralValue($placeholders, string $pluralKey): ?int
* Return the correct plural message form to use.
* When multiple plural form are available for a message, this method will return the correct oen to use based on the numeric value.
*
* @param array $messageArray The array with all the form inside ($pluralRule => $message)
* @param int $pluralValue The numeric value used to select the correct message
* @param mixed[] $messageArray The array with all the form inside ($pluralRule => $message)
* @param int $pluralValue The numeric value used to select the correct message
*
* @return int|null Returns which key from $messageArray to use
*/
Expand Down Expand Up @@ -253,13 +257,18 @@ protected function getPluralMessageKey(array $messageArray, int $pluralValue): ?
* Parse Placeholder.
* Replace placeholders in the message with their values from the passed argument.
*
* @param string $message The message to replace placeholders in
* @param array $placeholders An optional hash of placeholder (names => placeholder) values to substitute (default : [])
* @param string $message The message to replace placeholders in
* @param mixed[]|int $placeholders An optional hash of placeholder (names => placeholder) values to substitute (default : [])
*
* @return string The message with replaced placeholders
*/
protected function parsePlaceHolders(string $message, array $placeholders): string
protected function parsePlaceHolders(string $message, $placeholders): string
{
// If $placeholders is not an array at this point, we make it an array, using `plural` as the key
if (!is_array($placeholders)) {
$placeholders = [$this->defaultPluralKey => $placeholders];
}

// Interpolate translatable placeholders values. This allows to
// pre-translate placeholder which value starts with the `&` caracter
foreach ($placeholders as $name => $value) {
Expand Down Expand Up @@ -304,15 +313,18 @@ protected function parsePlaceHolders(string $message, array $placeholders): stri
* @see https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals
*
* @param int|float $number The number we want to get the plural case for. Float numbers are floored.
* @param mixed $forceRule False to use the plural rule of the language package
* @param int|bool $forceRule False to use the plural rule of the language package
* or an integer to force a certain plural rule
*
* @return int The plural-case we need to use for the number plural-rule combination
*/
public function getPluralForm($number, $forceRule = false)
{
// Default to English rule (1) or the forced one
$ruleNumber = $this->getPluralRuleNumber($forceRule);
if (is_int($forceRule)) {
$ruleNumber = $forceRule;
} else {
$ruleNumber = $this->dictionary->getLocale()->getPluralRule();
}

// Get the rule class
$class = "\UserFrosting\I18n\PluralRules\Rule$ruleNumber";
Expand All @@ -322,20 +334,4 @@ public function getPluralForm($number, $forceRule = false)

return $class::getRule((int) $number);
}

/**
* Return the correct rule number to use.
*
* @param int|bool $forceRule Force to use a particular rule. Otherwise, use the language defined one
*
* @return int
*/
protected function getPluralRuleNumber($forceRule): int
{
if ($forceRule !== false) {
return $forceRule;
}

return $this->dictionary->getLocale()->getPluralRule();
}
}
34 changes: 34 additions & 0 deletions tests/TranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ public function testGetPluralForm(): void
$this->assertEquals($translator->translate('X_CARS', 2), '2 cars');
}

/**
* @depends testGetPluralForm
*/
public function testGetPluralFormForced(): void
{
$translator = $this->getTranslator('en_US');
$this->assertSame(1, $translator->getPluralForm(2, 0));
}

/**
* @depends testGetPluralForm
* Test locale wihtout a plural rule.
Expand Down Expand Up @@ -131,6 +140,31 @@ public function testTranslate(string $key, $placeholders, string $expectedResult
$this->assertEquals($expectedResultFrench, $frenchTranslator->translate($key, $placeholders));
}

/**
* @depends testTranslate
*/
public function testTranslateKeyWithNoPlural(): void
{
$translator = $this->getTranslator();
$this->assertEquals($translator->translate('USERNAME', 123), 'Username');
$this->assertEquals($translator->translate('X_FOO'), 'x foos');
$this->assertEquals($translator->translate('X_FOO', ['plural' => 1]), '1x foos');
$this->assertEquals($translator->translate('X_FOO', 1), '1x foos');
$this->assertEquals($translator->translate('X_FOO', 123), '123x foos');
}

/**
* Force test a non-array / non-int placeholder.
*
* @depends testTranslate
*/
public function testTranslateKeyWithBadPlaceholder(): void
{
$translator = $this->getTranslator();
$this->expectException(\InvalidArgumentException::class);
$this->assertEquals($translator->translate('X_FOO', 'xx'), 'xxx foos');
}

/**
* Basic test to see if triple dependency works.
*/
Expand Down
2 changes: 2 additions & 0 deletions tests/data/sprinkles/core/locale/en_US/test.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
return [
'USERNAME' => 'Username',

'X_FOO' => '{{plural}}x foos',

'BASE_FALLBACK' => 'Base fallback',

'ACCOUNT' => [
Expand Down

0 comments on commit 3cc5509

Please sign in to comment.