bug #31266 [Translator] Load plurals from po files properly (Stadly)
This PR was squashed before being merged into the 3.4 branch (closes #31266).
Discussion
----------
[Translator] Load plurals from po files properly
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | https://github.com/symfony/symfony/issues/10152#issuecomment-55522675
| License | MIT
| Doc PR |
Plurals were not handled correctly when loading po files.
```
msgid "foo"
msgid_plural "foos"
msgstr[0] "bar"
msgstr[1] "bars"
```
Before, the po entry above was treated as two entries, which doesn't make sense:
```
'foo' => 'bar'
'foos' => 'bar|bars'
```
With this PR, it is treated as one entry:
```
'foo|foos' => 'bar|bars'
```
Commits
-------
6b69a99230
[Translator] Load plurals from po files properly
This commit is contained in:
commit
9fc8d2ec63
@ -126,23 +126,24 @@ class PoFileLoader extends FileLoader
|
|||||||
*/
|
*/
|
||||||
private function addMessage(array &$messages, array $item)
|
private function addMessage(array &$messages, array $item)
|
||||||
{
|
{
|
||||||
if (\is_array($item['translated'])) {
|
if (!empty($item['ids']['singular'])) {
|
||||||
$messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated'][0]);
|
$id = stripcslashes($item['ids']['singular']);
|
||||||
if (isset($item['ids']['plural'])) {
|
if (isset($item['ids']['plural'])) {
|
||||||
$plurals = $item['translated'];
|
$id .= '|'.stripcslashes($item['ids']['plural']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$translated = (array) $item['translated'];
|
||||||
// PO are by definition indexed so sort by index.
|
// PO are by definition indexed so sort by index.
|
||||||
ksort($plurals);
|
ksort($translated);
|
||||||
// Make sure every index is filled.
|
// Make sure every index is filled.
|
||||||
end($plurals);
|
end($translated);
|
||||||
$count = key($plurals);
|
$count = key($translated);
|
||||||
// Fill missing spots with '-'.
|
// Fill missing spots with '-'.
|
||||||
$empties = array_fill(0, $count + 1, '-');
|
$empties = array_fill(0, $count + 1, '-');
|
||||||
$plurals += $empties;
|
$translated += $empties;
|
||||||
ksort($plurals);
|
ksort($translated);
|
||||||
$messages[stripcslashes($item['ids']['plural'])] = stripcslashes(implode('|', $plurals));
|
|
||||||
}
|
$messages[$id] = stripcslashes(implode('|', $translated));
|
||||||
} elseif (!empty($item['ids']['singular'])) {
|
|
||||||
$messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,10 @@ class PoFileLoaderTest extends TestCase
|
|||||||
$resource = __DIR__.'/../fixtures/plurals.po';
|
$resource = __DIR__.'/../fixtures/plurals.po';
|
||||||
$catalogue = $loader->load($resource, 'en', 'domain1');
|
$catalogue = $loader->load($resource, 'en', 'domain1');
|
||||||
|
|
||||||
$this->assertEquals(['foo' => 'bar', 'foos' => 'bar|bars'], $catalogue->all('domain1'));
|
$this->assertEquals([
|
||||||
|
'foo|foos' => 'bar|bars',
|
||||||
|
'{0} no foos|one foo|%count% foos' => '{0} no bars|one bar|%count% bars',
|
||||||
|
], $catalogue->all('domain1'));
|
||||||
$this->assertEquals('en', $catalogue->getLocale());
|
$this->assertEquals('en', $catalogue->getLocale());
|
||||||
$this->assertEquals([new FileResource($resource)], $catalogue->getResources());
|
$this->assertEquals([new FileResource($resource)], $catalogue->getResources());
|
||||||
}
|
}
|
||||||
@ -89,10 +92,8 @@ class PoFileLoaderTest extends TestCase
|
|||||||
$catalogue = $loader->load($resource, 'en', 'domain1');
|
$catalogue = $loader->load($resource, 'en', 'domain1');
|
||||||
|
|
||||||
$messages = $catalogue->all('domain1');
|
$messages = $catalogue->all('domain1');
|
||||||
$this->assertArrayHasKey('escaped "foo"', $messages);
|
$this->assertArrayHasKey('escaped "foo"|escaped "foos"', $messages);
|
||||||
$this->assertArrayHasKey('escaped "foos"', $messages);
|
$this->assertEquals('escaped "bar"|escaped "bars"', $messages['escaped "foo"|escaped "foos"']);
|
||||||
$this->assertEquals('escaped "bar"', $messages['escaped "foo"']);
|
|
||||||
$this->assertEquals('escaped "bar"|escaped "bars"', $messages['escaped "foos"']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSkipFuzzyTranslations()
|
public function testSkipFuzzyTranslations()
|
||||||
@ -106,4 +107,16 @@ class PoFileLoaderTest extends TestCase
|
|||||||
$this->assertArrayNotHasKey('foo2', $messages);
|
$this->assertArrayNotHasKey('foo2', $messages);
|
||||||
$this->assertArrayHasKey('foo3', $messages);
|
$this->assertArrayHasKey('foo3', $messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMissingPlurals()
|
||||||
|
{
|
||||||
|
$loader = new PoFileLoader();
|
||||||
|
$resource = __DIR__.'/../fixtures/missing-plurals.po';
|
||||||
|
$catalogue = $loader->load($resource, 'en', 'domain1');
|
||||||
|
|
||||||
|
$this->assertEquals([
|
||||||
|
'foo|foos' => '-|bar|-|bars',
|
||||||
|
], $catalogue->all('domain1'));
|
||||||
|
$this->assertEquals('en', $catalogue->getLocale());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
4
src/Symfony/Component/Translation/Tests/fixtures/missing-plurals.po
vendored
Normal file
4
src/Symfony/Component/Translation/Tests/fixtures/missing-plurals.po
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
msgid "foo"
|
||||||
|
msgid_plural "foos"
|
||||||
|
msgstr[3] "bars"
|
||||||
|
msgstr[1] "bar"
|
@ -3,3 +3,5 @@ msgid_plural "foos"
|
|||||||
msgstr[0] "bar"
|
msgstr[0] "bar"
|
||||||
msgstr[1] "bars"
|
msgstr[1] "bars"
|
||||||
|
|
||||||
|
msgid "{0} no foos|one foo|%count% foos"
|
||||||
|
msgstr "{0} no bars|one bar|%count% bars"
|
||||||
|
Reference in New Issue
Block a user