Skip to content

Commit

Permalink
[Translation] added the component
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Sep 27, 2010
1 parent 6317ddf commit a753790
Show file tree
Hide file tree
Showing 16 changed files with 3,786 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/Symfony/Component/Translation/Loader/ArrayLoader.php
@@ -0,0 +1,33 @@
<?php

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\MessageCatalogue;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* ArrayLoader loads translations from a PHP array.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class ArrayLoader implements LoaderInterface
{
/**
* {@inheritdoc}
*/
function load($resource, $locale, $domain = 'messages')
{
$catalogue = new MessageCatalogue($locale);
$catalogue->addMessages($resource, $domain);

return $catalogue;
}
}
33 changes: 33 additions & 0 deletions src/Symfony/Component/Translation/Loader/LoaderInterface.php
@@ -0,0 +1,33 @@
<?php

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\MessageCatalogue;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* LoaderInterface is the interface implemented by all translation loaders.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface LoaderInterface
{
/**
* Loads a locale.
*
* @param mixed $resource A resource
* @param string $locale A locale
* @param string $domain The domain
*
* @return MessageCatalogue A MessageCatalogue instance
*/
function load($resource, $locale, $domain = 'messages');
}
35 changes: 35 additions & 0 deletions src/Symfony/Component/Translation/Loader/PhpFileLoader.php
@@ -0,0 +1,35 @@
<?php

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Resource\FileResource;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* PhpFileLoader loads translations from PHP files returning an array of translations.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class PhpFileLoader implements LoaderInterface
{
/**
* {@inheritdoc}
*/
function load($resource, $locale, $domain = 'messages')
{
$catalogue = new MessageCatalogue($locale);
$catalogue->addMessages(require($resource), $domain);
$catalogue->addResource(new FileResource($resource));

return $catalogue;
}
}
96 changes: 96 additions & 0 deletions src/Symfony/Component/Translation/Loader/XliffFileLoader.php
@@ -0,0 +1,96 @@
<?php

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Resource\FileResource;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* XliffFileLoader loads translations from XLIFF files.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class XliffFileLoader implements LoaderInterface
{
/**
* {@inheritdoc}
*/
function load($resource, $locale, $domain = 'messages')
{
$xml = $this->parseFile($resource);
$xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');

$catalogue = new MessageCatalogue($locale);
foreach ($xml->xpath('//xliff:trans-unit') as $translation) {
$catalogue->setMessage((string) $translation->source, (string) $translation->target, $domain);
}
$catalogue->addResource(new FileResource($resource));

return $catalogue;
}

/**
* Validates and parses the given file into a SimpleXMLElement
*
* @param string $file
* @return SimpleXMLElement
*/
protected function parseFile($file)
{
$dom = new \DOMDocument();
$current = libxml_use_internal_errors(true);
if (!@$dom->load($file, LIBXML_COMPACT)) {
throw new \Exception(implode("\n", $this->getXmlErrors()));
}

$parts = explode('/', str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd');
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
$location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));

$source = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-1.2-strict.xsd');
$source = str_replace('http://www.w3.org/2001/xml.xsd', $location, $source);

if (!@$dom->schemaValidateSource($source)) {
throw new \Exception(implode("\n", $this->getXmlErrors()));
}
$dom->validateOnParse = true;
$dom->normalizeDocument();
libxml_use_internal_errors($current);

return simplexml_import_dom($dom);
}

/**
* Returns the XML errors of the internal XML parser
*
* @return array An array of errors
*/
protected 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;
}
}

1 comment on commit a753790

@webmozart
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are the catalog classes and methods spelled "Catalogue"? We use american spelling everywhere else (ex. "serialize" instead of "serialise"), shouldn't we use american spelling here too?

Please sign in to comment.