Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 56cb7a5

Browse filesBrowse files
committed
[Translation] add gettext PO and MO Dumper
1 parent 2d53751 commit 56cb7a5
Copy full SHA for 56cb7a5

File tree

5 files changed

+204
-0
lines changed
Filter options

5 files changed

+204
-0
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
<parameter key="translation.loader.ini.class">Symfony\Component\Translation\Loader\IniFileLoader</parameter>
2020
<parameter key="translation.dumper.php.class">Symfony\Component\Translation\Dumper\PhpFileDumper</parameter>
2121
<parameter key="translation.dumper.xliff.class">Symfony\Component\Translation\Dumper\XliffFileDumper</parameter>
22+
<parameter key="translation.dumper.po.class">Symfony\Component\Translation\Dumper\PoFileDumper</parameter>
23+
<parameter key="translation.dumper.mo.class">Symfony\Component\Translation\Dumper\MoFileDumper</parameter>
2224
<parameter key="translation.dumper.yml.class">Symfony\Component\Translation\Dumper\YamlFileDumper</parameter>
2325
<parameter key="translation.dumper.qt.class">Symfony\Component\Translation\Dumper\QtFileDumper</parameter>
2426
<parameter key="translation.dumper.csv.class">Symfony\Component\Translation\Dumper\CsvFileDumper</parameter>
@@ -90,6 +92,14 @@
9092
<tag name="translation.dumper" alias="xliff" />
9193
</service>
9294

95+
<service id="translation.dumper.po" class="%translation.dumper.po.class%">
96+
<tag name="translation.dumper" alias="po" />
97+
</service>
98+
99+
<service id="translation.dumper.mo" class="%translation.dumper.mo.class%">
100+
<tag name="translation.dumper" alias="mo" />
101+
</service>
102+
93103
<service id="translation.dumper.yml" class="%translation.dumper.yml.class%">
94104
<tag name="translation.dumper" alias="yml" />
95105
</service>
+82Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Dumper;
13+
14+
use Symfony\Component\Translation\MessageCatalogue;
15+
use Symfony\Component\Translation\Loader\MoFileLoader;
16+
17+
/**
18+
* MoFileDumper generates a gettext formated string representation of a message catalogue.
19+
*
20+
* @author Stealth35
21+
*/
22+
class MoFileDumper extends FileDumper
23+
{
24+
/**
25+
* {@inheritDoc}
26+
*/
27+
public function format(MessageCatalogue $messages, $domain = 'messages')
28+
{
29+
$output = $sources = $targets = $source_offsets = $target_offsets = '';
30+
$offsets = array();
31+
$size = 0;
32+
33+
foreach ($messages->all($domain) as $source => $target) {
34+
$offsets[] = array_map('strlen', array($sources, $source, $targets, $target));
35+
$sources .= "\0".$source;
36+
$targets .= "\0".$target;
37+
++$size;
38+
}
39+
40+
$header = array(
41+
'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC,
42+
'formatRevision' => 0,
43+
'count' => $size,
44+
'offsetId' => MoFileLoader::MO_HEADER_SIZE,
45+
'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size),
46+
'sizeHashes' => 0,
47+
'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size),
48+
);
49+
50+
$sources_size = strlen($sources);
51+
$sources_start = $header['offsetHashes'] + 1;
52+
53+
foreach ($offsets as $offset) {
54+
$source_offsets .= $this->writeLong($offset[1])
55+
. $this->writeLong($offset[0] + $sources_start);
56+
$target_offsets .= $this->writeLong($offset[3])
57+
. $this->writeLong($offset[2] + $sources_start + $sources_size);
58+
}
59+
60+
$output = implode(array_map(array($this, 'writeLong'), $header))
61+
. $source_offsets
62+
. $target_offsets
63+
. $sources
64+
. $targets
65+
;
66+
67+
return $output;
68+
}
69+
70+
/**
71+
* {@inheritDoc}
72+
*/
73+
protected function getExtension()
74+
{
75+
return 'mo';
76+
}
77+
78+
private function writeLong($str)
79+
{
80+
return pack('V*', $str);
81+
}
82+
}
+50Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Dumper;
13+
14+
use Symfony\Component\Translation\MessageCatalogue;
15+
16+
/**
17+
* PoFileDumper generates a gettext formated string representation of a message catalogue.
18+
*
19+
* @author Stealth35
20+
*/
21+
class PoFileDumper extends FileDumper
22+
{
23+
/**
24+
* {@inheritDoc}
25+
*/
26+
public function format(MessageCatalogue $messages, $domain = 'messages')
27+
{
28+
$output = '';
29+
30+
foreach ($messages->all($domain) as $source => $target) {
31+
$output .= sprintf("msgid \"%s\"\n", $this->escape($source));
32+
$output .= sprintf("msgstr \"%s\"\n\n", $this->escape($target));
33+
}
34+
35+
return $output;
36+
}
37+
38+
/**
39+
* {@inheritDoc}
40+
*/
41+
protected function getExtension()
42+
{
43+
return 'po';
44+
}
45+
46+
private function escape($str)
47+
{
48+
return addcslashes($str, "\0..\37\42\134");
49+
}
50+
}
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Tests\Component\Translation\Dumper;
13+
14+
use Symfony\Component\Translation\MessageCatalogue;
15+
use Symfony\Component\Translation\Dumper\MoFileDumper;
16+
17+
class MoFileDumperTest extends \PHPUnit_Framework_TestCase
18+
{
19+
public function testDump()
20+
{
21+
$catalogue = new MessageCatalogue('en');
22+
$catalogue->add(array('foo' => 'bar'));
23+
24+
$tempDir = sys_get_temp_dir();
25+
$dumper = new MoFileDumper();
26+
$dumperString = $dumper->dump($catalogue, array('path' => $tempDir));
27+
$this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.mo'), file_get_contents($tempDir.'/messages.en.mo'));
28+
29+
unlink($tempDir.'/messages.en.mo');
30+
}
31+
}
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Tests\Component\Translation\Dumper;
13+
14+
use Symfony\Component\Translation\MessageCatalogue;
15+
use Symfony\Component\Translation\Dumper\PoFileDumper;
16+
17+
class PoFileDumperTest extends \PHPUnit_Framework_TestCase
18+
{
19+
public function testDump()
20+
{
21+
$catalogue = new MessageCatalogue('en');
22+
$catalogue->add(array('foo' => 'bar'));
23+
24+
$tempDir = sys_get_temp_dir();
25+
$dumper = new PoFileDumper();
26+
$dumperString = $dumper->dump($catalogue, array('path' => $tempDir));
27+
$this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.po'), file_get_contents($tempDir.'/messages.en.po'));
28+
29+
unlink($tempDir.'/messages.en.po');
30+
}
31+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.