merged branch beberlei/QtTranslations (PR #1154)

Commits
-------

f2761dd Fix typo and include suggestion by Stof
4ac380e Adjust QtTranslations patch and include QtTranslationsDumper + test aswell
5712798 Adjust QtTranslationLoader to throw RuntimeException
21b29c2 Merge symfony/master
6bf43a1 [Translation] Add .ts as file extension to search for Qt Translation files.
5808715 [Translation] Add Qt Translation component with tests

Discussion
----------

[2.1] Qt translations

Add support for QT translations - it has a GUI and www.crowdin.net supports it.

---------------------------------------------------------------------------

by stof at 2011/05/30 07:24:48 -0700

You also need to register it in FrameworkBundle.

---------------------------------------------------------------------------

by tristanbes at 2011/06/26 12:08:47 -0700

crowdin seems to be a cool service. didn't know about this website. thanks

---------------------------------------------------------------------------

by fabpot at 2011/07/11 02:58:31 -0700

Just for the record: I've just removed all usage of `\Exception` in Symfony2 master:

6a7359389d

---------------------------------------------------------------------------

by beberlei at 2011/07/11 03:02:14 -0700

I will adjust the PR.

---------------------------------------------------------------------------

by tristanbes at 2011/08/28 11:10:02 -0700

Any news @beberlei ?

---------------------------------------------------------------------------

by beberlei at 2011/08/29 01:07:28 -0700

Yes, i have to allocate some time. Havent managed to do so yet.

---------------------------------------------------------------------------

by stof at 2011/09/04 05:28:16 -0700

@beberlei the PR also need to be rebased as it conflicts with master.
This commit is contained in:
Fabien Potencier 2011-09-06 08:00:21 +02:00
commit 6c9331650f
6 changed files with 202 additions and 0 deletions

View File

@ -11,9 +11,11 @@
<parameter key="translation.loader.php.class">Symfony\Component\Translation\Loader\PhpFileLoader</parameter>
<parameter key="translation.loader.yml.class">Symfony\Component\Translation\Loader\YamlFileLoader</parameter>
<parameter key="translation.loader.xliff.class">Symfony\Component\Translation\Loader\XliffFileLoader</parameter>
<parameter key="translation.loader.qt.class">Symfony\Component\Translation\Loader\QtTranslationsLoader</parameter>
<parameter key="translation.dumper.php.class">Symfony\Component\Translation\Dumper\PhpDumper</parameter>
<parameter key="translation.dumper.xliff.class">Symfony\Component\Translation\Dumper\XliffDumper</parameter>
<parameter key="translation.dumper.yml.class">Symfony\Component\Translation\Dumper\YamlDumper</parameter>
<parameter key="translation.dumper.qt.class">Symfony\Component\Translation\Dumper\QtTranslationsDumper</parameter>
</parameters>
<services>
@ -46,6 +48,10 @@
<tag name="translation.loader" alias="xliff" />
</service>
<service id="translation.loader.qt" class="%translation.loader.qt.class%">
<tag name="translation.loader" alias="ts" />
</service>
<service id="translation.dumper.php" class="%translation.dumper.php.class%">
<tag name="translation.dumper" alias="php" />
</service>
@ -57,5 +63,9 @@
<service id="translation.dumper.yml" class="%translation.dumper.yml.class%">
<tag name="translation.dumper" alias="yml" />
</service>
<service id="translation.dumper.qt" class="%translation.dumper.qt.class%">
<tag name="translation.dumper" alias="ts" />
</service>
</services>
</container>

View File

@ -0,0 +1,39 @@
<?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;
/**
* QtTranslationsDumper generates a TS/XML formated string representation of a message catalogue
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class QtTranslationsDumper implements DumperInterface
{
public function dump(MessageCatalogue $messages, $domain = 'messages')
{
$dom = new \DOMDocument('1.0', 'utf-8');
$dom->formatOutput = true;
$ts = $dom->appendChild($dom->createElement('TS'));
$context = $ts->appendChild($dom->createElement('context'));
$context->appendChild($dom->createElement('name', $domain));
foreach ($messages->all($domain) as $source => $target) {
$message = $context->appendChild($dom->createElement('message'));
$message->appendChild($dom->createElement('source', $source));
$message->appendChild($dom->createElement('translation', $target));
}
return $dom->saveXML();
}
}

View File

@ -0,0 +1,85 @@
<?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\Loader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Translation\MessageCatalogue;
/**
* QtTranslationsLoader loads translations from QT Translations XML files.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
*
* @api
*/
class QtTranslationsLoader implements LoaderInterface
{
/**
* {@inheritdoc}
*
* @api
*/
public function load($resource, $locale, $domain = 'messages')
{
$dom = new \DOMDocument();
$current = libxml_use_internal_errors(true);
if (!@$dom->load($resource, LIBXML_COMPACT)) {
throw new \RuntimeException(implode("\n", $this->getXmlErrors()));
}
$xpath = new \DOMXPath($dom);
$nodes = $xpath->evaluate('//TS/context/name[text()="'.$domain.'"]');
$catalogue = new MessageCatalogue($locale);
if ($nodes->length == 1) {
$translations = $nodes->item(0)->nextSibling->parentNode->parentNode->getElementsByTagName('message');
foreach ($translations as $translation) {
$catalogue->set(
(string) $translation->getElementsByTagName('source')->item(0)->nodeValue,
(string) $translation->getElementsByTagName('translation')->item(0)->nodeValue,
$domain
);
$translation = $translation->nextSibling;
}
$catalogue->addResource(new FileResource($resource));
}
libxml_use_internal_errors($current);
return $catalogue;
}
/**
* Returns the XML errors of the internal XML parser
*
* @return array An array of errors
*/
private function getXmlErrors()
{
$errors = array();
foreach (libxml_get_errors() as $error) {
$errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
$error->code,
trim($error->message),
$error->file ? $error->file : 'n/a',
$error->line,
$error->column
);
}
libxml_clear_errors();
libxml_use_internal_errors(false);
return $errors;
}
}

View File

@ -0,0 +1,29 @@
<?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\QtTranslationsDumper;
class QtTranslationsDumperTest extends \PHPUnit_Framework_TestCase
{
public function testDump()
{
$catalogue = new MessageCatalogue('en');
$catalogue->add(array('foo' => 'bar'), 'resources');
$dumper = new QtTranslationsDumper();
$dumperString = $dumper->dump($catalogue, 'resources');
$this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.ts'), $dumperString);
}
}

View File

@ -0,0 +1,29 @@
<?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\Loader;
use Symfony\Component\Translation\Loader\QtTranslationsLoader;
use Symfony\Component\Config\Resource\FileResource;
class QtTranslationsLoaderTest extends \PHPUnit_Framework_TestCase
{
public function testLoad()
{
$loader = new QtTranslationsLoader();
$resource = __DIR__.'/../fixtures/resources.ts';
$catalogue = $loader->load($resource, 'en', 'resources');
$this->assertEquals(array('foo' => 'bar'), $catalogue->all('resources'));
$this->assertEquals('en', $catalogue->getLocale());
$this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
}
}

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<TS>
<context>
<name>resources</name>
<message>
<source>foo</source>
<translation>bar</translation>
</message>
</context>
</TS>