Skip to content

Commit

Permalink
merged branch stealth35/gettext_dumper (PR #2590)
Browse files Browse the repository at this point in the history
Commits
-------

56cb7a5 [Translation] add gettext PO and MO Dumper

Discussion
----------

[Translation] add gettext PO and MO Dumper

See #2412

    Bug fix: no
    Feature addition: yes
    Backwards compatibility break: no
    Symfony2 tests pass: yes
    Fixes the following tickets: -
  • Loading branch information
fabpot committed Nov 10, 2011
2 parents 2d53751 + 56cb7a5 commit 5882a98
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 0 deletions.
Expand Up @@ -19,6 +19,8 @@
<parameter key="translation.loader.ini.class">Symfony\Component\Translation\Loader\IniFileLoader</parameter>
<parameter key="translation.dumper.php.class">Symfony\Component\Translation\Dumper\PhpFileDumper</parameter>
<parameter key="translation.dumper.xliff.class">Symfony\Component\Translation\Dumper\XliffFileDumper</parameter>
<parameter key="translation.dumper.po.class">Symfony\Component\Translation\Dumper\PoFileDumper</parameter>
<parameter key="translation.dumper.mo.class">Symfony\Component\Translation\Dumper\MoFileDumper</parameter>
<parameter key="translation.dumper.yml.class">Symfony\Component\Translation\Dumper\YamlFileDumper</parameter>
<parameter key="translation.dumper.qt.class">Symfony\Component\Translation\Dumper\QtFileDumper</parameter>
<parameter key="translation.dumper.csv.class">Symfony\Component\Translation\Dumper\CsvFileDumper</parameter>
Expand Down Expand Up @@ -90,6 +92,14 @@
<tag name="translation.dumper" alias="xliff" />
</service>

<service id="translation.dumper.po" class="%translation.dumper.po.class%">
<tag name="translation.dumper" alias="po" />
</service>

<service id="translation.dumper.mo" class="%translation.dumper.mo.class%">
<tag name="translation.dumper" alias="mo" />
</service>

<service id="translation.dumper.yml" class="%translation.dumper.yml.class%">
<tag name="translation.dumper" alias="yml" />
</service>
Expand Down
82 changes: 82 additions & 0 deletions src/Symfony/Component/Translation/Dumper/MoFileDumper.php
@@ -0,0 +1,82 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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);
}
}
50 changes: 50 additions & 0 deletions src/Symfony/Component/Translation/Dumper/PoFileDumper.php
@@ -0,0 +1,50 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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");
}
}
@@ -0,0 +1,31 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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');
}
}
@@ -0,0 +1,31 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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');
}
}

0 comments on commit 5882a98

Please sign in to comment.