diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index 32eed76e608a7..4d9b96b8f64e2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -19,6 +19,8 @@ Symfony\Component\Translation\Loader\IniFileLoader Symfony\Component\Translation\Dumper\PhpFileDumper Symfony\Component\Translation\Dumper\XliffFileDumper + Symfony\Component\Translation\Dumper\PoFileDumper + Symfony\Component\Translation\Dumper\MoFileDumper Symfony\Component\Translation\Dumper\YamlFileDumper Symfony\Component\Translation\Dumper\QtFileDumper Symfony\Component\Translation\Dumper\CsvFileDumper @@ -90,6 +92,14 @@ + + + + + + + + diff --git a/src/Symfony/Component/Translation/Dumper/MoFileDumper.php b/src/Symfony/Component/Translation/Dumper/MoFileDumper.php new file mode 100644 index 0000000000000..84eafa33ae711 --- /dev/null +++ b/src/Symfony/Component/Translation/Dumper/MoFileDumper.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Loader\MoFileLoader; + +/** + * MoFileDumper generates a gettext formated string representation of a message catalogue. + * + * @author Stealth35 + */ +class MoFileDumper extends FileDumper +{ + /** + * {@inheritDoc} + */ + public function format(MessageCatalogue $messages, $domain = 'messages') + { + $output = $sources = $targets = $source_offsets = $target_offsets = ''; + $offsets = array(); + $size = 0; + + foreach ($messages->all($domain) as $source => $target) { + $offsets[] = array_map('strlen', array($sources, $source, $targets, $target)); + $sources .= "\0".$source; + $targets .= "\0".$target; + ++$size; + } + + $header = array( + 'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC, + 'formatRevision' => 0, + 'count' => $size, + 'offsetId' => MoFileLoader::MO_HEADER_SIZE, + 'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size), + 'sizeHashes' => 0, + 'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size), + ); + + $sources_size = strlen($sources); + $sources_start = $header['offsetHashes'] + 1; + + foreach ($offsets as $offset) { + $source_offsets .= $this->writeLong($offset[1]) + . $this->writeLong($offset[0] + $sources_start); + $target_offsets .= $this->writeLong($offset[3]) + . $this->writeLong($offset[2] + $sources_start + $sources_size); + } + + $output = implode(array_map(array($this, 'writeLong'), $header)) + . $source_offsets + . $target_offsets + . $sources + . $targets + ; + + return $output; + } + + /** + * {@inheritDoc} + */ + protected function getExtension() + { + return 'mo'; + } + + private function writeLong($str) + { + return pack('V*', $str); + } +} diff --git a/src/Symfony/Component/Translation/Dumper/PoFileDumper.php b/src/Symfony/Component/Translation/Dumper/PoFileDumper.php new file mode 100644 index 0000000000000..82e26b9e0d483 --- /dev/null +++ b/src/Symfony/Component/Translation/Dumper/PoFileDumper.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; + +/** + * PoFileDumper generates a gettext formated string representation of a message catalogue. + * + * @author Stealth35 + */ +class PoFileDumper extends FileDumper +{ + /** + * {@inheritDoc} + */ + public function format(MessageCatalogue $messages, $domain = 'messages') + { + $output = ''; + + foreach ($messages->all($domain) as $source => $target) { + $output .= sprintf("msgid \"%s\"\n", $this->escape($source)); + $output .= sprintf("msgstr \"%s\"\n\n", $this->escape($target)); + } + + return $output; + } + + /** + * {@inheritDoc} + */ + protected function getExtension() + { + return 'po'; + } + + private function escape($str) + { + return addcslashes($str, "\0..\37\42\134"); + } +} diff --git a/tests/Symfony/Tests/Component/Translation/Dumper/MoFileDumperTest.php b/tests/Symfony/Tests/Component/Translation/Dumper/MoFileDumperTest.php new file mode 100644 index 0000000000000..34a309e13b72a --- /dev/null +++ b/tests/Symfony/Tests/Component/Translation/Dumper/MoFileDumperTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\MoFileDumper; + +class MoFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testDump() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $tempDir = sys_get_temp_dir(); + $dumper = new MoFileDumper(); + $dumperString = $dumper->dump($catalogue, array('path' => $tempDir)); + $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.mo'), file_get_contents($tempDir.'/messages.en.mo')); + + unlink($tempDir.'/messages.en.mo'); + } +} diff --git a/tests/Symfony/Tests/Component/Translation/Dumper/PoFileDumperTest.php b/tests/Symfony/Tests/Component/Translation/Dumper/PoFileDumperTest.php new file mode 100644 index 0000000000000..bc4491351842e --- /dev/null +++ b/tests/Symfony/Tests/Component/Translation/Dumper/PoFileDumperTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\PoFileDumper; + +class PoFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testDump() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $tempDir = sys_get_temp_dir(); + $dumper = new PoFileDumper(); + $dumperString = $dumper->dump($catalogue, array('path' => $tempDir)); + $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.po'), file_get_contents($tempDir.'/messages.en.po')); + + unlink($tempDir.'/messages.en.po'); + } +}