Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4b05ff6

Browse files
[Translation] make intl+icu format seamless by handling it in MessageCatalogue
1 parent 100f205 commit 4b05ff6

11 files changed

+154
-26
lines changed

src/Symfony/Component/Translation/Catalogue/MergeOperation.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Translation\Catalogue;
1313

14+
use Symfony\Component\Translation\MessageCatalogueInterface;
15+
1416
/**
1517
* Merge operation between two catalogues as follows:
1618
* all = source ∪ target = {x: x ∈ source ∨ x ∈ target}
@@ -32,10 +34,11 @@ protected function processDomain($domain)
3234
'new' => array(),
3335
'obsolete' => array(),
3436
);
37+
$intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
3538

3639
foreach ($this->source->all($domain) as $id => $message) {
3740
$this->messages[$domain]['all'][$id] = $message;
38-
$this->result->add(array($id => $message), $domain);
41+
$this->result->add(array($id => $message), $this->source->defines($id, $intlDomain) ? $intlDomain : $domain);
3942
if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
4043
$this->result->setMetadata($id, $keyMetadata, $domain);
4144
}
@@ -45,7 +48,7 @@ protected function processDomain($domain)
4548
if (!$this->source->has($id, $domain)) {
4649
$this->messages[$domain]['all'][$id] = $message;
4750
$this->messages[$domain]['new'][$id] = $message;
48-
$this->result->add(array($id => $message), $domain);
51+
$this->result->add(array($id => $message), $this->target->defines($id, $intlDomain) ? $intlDomain : $domain);
4952
if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
5053
$this->result->setMetadata($id, $keyMetadata, $domain);
5154
}

src/Symfony/Component/Translation/Catalogue/TargetOperation.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Translation\Catalogue;
1313

14+
use Symfony\Component\Translation\MessageCatalogueInterface;
15+
1416
/**
1517
* Target operation between two catalogues:
1618
* intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target}
@@ -33,6 +35,7 @@ protected function processDomain($domain)
3335
'new' => array(),
3436
'obsolete' => array(),
3537
);
38+
$intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
3639

3740
// For 'all' messages, the code can't be simplified as ``$this->messages[$domain]['all'] = $target->all($domain);``,
3841
// because doing so will drop messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
@@ -46,7 +49,7 @@ protected function processDomain($domain)
4649
foreach ($this->source->all($domain) as $id => $message) {
4750
if ($this->target->has($id, $domain)) {
4851
$this->messages[$domain]['all'][$id] = $message;
49-
$this->result->add(array($id => $message), $domain);
52+
$this->result->add(array($id => $message), $this->target->defines($id, $intlDomain) ? $intlDomain : $domain);
5053
if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
5154
$this->result->setMetadata($id, $keyMetadata, $domain);
5255
}
@@ -59,7 +62,7 @@ protected function processDomain($domain)
5962
if (!$this->source->has($id, $domain)) {
6063
$this->messages[$domain]['all'][$id] = $message;
6164
$this->messages[$domain]['new'][$id] = $message;
62-
$this->result->add(array($id => $message), $domain);
65+
$this->result->add(array($id => $message), $this->target->defines($id, $intlDomain) ? $intlDomain : $domain);
6366
if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
6467
$this->result->setMetadata($id, $keyMetadata, $domain);
6568
}

src/Symfony/Component/Translation/Dumper/FileDumper.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,26 @@ public function dump(MessageCatalogue $messages, $options = array())
7676
throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory));
7777
}
7878
}
79-
// save file
79+
80+
$intlDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX;
81+
$intlMessages = $messages->all($intlDomain);
82+
83+
if ($intlMessages) {
84+
$intlPath = $options['path'].'/'.$this->getRelativePath($intlDomain, $messages->getLocale());
85+
file_put_contents($intlPath, $this->formatCatalogue($messages, $intlDomain, $options));
86+
87+
$messages->replace(array(), $intlDomain);
88+
89+
try {
90+
if ($messages->all($domain)) {
91+
file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
92+
}
93+
continue;
94+
} finally {
95+
$messages->replace($intlMessages, $intlDomain);
96+
}
97+
}
98+
8099
file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
81100
}
82101
}

src/Symfony/Component/Translation/Formatter/IntlFormatterInterface.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
*/
1919
interface IntlFormatterInterface
2020
{
21-
const DOMAIN_SUFFIX = '+intl-icu';
22-
2321
/**
2422
* Formats a localized message using rules defined by ICU MessageFormat.
2523
*

src/Symfony/Component/Translation/MessageCatalogue.php

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,41 @@ public function getLocale()
4949
*/
5050
public function getDomains()
5151
{
52-
return array_keys($this->messages);
52+
$domains = array();
53+
$suffixLength = \strlen(self::INTL_DOMAIN_SUFFIX);
54+
55+
foreach ($this->messages as $domain => $messages) {
56+
if (\strlen($domain) > $suffixLength && false !== $i = strpos($domain, self::INTL_DOMAIN_SUFFIX, -$suffixLength)) {
57+
$domain = substr($domain, 0, $i);
58+
}
59+
$domains[$domain] = $domain;
60+
}
61+
62+
return array_values($domains);
5363
}
5464

5565
/**
5666
* {@inheritdoc}
5767
*/
5868
public function all($domain = null)
5969
{
60-
if (null === $domain) {
61-
return $this->messages;
70+
if (null !== $domain) {
71+
return ($this->messages[$domain.self::INTL_DOMAIN_SUFFIX] ?? array()) + ($this->messages[$domain] ?? array());
72+
}
73+
74+
$allMessages = array();
75+
$suffixLength = \strlen(self::INTL_DOMAIN_SUFFIX);
76+
77+
foreach ($this->messages as $domain => $messages) {
78+
if (\strlen($domain) > $suffixLength && false !== $i = strpos($domain, self::INTL_DOMAIN_SUFFIX, -$suffixLength)) {
79+
$domain = substr($domain, 0, $i);
80+
$allMessages[$domain] = $messages + ($allMessages[$domain] ?? array());
81+
} else {
82+
$allMessages[$domain] = ($allMessages[$domain] ?? array()) + $messages;
83+
}
6284
}
6385

64-
return isset($this->messages[$domain]) ? $this->messages[$domain] : array();
86+
return $allMessages;
6587
}
6688

6789
/**
@@ -77,7 +99,7 @@ public function set($id, $translation, $domain = 'messages')
7799
*/
78100
public function has($id, $domain = 'messages')
79101
{
80-
if (isset($this->messages[$domain][$id])) {
102+
if (isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
81103
return true;
82104
}
83105

@@ -93,14 +115,18 @@ public function has($id, $domain = 'messages')
93115
*/
94116
public function defines($id, $domain = 'messages')
95117
{
96-
return isset($this->messages[$domain][$id]);
118+
return isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]);
97119
}
98120

99121
/**
100122
* {@inheritdoc}
101123
*/
102124
public function get($id, $domain = 'messages')
103125
{
126+
if (isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
127+
return $this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id];
128+
}
129+
104130
if (isset($this->messages[$domain][$id])) {
105131
return $this->messages[$domain][$id];
106132
}
@@ -117,7 +143,7 @@ public function get($id, $domain = 'messages')
117143
*/
118144
public function replace($messages, $domain = 'messages')
119145
{
120-
$this->messages[$domain] = array();
146+
unset($this->messages[$domain], $this->messages[$domain.self::INTL_DOMAIN_SUFFIX]);
121147

122148
$this->add($messages, $domain);
123149
}
@@ -144,6 +170,10 @@ public function addCatalogue(MessageCatalogueInterface $catalogue)
144170
}
145171

146172
foreach ($catalogue->all() as $domain => $messages) {
173+
if ($intlMessages = $catalogue->all($domain.self::INTL_DOMAIN_SUFFIX)) {
174+
$this->add($intlMessages, $domain.self::INTL_DOMAIN_SUFFIX);
175+
$messages = array_diff_key($messages, $intlMessages);
176+
}
147177
$this->add($messages, $domain);
148178
}
149179

src/Symfony/Component/Translation/MessageCatalogueInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
*/
2121
interface MessageCatalogueInterface
2222
{
23+
const INTL_DOMAIN_SUFFIX = '+intl-icu';
24+
2325
/**
2426
* Gets the catalogue locale.
2527
*

src/Symfony/Component/Translation/Tests/Catalogue/MergeOperationTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ public function testGetResultFromSingleDomain()
5353
);
5454
}
5555

56+
public function testGetResultFromIntlDomain()
57+
{
58+
$this->assertEquals(
59+
new MessageCatalogue('en', array(
60+
'messages' => array('a' => 'old_a', 'b' => 'old_b'),
61+
'messages+intl-icu' => array('d' => 'old_d', 'c' => 'new_c'),
62+
)),
63+
$this->createOperation(
64+
new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'), 'messages+intl-icu' => array('d' => 'old_d'))),
65+
new MessageCatalogue('en', array('messages+intl-icu' => array('a' => 'new_a', 'c' => 'new_c')))
66+
)->getResult()
67+
);
68+
}
69+
5670
public function testGetResultWithMetadata()
5771
{
5872
$leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b')));

src/Symfony/Component/Translation/Tests/Catalogue/TargetOperationTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ public function testGetResultFromSingleDomain()
5353
);
5454
}
5555

56+
public function testGetResultFromIntlDomain()
57+
{
58+
$this->assertEquals(
59+
new MessageCatalogue('en', array(
60+
'messages' => array('a' => 'old_a'),
61+
'messages+intl-icu' => array('c' => 'new_c'),
62+
)),
63+
$this->createOperation(
64+
new MessageCatalogue('en', array('messages' => array('a' => 'old_a'), 'messages+intl-icu' => array('b' => 'old_b'))),
65+
new MessageCatalogue('en', array('messages' => array('a' => 'new_a'), 'messages+intl-icu' => array('c' => 'new_c')))
66+
)->getResult()
67+
);
68+
}
69+
5670
public function testGetResultWithMetadata()
5771
{
5872
$leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b')));

src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,30 @@ public function testDump()
3232
@unlink($tempDir.'/messages.en.concrete');
3333
}
3434

35+
public function testDumpIntl()
36+
{
37+
$tempDir = sys_get_temp_dir();
38+
39+
$catalogue = new MessageCatalogue('en');
40+
$catalogue->add(array('foo' => 'bar'), 'd1');
41+
$catalogue->add(array('bar' => 'foo'), 'd1+intl-icu');
42+
$catalogue->add(array('bar' => 'foo'), 'd2+intl-icu');
43+
44+
$dumper = new ConcreteFileDumper();
45+
@unlink($tempDir.'/d2.en.concrete');
46+
$dumper->dump($catalogue, array('path' => $tempDir));
47+
48+
$this->assertStringEqualsFile($tempDir.'/d1.en.concrete', 'foo=bar');
49+
@unlink($tempDir.'/d1.en.concrete');
50+
51+
$this->assertStringEqualsFile($tempDir.'/d1+intl-icu.en.concrete', 'bar=foo');
52+
@unlink($tempDir.'/d1+intl-icu.en.concrete');
53+
54+
$this->assertFileNotExists($tempDir.'/d2.en.concrete');
55+
$this->assertStringEqualsFile($tempDir.'/d2+intl-icu.en.concrete', 'bar=foo');
56+
@unlink($tempDir.'/d2+intl-icu.en.concrete');
57+
}
58+
3559
public function testDumpCreatesNestedDirectoriesAndFile()
3660
{
3761
$tempDir = sys_get_temp_dir();
@@ -56,7 +80,7 @@ class ConcreteFileDumper extends FileDumper
5680
{
5781
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
5882
{
59-
return '';
83+
return http_build_query($messages->all($domain), '', '&');
6084
}
6185

6286
protected function getExtension()

src/Symfony/Component/Translation/Tests/MessageCatalogueTest.php

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public function testGetLocale()
2525

2626
public function testGetDomains()
2727
{
28-
$catalogue = new MessageCatalogue('en', array('domain1' => array(), 'domain2' => array()));
28+
$catalogue = new MessageCatalogue('en', array('domain1' => array(), 'domain2' => array(), 'domain2+intl-icu' => array(), 'domain3+intl-icu' => array()));
2929

30-
$this->assertEquals(array('domain1', 'domain2'), $catalogue->getDomains());
30+
$this->assertEquals(array('domain1', 'domain2', 'domain3'), $catalogue->getDomains());
3131
}
3232

3333
public function testAll()
@@ -37,24 +37,43 @@ public function testAll()
3737
$this->assertEquals(array('foo' => 'foo'), $catalogue->all('domain1'));
3838
$this->assertEquals(array(), $catalogue->all('domain88'));
3939
$this->assertEquals($messages, $catalogue->all());
40+
41+
$messages = array('domain1+intl-icu' => array('foo' => 'bar')) + $messages + array(
42+
'domain2+intl-icu' => array('bar' => 'foo'),
43+
'domain3+intl-icu' => array('biz' => 'biz'),
44+
);
45+
$catalogue = new MessageCatalogue('en', $messages);
46+
47+
$this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
48+
$this->assertEquals(array('bar' => 'foo'), $catalogue->all('domain2'));
49+
$this->assertEquals(array('biz' => 'biz'), $catalogue->all('domain3'));
50+
51+
$messages = array(
52+
'domain1' => array('foo' => 'bar'),
53+
'domain2' => array('bar' => 'foo'),
54+
'domain3' => array('biz' => 'biz'),
55+
);
56+
$this->assertEquals($messages, $catalogue->all());
4057
}
4158

4259
public function testHas()
4360
{
44-
$catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
61+
$catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2+intl-icu' => array('bar' => 'bar')));
4562

4663
$this->assertTrue($catalogue->has('foo', 'domain1'));
64+
$this->assertTrue($catalogue->has('bar', 'domain2'));
4765
$this->assertFalse($catalogue->has('bar', 'domain1'));
4866
$this->assertFalse($catalogue->has('foo', 'domain88'));
4967
}
5068

5169
public function testGetSet()
5270
{
53-
$catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
71+
$catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar'), 'domain2+intl-icu' => array('bar' => 'foo')));
5472
$catalogue->set('foo1', 'foo1', 'domain1');
5573

5674
$this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
5775
$this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
76+
$this->assertEquals('foo', $catalogue->get('bar', 'domain2'));
5877
}
5978

6079
public function testAdd()
@@ -75,7 +94,7 @@ public function testAdd()
7594

7695
public function testReplace()
7796
{
78-
$catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
97+
$catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain1+intl-icu' => array('bar' => 'bar')));
7998
$catalogue->replace($messages = array('foo1' => 'foo1'), 'domain1');
8099

81100
$this->assertEquals($messages, $catalogue->all('domain1'));
@@ -89,16 +108,18 @@ public function testAddCatalogue()
89108
$r1 = $this->getMockBuilder('Symfony\Component\Config\Resource\ResourceInterface')->getMock();
90109
$r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
91110

92-
$catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
111+
$catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo')));
93112
$catalogue->addResource($r);
94113

95-
$catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo1' => 'foo1')));
114+
$catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo1' => 'foo1'), 'domain2+intl-icu' => array('bar' => 'bar')));
96115
$catalogue1->addResource($r1);
97116

98117
$catalogue->addCatalogue($catalogue1);
99118

100119
$this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
101120
$this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
121+
$this->assertEquals('bar', $catalogue->get('bar', 'domain2'));
122+
$this->assertEquals('bar', $catalogue->get('bar', 'domain2+intl-icu'));
102123

103124
$this->assertEquals(array($r, $r1), $catalogue->getResources());
104125
}

src/Symfony/Component/Translation/Translator.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,7 @@ public function trans($id, array $parameters = array(), $domain = null, $locale
203203
$id = (string) $id;
204204
$catalogue = $this->getCatalogue($locale);
205205
$locale = $catalogue->getLocale();
206-
$intlDomain = $this->hasIntlFormatter ? $domain.IntlFormatterInterface::DOMAIN_SUFFIX : null;
207206
while (true) {
208-
if (null !== $intlDomain && $catalogue->defines($id, $intlDomain)) {
209-
return $this->formatter->formatIntl($catalogue->get($id, $intlDomain), $locale, $parameters);
210-
}
211207
if ($catalogue->defines($id, $domain)) {
212208
break;
213209
}
@@ -219,6 +215,10 @@ public function trans($id, array $parameters = array(), $domain = null, $locale
219215
}
220216
}
221217

218+
if ($this->hasIntlFormatter && $catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
219+
return $this->formatter->formatIntl($catalogue->get($id, $domain), $locale, $parameters);
220+
}
221+
222222
return $this->formatter->format($catalogue->get($id, $domain), $locale, $parameters);
223223
}
224224

0 commit comments

Comments
 (0)