Update to Drupal 8.1.0. For more information, see https://www.drupal.org/drupal-8.1.0-release-notes
This commit is contained in:
parent
b11a755ba8
commit
c0a0d5a94c
6920 changed files with 64395 additions and 57312 deletions
16
vendor/symfony/translation/CHANGELOG.md
vendored
16
vendor/symfony/translation/CHANGELOG.md
vendored
|
@ -1,6 +1,22 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.8.0
|
||||
-----
|
||||
|
||||
* deprecated FileDumper::format(), overwrite FileDumper::formatCatalogue() instead.
|
||||
* deprecated Translator::getMessages(), rely on TranslatorBagInterface::getCatalogue() instead.
|
||||
* added `FileDumper::formatCatalogue` which allows format the catalogue without dumping it into file.
|
||||
* added option `json_encoding` to JsonFileDumper
|
||||
* added options `as_tree`, `inline` to YamlFileDumper
|
||||
* added support for XLIFF 2.0.
|
||||
* added support for XLIFF target and tool attributes.
|
||||
* added message parameters to DataCollectorTranslator.
|
||||
* [DEPRECATION] The `DiffOperation` class has been deprecated and
|
||||
will be removed in Symfony 3.0, since its operation has nothing to do with 'diff',
|
||||
so the class name is misleading. The `TargetOperation` class should be used for
|
||||
this use-case instead.
|
||||
|
||||
2.7.0
|
||||
-----
|
||||
|
||||
|
|
|
@ -17,38 +17,60 @@ use Symfony\Component\Translation\MessageCatalogueInterface;
|
|||
/**
|
||||
* Base catalogues binary operation class.
|
||||
*
|
||||
* A catalogue binary operation performs operation on
|
||||
* source (the left argument) and target (the right argument) catalogues.
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*/
|
||||
abstract class AbstractOperation implements OperationInterface
|
||||
{
|
||||
/**
|
||||
* @var MessageCatalogueInterface
|
||||
* @var MessageCatalogueInterface The source catalogue
|
||||
*/
|
||||
protected $source;
|
||||
|
||||
/**
|
||||
* @var MessageCatalogueInterface
|
||||
* @var MessageCatalogueInterface The target catalogue
|
||||
*/
|
||||
protected $target;
|
||||
|
||||
/**
|
||||
* @var MessageCatalogue
|
||||
* @var MessageCatalogue The result catalogue
|
||||
*/
|
||||
protected $result;
|
||||
|
||||
/**
|
||||
* @var null|array
|
||||
* @var null|array The domains affected by this operation
|
||||
*/
|
||||
private $domains;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* This array stores 'all', 'new' and 'obsolete' messages for all valid domains.
|
||||
*
|
||||
* The data structure of this array is as follows:
|
||||
* ```php
|
||||
* array(
|
||||
* 'domain 1' => array(
|
||||
* 'all' => array(...),
|
||||
* 'new' => array(...),
|
||||
* 'obsolete' => array(...)
|
||||
* ),
|
||||
* 'domain 2' => array(
|
||||
* 'all' => array(...),
|
||||
* 'new' => array(...),
|
||||
* 'obsolete' => array(...)
|
||||
* ),
|
||||
* ...
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @var array The array that stores 'all', 'new' and 'obsolete' messages
|
||||
*/
|
||||
protected $messages;
|
||||
|
||||
/**
|
||||
* @param MessageCatalogueInterface $source
|
||||
* @param MessageCatalogueInterface $target
|
||||
* @param MessageCatalogueInterface $source The source catalogue
|
||||
* @param MessageCatalogueInterface $target The target catalogue
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
|
@ -140,7 +162,10 @@ abstract class AbstractOperation implements OperationInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $domain
|
||||
* Performs operation on source and target catalogues for the given domain and
|
||||
* stores the results.
|
||||
*
|
||||
* @param string $domain The domain which the operation will be performed for
|
||||
*/
|
||||
abstract protected function processDomain($domain);
|
||||
}
|
||||
|
|
|
@ -11,45 +11,23 @@
|
|||
|
||||
namespace Symfony\Component\Translation\Catalogue;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\DiffOperation class is deprecated since version 2.8 and will be removed in 3.0. Use the TargetOperation class in the same namespace instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Diff operation between two catalogues.
|
||||
*
|
||||
* The name of 'Diff' is misleading because the operation
|
||||
* has nothing to do with diff:
|
||||
*
|
||||
* intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target}
|
||||
* all = intersection ∪ (target ∖ intersection) = target
|
||||
* new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
|
||||
* obsolete = source ∖ all = source ∖ target = {x: x ∈ source ∧ x ∉ target}
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0. Use TargetOperation instead.
|
||||
*/
|
||||
class DiffOperation extends AbstractOperation
|
||||
class DiffOperation extends TargetOperation
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processDomain($domain)
|
||||
{
|
||||
$this->messages[$domain] = array(
|
||||
'all' => array(),
|
||||
'new' => array(),
|
||||
'obsolete' => array(),
|
||||
);
|
||||
|
||||
foreach ($this->source->all($domain) as $id => $message) {
|
||||
if ($this->target->has($id, $domain)) {
|
||||
$this->messages[$domain]['all'][$id] = $message;
|
||||
$this->result->add(array($id => $message), $domain);
|
||||
if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
|
||||
$this->result->setMetadata($id, $keyMetadata, $domain);
|
||||
}
|
||||
} else {
|
||||
$this->messages[$domain]['obsolete'][$id] = $message;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->target->all($domain) as $id => $message) {
|
||||
if (!$this->source->has($id, $domain)) {
|
||||
$this->messages[$domain]['all'][$id] = $message;
|
||||
$this->messages[$domain]['new'][$id] = $message;
|
||||
$this->result->add(array($id => $message), $domain);
|
||||
if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
|
||||
$this->result->setMetadata($id, $keyMetadata, $domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,11 @@
|
|||
namespace Symfony\Component\Translation\Catalogue;
|
||||
|
||||
/**
|
||||
* Merge operation between two catalogues.
|
||||
* Merge operation between two catalogues as follows:
|
||||
* all = source ∪ target = {x: x ∈ source ∨ x ∈ target}
|
||||
* new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
|
||||
* obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ source ∧ x ∉ target} = ∅
|
||||
* Basically, the result contains messages from both catalogues.
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*/
|
||||
|
|
|
@ -16,6 +16,20 @@ use Symfony\Component\Translation\MessageCatalogueInterface;
|
|||
/**
|
||||
* Represents an operation on catalogue(s).
|
||||
*
|
||||
* An instance of this interface performs an operation on one or more catalogues and
|
||||
* stores intermediate and final results of the operation.
|
||||
*
|
||||
* The first catalogue in its argument(s) is called the 'source catalogue' or 'source' and
|
||||
* the following results are stored:
|
||||
*
|
||||
* Messages: also called 'all', are valid messages for the given domain after the operation is performed.
|
||||
*
|
||||
* New Messages: also called 'new' (new = all ∖ source = {x: x ∈ all ∧ x ∉ source}).
|
||||
*
|
||||
* Obsolete Messages: also called 'obsolete' (obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ all}).
|
||||
*
|
||||
* Result: also called 'result', is the resulting catalogue for the given domain that holds the same messages as 'all'.
|
||||
*
|
||||
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
||||
*/
|
||||
interface OperationInterface
|
||||
|
@ -28,7 +42,7 @@ interface OperationInterface
|
|||
public function getDomains();
|
||||
|
||||
/**
|
||||
* Returns all valid messages after operation.
|
||||
* Returns all valid messages ('all') after operation.
|
||||
*
|
||||
* @param string $domain
|
||||
*
|
||||
|
@ -37,7 +51,7 @@ interface OperationInterface
|
|||
public function getMessages($domain);
|
||||
|
||||
/**
|
||||
* Returns new messages after operation.
|
||||
* Returns new messages ('new') after operation.
|
||||
*
|
||||
* @param string $domain
|
||||
*
|
||||
|
@ -46,7 +60,7 @@ interface OperationInterface
|
|||
public function getNewMessages($domain);
|
||||
|
||||
/**
|
||||
* Returns obsolete messages after operation.
|
||||
* Returns obsolete messages ('obsolete') after operation.
|
||||
*
|
||||
* @param string $domain
|
||||
*
|
||||
|
@ -55,7 +69,7 @@ interface OperationInterface
|
|||
public function getObsoleteMessages($domain);
|
||||
|
||||
/**
|
||||
* Returns resulting catalogue.
|
||||
* Returns resulting catalogue ('result').
|
||||
*
|
||||
* @return MessageCatalogueInterface
|
||||
*/
|
||||
|
|
69
vendor/symfony/translation/Catalogue/TargetOperation.php
vendored
Normal file
69
vendor/symfony/translation/Catalogue/TargetOperation.php
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?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\Catalogue;
|
||||
|
||||
/**
|
||||
* Target operation between two catalogues:
|
||||
* intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target}
|
||||
* all = intersection ∪ (target ∖ intersection) = target
|
||||
* new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
|
||||
* obsolete = source ∖ all = source ∖ target = {x: x ∈ source ∧ x ∉ target}
|
||||
* Basically, the result contains messages from the target catalogue.
|
||||
*
|
||||
* @author Michael Lee <michael.lee@zerustech.com>
|
||||
*/
|
||||
class TargetOperation extends AbstractOperation
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processDomain($domain)
|
||||
{
|
||||
$this->messages[$domain] = array(
|
||||
'all' => array(),
|
||||
'new' => array(),
|
||||
'obsolete' => array(),
|
||||
);
|
||||
|
||||
// For 'all' messages, the code can't be simplified as ``$this->messages[$domain]['all'] = $target->all($domain);``,
|
||||
// because doing so will drop messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
|
||||
//
|
||||
// For 'new' messages, the code can't be simplied as ``array_diff_assoc($this->target->all($domain), $this->source->all($domain));``
|
||||
// because doing so will not exclude messages like {x: x ∈ target ∧ x ∉ source.all ∧ x ∈ source.fallback}
|
||||
//
|
||||
// For 'obsolete' messages, the code can't be simplifed as ``array_diff_assoc($this->source->all($domain), $this->target->all($domain))``
|
||||
// because doing so will not exclude messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
|
||||
|
||||
foreach ($this->source->all($domain) as $id => $message) {
|
||||
if ($this->target->has($id, $domain)) {
|
||||
$this->messages[$domain]['all'][$id] = $message;
|
||||
$this->result->add(array($id => $message), $domain);
|
||||
if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
|
||||
$this->result->setMetadata($id, $keyMetadata, $domain);
|
||||
}
|
||||
} else {
|
||||
$this->messages[$domain]['obsolete'][$id] = $message;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->target->all($domain) as $id => $message) {
|
||||
if (!$this->source->has($id, $domain)) {
|
||||
$this->messages[$domain]['all'][$id] = $message;
|
||||
$this->messages[$domain]['new'][$id] = $message;
|
||||
$this->result->add(array($id => $message), $domain);
|
||||
if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
|
||||
$this->result->setMetadata($id, $keyMetadata, $domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -101,9 +101,14 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto
|
|||
|
||||
if (!isset($result[$messageId])) {
|
||||
$message['count'] = 1;
|
||||
$message['parameters'] = !empty($message['parameters']) ? array($message['parameters']) : array();
|
||||
$messages[$key]['translation'] = $this->sanitizeString($message['translation']);
|
||||
$result[$messageId] = $message;
|
||||
} else {
|
||||
if (!empty($message['parameters'])) {
|
||||
$result[$messageId]['parameters'][] = $message['parameters'];
|
||||
}
|
||||
|
||||
++$result[$messageId]['count'];
|
||||
}
|
||||
|
||||
|
@ -132,7 +137,7 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto
|
|||
{
|
||||
$string = trim(preg_replace('/\s+/', ' ', $string));
|
||||
|
||||
if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($string)) {
|
||||
if (false !== $encoding = mb_detect_encoding($string, null, true)) {
|
||||
if (mb_strlen($string, $encoding) > $length) {
|
||||
return mb_substr($string, 0, $length - 3, $encoding).'...';
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
|||
public function trans($id, array $parameters = array(), $domain = null, $locale = null)
|
||||
{
|
||||
$trans = $this->translator->trans($id, $parameters, $domain, $locale);
|
||||
$this->collectMessage($locale, $domain, $id, $trans);
|
||||
$this->collectMessage($locale, $domain, $id, $trans, $parameters);
|
||||
|
||||
return $trans;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
|||
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
|
||||
{
|
||||
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
|
||||
$this->collectMessage($locale, $domain, $id, $trans);
|
||||
$this->collectMessage($locale, $domain, $id, $trans, $parameters, $number);
|
||||
|
||||
return $trans;
|
||||
}
|
||||
|
@ -108,9 +108,11 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
|||
* @param string|null $locale
|
||||
* @param string|null $domain
|
||||
* @param string $id
|
||||
* @param string $trans
|
||||
* @param string $translation
|
||||
* @param array|null $parameters
|
||||
* @param int|null $number
|
||||
*/
|
||||
private function collectMessage($locale, $domain, $id, $translation)
|
||||
private function collectMessage($locale, $domain, $id, $translation, $parameters = array(), $number = null)
|
||||
{
|
||||
if (null === $domain) {
|
||||
$domain = 'messages';
|
||||
|
@ -142,6 +144,8 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
|||
'domain' => $domain,
|
||||
'id' => $id,
|
||||
'translation' => $translation,
|
||||
'parameters' => $parameters,
|
||||
'transChoiceNumber' => $number,
|
||||
'state' => $state,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,16 @@ class CsvFileDumper extends FileDumper
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(MessageCatalogue $messages, $domain = 'messages')
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
$handle = fopen('php://memory', 'rb+');
|
||||
|
||||
|
|
27
vendor/symfony/translation/Dumper/FileDumper.php
vendored
27
vendor/symfony/translation/Dumper/FileDumper.php
vendored
|
@ -82,10 +82,28 @@ abstract class FileDumper implements DumperInterface
|
|||
}
|
||||
}
|
||||
// save file
|
||||
file_put_contents($fullpath, $this->format($messages, $domain));
|
||||
file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a domain of a message catalogue to its string representation.
|
||||
*
|
||||
* Override this function in child class if $options is used for message formatting.
|
||||
*
|
||||
* @param MessageCatalogue $messages
|
||||
* @param string $domain
|
||||
* @param array $options
|
||||
*
|
||||
* @return string representation
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method will replace the format method in 3.0. You should overwrite it instead of overwriting format instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->format($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a domain of a message catalogue to its string representation.
|
||||
*
|
||||
|
@ -93,8 +111,13 @@ abstract class FileDumper implements DumperInterface
|
|||
* @param string $domain
|
||||
*
|
||||
* @return string representation
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0. Overwrite formatCatalogue() instead.
|
||||
*/
|
||||
abstract protected function format(MessageCatalogue $messages, $domain);
|
||||
protected function format(MessageCatalogue $messages, $domain)
|
||||
{
|
||||
throw new \LogicException('The "FileDumper::format" method needs to be overwritten, you should implement either "format" or "formatCatalogue".');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file extension of the dumper.
|
||||
|
|
|
@ -29,6 +29,16 @@ class IcuResFileDumper extends FileDumper
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(MessageCatalogue $messages, $domain = 'messages')
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
$data = $indexes = $resources = '';
|
||||
|
||||
|
@ -79,11 +89,7 @@ class IcuResFileDumper extends FileDumper
|
|||
1, 4, 0, 0 // Unicode version
|
||||
);
|
||||
|
||||
$output = $header
|
||||
.$root
|
||||
.$data;
|
||||
|
||||
return $output;
|
||||
return $header.$root.$data;
|
||||
}
|
||||
|
||||
private function writePadding($data)
|
||||
|
@ -97,9 +103,7 @@ class IcuResFileDumper extends FileDumper
|
|||
|
||||
private function getPosition($data)
|
||||
{
|
||||
$position = (strlen($data) + 28) / 4;
|
||||
|
||||
return $position;
|
||||
return (strlen($data) + 28) / 4;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,16 @@ class IniFileDumper extends FileDumper
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(MessageCatalogue $messages, $domain = 'messages')
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
$output = '';
|
||||
|
||||
|
|
|
@ -25,7 +25,23 @@ class JsonFileDumper extends FileDumper
|
|||
*/
|
||||
public function format(MessageCatalogue $messages, $domain = 'messages')
|
||||
{
|
||||
return json_encode($messages->all($domain), defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0);
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
if (isset($options['json_encoding'])) {
|
||||
$flags = $options['json_encoding'];
|
||||
} else {
|
||||
$flags = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0;
|
||||
}
|
||||
|
||||
return json_encode($messages->all($domain), $flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,16 @@ class MoFileDumper extends FileDumper
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(MessageCatalogue $messages, $domain = 'messages')
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
$output = $sources = $targets = $sourceOffsets = $targetOffsets = '';
|
||||
$offsets = array();
|
||||
|
|
|
@ -25,9 +25,17 @@ class PhpFileDumper extends FileDumper
|
|||
*/
|
||||
protected function format(MessageCatalogue $messages, $domain)
|
||||
{
|
||||
$output = "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $output;
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
return "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,16 @@ class PoFileDumper extends FileDumper
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(MessageCatalogue $messages, $domain = 'messages')
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
$output = 'msgid ""'."\n";
|
||||
$output .= 'msgstr ""'."\n";
|
||||
|
|
|
@ -24,6 +24,16 @@ class QtFileDumper extends FileDumper
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(MessageCatalogue $messages, $domain)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->formatOutput = true;
|
||||
|
|
|
@ -20,23 +20,30 @@ use Symfony\Component\Translation\MessageCatalogue;
|
|||
*/
|
||||
class XliffFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $defaultLocale;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dump(MessageCatalogue $messages, $options = array())
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
if (array_key_exists('default_locale', $options)) {
|
||||
$this->defaultLocale = $options['default_locale'];
|
||||
} else {
|
||||
$this->defaultLocale = \Locale::getDefault();
|
||||
$xliffVersion = '1.2';
|
||||
if (array_key_exists('xliff_version', $options)) {
|
||||
$xliffVersion = $options['xliff_version'];
|
||||
}
|
||||
|
||||
parent::dump($messages, $options);
|
||||
if (array_key_exists('default_locale', $options)) {
|
||||
$defaultLocale = $options['default_locale'];
|
||||
} else {
|
||||
$defaultLocale = \Locale::getDefault();
|
||||
}
|
||||
|
||||
if ('1.2' === $xliffVersion) {
|
||||
return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
|
||||
}
|
||||
if ('2.0' === $xliffVersion) {
|
||||
return $this->dumpXliff2($defaultLocale, $messages, $domain, $options);
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,6 +51,26 @@ class XliffFileDumper extends FileDumper
|
|||
*/
|
||||
protected function format(MessageCatalogue $messages, $domain)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
{
|
||||
return 'xlf';
|
||||
}
|
||||
|
||||
private function dumpXliff1($defaultLocale, MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
$toolInfo = array('tool-id' => 'symfony', 'tool-name' => 'Symfony');
|
||||
if (array_key_exists('tool_info', $options)) {
|
||||
$toolInfo = array_merge($toolInfo, $options['tool_info']);
|
||||
}
|
||||
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->formatOutput = true;
|
||||
|
||||
|
@ -52,11 +79,17 @@ class XliffFileDumper extends FileDumper
|
|||
$xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
|
||||
|
||||
$xliffFile = $xliff->appendChild($dom->createElement('file'));
|
||||
$xliffFile->setAttribute('source-language', str_replace('_', '-', $this->defaultLocale));
|
||||
$xliffFile->setAttribute('source-language', str_replace('_', '-', $defaultLocale));
|
||||
$xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
|
||||
$xliffFile->setAttribute('datatype', 'plaintext');
|
||||
$xliffFile->setAttribute('original', 'file.ext');
|
||||
|
||||
$xliffHead = $xliffFile->appendChild($dom->createElement('header'));
|
||||
$xliffTool = $xliffHead->appendChild($dom->createElement('tool'));
|
||||
foreach ($toolInfo as $id => $value) {
|
||||
$xliffTool->setAttribute($id, $value);
|
||||
}
|
||||
|
||||
$xliffBody = $xliffFile->appendChild($dom->createElement('body'));
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$translation = $dom->createElement('trans-unit');
|
||||
|
@ -70,11 +103,17 @@ class XliffFileDumper extends FileDumper
|
|||
// Does the target contain characters requiring a CDATA section?
|
||||
$text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
|
||||
|
||||
$t = $translation->appendChild($dom->createElement('target'));
|
||||
$targetElement = $dom->createElement('target');
|
||||
$metadata = $messages->getMetadata($source, $domain);
|
||||
if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
|
||||
foreach ($metadata['target-attributes'] as $name => $value) {
|
||||
$targetElement->setAttribute($name, $value);
|
||||
}
|
||||
}
|
||||
$t = $translation->appendChild($targetElement);
|
||||
$t->appendChild($text);
|
||||
|
||||
$metadata = $messages->getMetadata($source, $domain);
|
||||
if (null !== $metadata && array_key_exists('notes', $metadata) && is_array($metadata['notes'])) {
|
||||
if ($this->hasMetadataArrayInfo('notes', $metadata)) {
|
||||
foreach ($metadata['notes'] as $note) {
|
||||
if (!isset($note['content'])) {
|
||||
continue;
|
||||
|
@ -99,11 +138,56 @@ class XliffFileDumper extends FileDumper
|
|||
return $dom->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
private function dumpXliff2($defaultLocale, MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
return 'xlf';
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->formatOutput = true;
|
||||
|
||||
$xliff = $dom->appendChild($dom->createElement('xliff'));
|
||||
$xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
|
||||
$xliff->setAttribute('version', '2.0');
|
||||
$xliff->setAttribute('srcLang', str_replace('_', '-', $defaultLocale));
|
||||
$xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));
|
||||
|
||||
$xliffFile = $xliff->appendChild($dom->createElement('file'));
|
||||
$xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
|
||||
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$translation = $dom->createElement('unit');
|
||||
$translation->setAttribute('id', md5($source));
|
||||
|
||||
$segment = $translation->appendChild($dom->createElement('segment'));
|
||||
|
||||
$s = $segment->appendChild($dom->createElement('source'));
|
||||
$s->appendChild($dom->createTextNode($source));
|
||||
|
||||
// Does the target contain characters requiring a CDATA section?
|
||||
$text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
|
||||
|
||||
$targetElement = $dom->createElement('target');
|
||||
$metadata = $messages->getMetadata($source, $domain);
|
||||
if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
|
||||
foreach ($metadata['target-attributes'] as $name => $value) {
|
||||
$targetElement->setAttribute($name, $value);
|
||||
}
|
||||
}
|
||||
$t = $segment->appendChild($targetElement);
|
||||
$t->appendChild($text);
|
||||
|
||||
$xliffFile->appendChild($translation);
|
||||
}
|
||||
|
||||
return $dom->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array|null $metadata
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasMetadataArrayInfo($key, $metadata = null)
|
||||
{
|
||||
return null !== $metadata && array_key_exists($key, $metadata) && ($metadata[$key] instanceof \Traversable || is_array($metadata[$key]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
use Symfony\Component\Translation\Util\ArrayConverter;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
|
@ -24,13 +25,33 @@ class YamlFileDumper extends FileDumper
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function format(MessageCatalogue $messages, $domain)
|
||||
public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
|
||||
{
|
||||
if (!class_exists('Symfony\Component\Yaml\Yaml')) {
|
||||
throw new \LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.');
|
||||
}
|
||||
|
||||
return Yaml::dump($messages->all($domain));
|
||||
$data = $messages->all($domain);
|
||||
|
||||
if (isset($options['as_tree']) && $options['as_tree']) {
|
||||
$data = ArrayConverter::expandToTree($data);
|
||||
}
|
||||
|
||||
if (isset($options['inline']) && ($inline = (int) $options['inline']) > 0) {
|
||||
return Yaml::dump($data, $inline);
|
||||
}
|
||||
|
||||
return Yaml::dump($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function format(MessageCatalogue $messages, $domain)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->formatCatalogue($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
2
vendor/symfony/translation/LICENSE
vendored
2
vendor/symfony/translation/LICENSE
vendored
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2004-2015 Fabien Potencier
|
||||
Copyright (c) 2004-2016 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -11,16 +11,14 @@
|
|||
|
||||
namespace Symfony\Component\Translation\Loader;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
/**
|
||||
* CsvFileLoader loads translations from CSV files.
|
||||
*
|
||||
* @author Saša Stamenković <umpirsky@gmail.com>
|
||||
*/
|
||||
class CsvFileLoader extends ArrayLoader
|
||||
class CsvFileLoader extends FileLoader
|
||||
{
|
||||
private $delimiter = ';';
|
||||
private $enclosure = '"';
|
||||
|
@ -29,16 +27,8 @@ class CsvFileLoader extends ArrayLoader
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, $locale, $domain = 'messages')
|
||||
protected function loadResource($resource)
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
}
|
||||
|
||||
if (!file_exists($resource)) {
|
||||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
$messages = array();
|
||||
|
||||
try {
|
||||
|
@ -56,13 +46,7 @@ class CsvFileLoader extends ArrayLoader
|
|||
}
|
||||
}
|
||||
|
||||
$catalogue = parent::load($messages, $locale, $domain);
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
65
vendor/symfony/translation/Loader/FileLoader.php
vendored
Normal file
65
vendor/symfony/translation/Loader/FileLoader.php
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?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\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
/**
|
||||
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
|
||||
*/
|
||||
abstract class FileLoader extends ArrayLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, $locale, $domain = 'messages')
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
}
|
||||
|
||||
if (!file_exists($resource)) {
|
||||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
$messages = $this->loadResource($resource);
|
||||
|
||||
// empty resource
|
||||
if (null === $messages) {
|
||||
$messages = array();
|
||||
}
|
||||
|
||||
// not an array
|
||||
if (!is_array($messages)) {
|
||||
throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
|
||||
}
|
||||
|
||||
$catalogue = parent::load($messages, $locale, $domain);
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param string $resource
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws InvalidResourceException If stream content has an invalid format.
|
||||
*/
|
||||
abstract protected function loadResource($resource);
|
||||
}
|
|
@ -11,38 +11,18 @@
|
|||
|
||||
namespace Symfony\Component\Translation\Loader;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
/**
|
||||
* IniFileLoader loads translations from an ini file.
|
||||
*
|
||||
* @author stealth35
|
||||
*/
|
||||
class IniFileLoader extends ArrayLoader
|
||||
class IniFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, $locale, $domain = 'messages')
|
||||
protected function loadResource($resource)
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
}
|
||||
|
||||
if (!file_exists($resource)) {
|
||||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
$messages = parse_ini_file($resource, true);
|
||||
|
||||
$catalogue = parent::load($messages, $locale, $domain);
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
return parse_ini_file($resource, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,29 +12,19 @@
|
|||
namespace Symfony\Component\Translation\Loader;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
/**
|
||||
* JsonFileLoader loads translations from an json file.
|
||||
*
|
||||
* @author singles
|
||||
*/
|
||||
class JsonFileLoader extends ArrayLoader
|
||||
class JsonFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, $locale, $domain = 'messages')
|
||||
protected function loadResource($resource)
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
}
|
||||
|
||||
if (!file_exists($resource)) {
|
||||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
$messages = array();
|
||||
if ($data = file_get_contents($resource)) {
|
||||
$messages = json_decode($data, true);
|
||||
|
@ -44,14 +34,7 @@ class JsonFileLoader extends ArrayLoader
|
|||
}
|
||||
}
|
||||
|
||||
if (null === $messages) {
|
||||
$messages = array();
|
||||
}
|
||||
|
||||
$catalogue = parent::load($messages, $locale, $domain);
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
|
||||
return $catalogue;
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,13 +12,11 @@
|
|||
namespace Symfony\Component\Translation\Loader;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
|
||||
*/
|
||||
class MoFileLoader extends ArrayLoader
|
||||
class MoFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Magic used for validating the format of a MO file as well as
|
||||
|
@ -43,48 +41,13 @@ class MoFileLoader extends ArrayLoader
|
|||
*/
|
||||
const MO_HEADER_SIZE = 28;
|
||||
|
||||
public function load($resource, $locale, $domain = 'messages')
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
}
|
||||
|
||||
if (!file_exists($resource)) {
|
||||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
$messages = $this->parse($resource);
|
||||
|
||||
// empty file
|
||||
if (null === $messages) {
|
||||
$messages = array();
|
||||
}
|
||||
|
||||
// not an array
|
||||
if (!is_array($messages)) {
|
||||
throw new InvalidResourceException(sprintf('The file "%s" must contain a valid mo file.', $resource));
|
||||
}
|
||||
|
||||
$catalogue = parent::load($messages, $locale, $domain);
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses machine object (MO) format, independent of the machine's endian it
|
||||
* was created on. Both 32bit and 64bit systems are supported.
|
||||
*
|
||||
* @param resource $resource
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws InvalidResourceException If stream content has an invalid format.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
private function parse($resource)
|
||||
protected function loadResource($resource)
|
||||
{
|
||||
$stream = fopen($resource, 'r');
|
||||
|
||||
|
|
|
@ -11,38 +11,18 @@
|
|||
|
||||
namespace Symfony\Component\Translation\Loader;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
/**
|
||||
* PhpFileLoader loads translations from PHP files returning an array of translations.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class PhpFileLoader extends ArrayLoader
|
||||
class PhpFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, $locale, $domain = 'messages')
|
||||
protected function loadResource($resource)
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
}
|
||||
|
||||
if (!file_exists($resource)) {
|
||||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
$messages = require $resource;
|
||||
|
||||
$catalogue = parent::load($messages, $locale, $domain);
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
return require $resource;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,47 +11,12 @@
|
|||
|
||||
namespace Symfony\Component\Translation\Loader;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
|
||||
* @copyright Copyright (c) 2012, Clemens Tolboom
|
||||
*/
|
||||
class PoFileLoader extends ArrayLoader
|
||||
class PoFileLoader extends FileLoader
|
||||
{
|
||||
public function load($resource, $locale, $domain = 'messages')
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
}
|
||||
|
||||
if (!file_exists($resource)) {
|
||||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
$messages = $this->parse($resource);
|
||||
|
||||
// empty file
|
||||
if (null === $messages) {
|
||||
$messages = array();
|
||||
}
|
||||
|
||||
// not an array
|
||||
if (!is_array($messages)) {
|
||||
throw new InvalidResourceException(sprintf('The file "%s" must contain a valid po file.', $resource));
|
||||
}
|
||||
|
||||
$catalogue = parent::load($messages, $locale, $domain);
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses portable object (PO) format.
|
||||
*
|
||||
|
@ -93,11 +58,9 @@ class PoFileLoader extends ArrayLoader
|
|||
*
|
||||
* Items with an empty id are ignored.
|
||||
*
|
||||
* @param resource $resource
|
||||
*
|
||||
* @return array
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
private function parse($resource)
|
||||
protected function loadResource($resource)
|
||||
{
|
||||
$stream = fopen($resource, 'r');
|
||||
|
||||
|
@ -108,14 +71,20 @@ class PoFileLoader extends ArrayLoader
|
|||
|
||||
$messages = array();
|
||||
$item = $defaults;
|
||||
$flags = array();
|
||||
|
||||
while ($line = fgets($stream)) {
|
||||
$line = trim($line);
|
||||
|
||||
if ($line === '') {
|
||||
// Whitespace indicated current item is done
|
||||
$this->addMessage($messages, $item);
|
||||
if (!in_array('fuzzy', $flags)) {
|
||||
$this->addMessage($messages, $item);
|
||||
}
|
||||
$item = $defaults;
|
||||
$flags = array();
|
||||
} elseif (substr($line, 0, 2) === '#,') {
|
||||
$flags = array_map('trim', explode(',', substr($line, 2)));
|
||||
} elseif (substr($line, 0, 7) === 'msgid "') {
|
||||
// We start a new msg so save previous
|
||||
// TODO: this fails when comments or contexts are added
|
||||
|
@ -141,7 +110,9 @@ class PoFileLoader extends ArrayLoader
|
|||
}
|
||||
}
|
||||
// save last item
|
||||
$this->addMessage($messages, $item);
|
||||
if (!in_array('fuzzy', $flags)) {
|
||||
$this->addMessage($messages, $item);
|
||||
}
|
||||
fclose($stream);
|
||||
|
||||
return $messages;
|
||||
|
|
|
@ -37,10 +37,49 @@ class XliffFileLoader implements LoaderInterface
|
|||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
list($xml, $encoding) = $this->parseFile($resource);
|
||||
$xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
|
||||
|
||||
$catalogue = new MessageCatalogue($locale);
|
||||
$this->extract($resource, $catalogue, $domain);
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
}
|
||||
|
||||
private function extract($resource, MessageCatalogue $catalogue, $domain)
|
||||
{
|
||||
try {
|
||||
$dom = XmlUtils::loadFile($resource);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new InvalidResourceException(sprintf('Unable to load "%s": %s', $resource, $e->getMessage()), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
$xliffVersion = $this->getVersionNumber($dom);
|
||||
$this->validateSchema($xliffVersion, $dom, $this->getSchema($xliffVersion));
|
||||
|
||||
if ('1.2' === $xliffVersion) {
|
||||
$this->extractXliff1($dom, $catalogue, $domain);
|
||||
}
|
||||
|
||||
if ('2.0' === $xliffVersion) {
|
||||
$this->extractXliff2($dom, $catalogue, $domain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract messages and metadata from DOMDocument into a MessageCatalogue.
|
||||
*
|
||||
* @param \DOMDocument $dom Source to extract messages and metadata
|
||||
* @param MessageCatalogue $catalogue Catalogue where we'll collect messages and metadata
|
||||
* @param string $domain The domain
|
||||
*/
|
||||
private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, $domain)
|
||||
{
|
||||
$xml = simplexml_import_dom($dom);
|
||||
$encoding = strtoupper($dom->encoding);
|
||||
|
||||
$xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
|
||||
foreach ($xml->xpath('//xliff:trans-unit') as $translation) {
|
||||
$attributes = $translation->attributes();
|
||||
|
||||
|
@ -55,31 +94,52 @@ class XliffFileLoader implements LoaderInterface
|
|||
|
||||
$catalogue->set((string) $source, $target, $domain);
|
||||
|
||||
if (isset($translation->note)) {
|
||||
$notes = array();
|
||||
foreach ($translation->note as $xmlNote) {
|
||||
$noteAttributes = $xmlNote->attributes();
|
||||
$note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding));
|
||||
if (isset($noteAttributes['priority'])) {
|
||||
$note['priority'] = (int) $noteAttributes['priority'];
|
||||
}
|
||||
|
||||
if (isset($noteAttributes['from'])) {
|
||||
$note['from'] = (string) $noteAttributes['from'];
|
||||
}
|
||||
|
||||
$notes[] = $note;
|
||||
}
|
||||
|
||||
$catalogue->setMetadata((string) $source, array('notes' => $notes), $domain);
|
||||
$metadata = array();
|
||||
if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) {
|
||||
$metadata['notes'] = $notes;
|
||||
}
|
||||
if (isset($translation->target) && $translation->target->attributes()) {
|
||||
$metadata['target-attributes'] = array();
|
||||
foreach ($translation->target->attributes() as $key => $value) {
|
||||
$metadata['target-attributes'][$key] = (string) $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
$catalogue->setMetadata((string) $source, $metadata, $domain);
|
||||
}
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
/**
|
||||
* @param \DOMDocument $dom
|
||||
* @param MessageCatalogue $catalogue
|
||||
* @param string $domain
|
||||
*/
|
||||
private function extractXliff2(\DOMDocument $dom, MessageCatalogue $catalogue, $domain)
|
||||
{
|
||||
$xml = simplexml_import_dom($dom);
|
||||
$encoding = strtoupper($dom->encoding);
|
||||
|
||||
$xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:2.0');
|
||||
|
||||
foreach ($xml->xpath('//xliff:unit/xliff:segment') as $segment) {
|
||||
$source = $segment->source;
|
||||
|
||||
// If the xlf file has another encoding specified, try to convert it because
|
||||
// simple_xml will always return utf-8 encoded values
|
||||
$target = $this->utf8ToCharset((string) (isset($segment->target) ? $segment->target : $source), $encoding);
|
||||
|
||||
$catalogue->set((string) $source, $target, $domain);
|
||||
|
||||
$metadata = array();
|
||||
if (isset($segment->target) && $segment->target->attributes()) {
|
||||
$metadata['target-attributes'] = array();
|
||||
foreach ($segment->target->attributes() as $key => $value) {
|
||||
$metadata['target-attributes'][$key] = (string) $value;
|
||||
}
|
||||
}
|
||||
|
||||
$catalogue->setMetadata((string) $source, $metadata, $domain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,57 +153,24 @@ class XliffFileLoader implements LoaderInterface
|
|||
private function utf8ToCharset($content, $encoding = null)
|
||||
{
|
||||
if ('UTF-8' !== $encoding && !empty($encoding)) {
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($content, $encoding, 'UTF-8');
|
||||
}
|
||||
|
||||
if (function_exists('iconv')) {
|
||||
return iconv('UTF-8', $encoding, $content);
|
||||
}
|
||||
|
||||
throw new \RuntimeException('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
|
||||
return mb_convert_encoding($content, $encoding, 'UTF-8');
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and parses the given file into a SimpleXMLElement.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return \SimpleXMLElement
|
||||
* @param string $file
|
||||
* @param \DOMDocument $dom
|
||||
* @param string $schema source of the schema
|
||||
*
|
||||
* @throws InvalidResourceException
|
||||
*/
|
||||
private function parseFile($file)
|
||||
private function validateSchema($file, \DOMDocument $dom, $schema)
|
||||
{
|
||||
try {
|
||||
$dom = XmlUtils::loadFile($file);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new InvalidResourceException(sprintf('Unable to load "%s": %s', $file, $e->getMessage()), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
|
||||
$location = str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd';
|
||||
$parts = explode('/', $location);
|
||||
if (0 === stripos($location, 'phar://')) {
|
||||
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
|
||||
if ($tmpfile) {
|
||||
copy($location, $tmpfile);
|
||||
$parts = explode('/', str_replace('\\', '/', $tmpfile));
|
||||
}
|
||||
}
|
||||
$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)) {
|
||||
if (!@$dom->schemaValidateSource($schema)) {
|
||||
throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s', $file, implode("\n", $this->getXmlErrors($internalErrors))));
|
||||
}
|
||||
|
||||
|
@ -151,8 +178,46 @@ class XliffFileLoader implements LoaderInterface
|
|||
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
}
|
||||
|
||||
return array(simplexml_import_dom($dom), strtoupper($dom->encoding));
|
||||
private function getSchema($xliffVersion)
|
||||
{
|
||||
if ('1.2' === $xliffVersion) {
|
||||
$schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-1.2-strict.xsd');
|
||||
$xmlUri = 'http://www.w3.org/2001/xml.xsd';
|
||||
} elseif ('2.0' === $xliffVersion) {
|
||||
$schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-2.0.xsd');
|
||||
$xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd';
|
||||
} else {
|
||||
throw new \InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion));
|
||||
}
|
||||
|
||||
return $this->fixXmlLocation($schemaSource, $xmlUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internally changes the URI of a dependent xsd to be loaded locally.
|
||||
*
|
||||
* @param string $schemaSource Current content of schema file
|
||||
* @param string $xmlUri External URI of XML to convert to local
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function fixXmlLocation($schemaSource, $xmlUri)
|
||||
{
|
||||
$newPath = str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd';
|
||||
$parts = explode('/', $newPath);
|
||||
if (0 === stripos($newPath, 'phar://')) {
|
||||
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
|
||||
if ($tmpfile) {
|
||||
copy($newPath, $tmpfile);
|
||||
$parts = explode('/', str_replace('\\', '/', $tmpfile));
|
||||
}
|
||||
}
|
||||
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
|
||||
$newPath = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
|
||||
|
||||
return str_replace($xmlUri, $newPath, $schemaSource);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,4 +246,68 @@ class XliffFileLoader implements LoaderInterface
|
|||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets xliff file version based on the root "version" attribute.
|
||||
* Defaults to 1.2 for backwards compatibility.
|
||||
*
|
||||
* @param \DOMDocument $dom
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getVersionNumber(\DOMDocument $dom)
|
||||
{
|
||||
/** @var \DOMNode $xliff */
|
||||
foreach ($dom->getElementsByTagName('xliff') as $xliff) {
|
||||
$version = $xliff->attributes->getNamedItem('version');
|
||||
if ($version) {
|
||||
return $version->nodeValue;
|
||||
}
|
||||
|
||||
$namespace = $xliff->attributes->getNamedItem('xmlns');
|
||||
if ($namespace) {
|
||||
if (substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34) !== 0) {
|
||||
throw new \InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s"', $namespace));
|
||||
}
|
||||
|
||||
return substr($namespace, 34);
|
||||
}
|
||||
}
|
||||
|
||||
// Falls back to v1.2
|
||||
return '1.2';
|
||||
}
|
||||
|
||||
/*
|
||||
* @param \SimpleXMLElement|null $noteElement
|
||||
* @param string|null $encoding
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, $encoding = null)
|
||||
{
|
||||
$notes = array();
|
||||
|
||||
if (null === $noteElement) {
|
||||
return $notes;
|
||||
}
|
||||
|
||||
foreach ($noteElement as $xmlNote) {
|
||||
$noteAttributes = $xmlNote->attributes();
|
||||
$note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding));
|
||||
if (isset($noteAttributes['priority'])) {
|
||||
$note['priority'] = (int) $noteAttributes['priority'];
|
||||
}
|
||||
|
||||
if (isset($noteAttributes['from'])) {
|
||||
$note['from'] = (string) $noteAttributes['from'];
|
||||
}
|
||||
|
||||
$notes[] = $note;
|
||||
}
|
||||
|
||||
return $notes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
namespace Symfony\Component\Translation\Loader;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Yaml\Parser as YamlParser;
|
||||
use Symfony\Component\Yaml\Exception\ParseException;
|
||||
|
||||
|
@ -22,28 +20,20 @@ use Symfony\Component\Yaml\Exception\ParseException;
|
|||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class YamlFileLoader extends ArrayLoader
|
||||
class YamlFileLoader extends FileLoader
|
||||
{
|
||||
private $yamlParser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, $locale, $domain = 'messages')
|
||||
protected function loadResource($resource)
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
}
|
||||
|
||||
if (!file_exists($resource)) {
|
||||
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
|
||||
}
|
||||
|
||||
if (!class_exists('Symfony\Component\Yaml\Parser')) {
|
||||
throw new \LogicException('Loading translations from the YAML format requires the Symfony Yaml component.');
|
||||
}
|
||||
|
||||
if (null === $this->yamlParser) {
|
||||
if (!class_exists('Symfony\Component\Yaml\Parser')) {
|
||||
throw new \LogicException('Loading translations from the YAML format requires the Symfony Yaml component.');
|
||||
}
|
||||
|
||||
$this->yamlParser = new YamlParser();
|
||||
}
|
||||
|
||||
|
@ -53,22 +43,6 @@ class YamlFileLoader extends ArrayLoader
|
|||
throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s"', $resource), 0, $e);
|
||||
}
|
||||
|
||||
// empty file
|
||||
if (null === $messages) {
|
||||
$messages = array();
|
||||
}
|
||||
|
||||
// not an array
|
||||
if (!is_array($messages)) {
|
||||
throw new InvalidResourceException(sprintf('The file "%s" must contain a YAML array.', $resource));
|
||||
}
|
||||
|
||||
$catalogue = parent::load($messages, $locale, $domain);
|
||||
|
||||
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
}
|
||||
|
||||
return $catalogue;
|
||||
return $messages;
|
||||
}
|
||||
}
|
||||
|
|
411
vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsd
vendored
Normal file
411
vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsd
vendored
Normal file
|
@ -0,0 +1,411 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
XLIFF Version 2.0
|
||||
OASIS Standard
|
||||
05 August 2014
|
||||
Copyright (c) OASIS Open 2014. All rights reserved.
|
||||
Source: http://docs.oasis-open.org/xliff/xliff-core/v2.0/os/schemas/
|
||||
-->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
elementFormDefault="qualified"
|
||||
xmlns:xlf="urn:oasis:names:tc:xliff:document:2.0"
|
||||
targetNamespace="urn:oasis:names:tc:xliff:document:2.0">
|
||||
|
||||
<!-- Import -->
|
||||
|
||||
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="informativeCopiesOf3rdPartySchemas/w3c/xml.xsd"/>
|
||||
|
||||
<!-- Element Group -->
|
||||
|
||||
<xs:group name="inline">
|
||||
<xs:choice>
|
||||
<xs:element ref="xlf:cp"/>
|
||||
<xs:element ref="xlf:ph"/>
|
||||
<xs:element ref="xlf:pc"/>
|
||||
<xs:element ref="xlf:sc"/>
|
||||
<xs:element ref="xlf:ec"/>
|
||||
<xs:element ref="xlf:mrk"/>
|
||||
<xs:element ref="xlf:sm"/>
|
||||
<xs:element ref="xlf:em"/>
|
||||
</xs:choice>
|
||||
</xs:group>
|
||||
|
||||
<!-- Attribute Types -->
|
||||
|
||||
<xs:simpleType name="yesNo">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="yes"/>
|
||||
<xs:enumeration value="no"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="yesNoFirstNo">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="yes"/>
|
||||
<xs:enumeration value="firstNo"/>
|
||||
<xs:enumeration value="no"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="dirValue">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="ltr"/>
|
||||
<xs:enumeration value="rtl"/>
|
||||
<xs:enumeration value="auto"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="appliesTo">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="source"/>
|
||||
<xs:enumeration value="target"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="userDefinedValue">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="[^\s:]+:[^\s:]+"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="attrType_type">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="fmt"/>
|
||||
<xs:enumeration value="ui"/>
|
||||
<xs:enumeration value="quote"/>
|
||||
<xs:enumeration value="link"/>
|
||||
<xs:enumeration value="image"/>
|
||||
<xs:enumeration value="other"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="typeForMrkValues">
|
||||
<xs:restriction base="xs:NMTOKEN">
|
||||
<xs:enumeration value="generic"/>
|
||||
<xs:enumeration value="comment"/>
|
||||
<xs:enumeration value="term"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="attrType_typeForMrk">
|
||||
<xs:union memberTypes="xlf:typeForMrkValues xlf:userDefinedValue"/>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="priorityValue">
|
||||
<xs:restriction base="xs:positiveInteger">
|
||||
<xs:minInclusive value="1"/>
|
||||
<xs:maxInclusive value="10"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="stateType">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="initial"/>
|
||||
<xs:enumeration value="translated"/>
|
||||
<xs:enumeration value="reviewed"/>
|
||||
<xs:enumeration value="final"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<!-- Structural Elements -->
|
||||
|
||||
<xs:element name="xliff">
|
||||
<xs:complexType mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:file"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="version" use="required"/>
|
||||
<xs:attribute name="srcLang" use="required"/>
|
||||
<xs:attribute name="trgLang" use="optional"/>
|
||||
<xs:attribute ref="xml:space" use="optional" default="default"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="file">
|
||||
<xs:complexType mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="0" maxOccurs="1" ref="xlf:skeleton"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
|
||||
processContents="lax"/>
|
||||
<xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
|
||||
<xs:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:element ref="xlf:unit"/>
|
||||
<xs:element ref="xlf:group"/>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="canResegment" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="original" use="optional"/>
|
||||
<xs:attribute name="translate" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="srcDir" use="optional" type="xlf:dirValue" default="auto"/>
|
||||
<xs:attribute name="trgDir" use="optional" type="xlf:dirValue" default="auto"/>
|
||||
<xs:attribute ref="xml:space" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="skeleton">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
|
||||
processContents="lax"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="href" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="group">
|
||||
<xs:complexType mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
|
||||
processContents="lax"/>
|
||||
<xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="xlf:unit"/>
|
||||
<xs:element ref="xlf:group"/>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="name" use="optional"/>
|
||||
<xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
|
||||
<xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
|
||||
<xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
|
||||
<xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
|
||||
<xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
|
||||
<xs:attribute ref="xml:space" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="unit">
|
||||
<xs:complexType mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
|
||||
processContents="lax"/>
|
||||
<xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
|
||||
<xs:element minOccurs="0" maxOccurs="1" ref="xlf:originalData"/>
|
||||
<xs:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:element ref="xlf:segment"/>
|
||||
<xs:element ref="xlf:ignorable"/>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="name" use="optional"/>
|
||||
<xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
|
||||
<xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
|
||||
<xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
|
||||
<xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
|
||||
<xs:attribute ref="xml:space" use="optional"/>
|
||||
<xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="segment">
|
||||
<xs:complexType mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
|
||||
<xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
|
||||
<xs:attribute name="state" use="optional" type="xlf:stateType" default="initial"/>
|
||||
<xs:attribute name="subState" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="ignorable">
|
||||
<xs:complexType mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
|
||||
<xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="notes">
|
||||
<xs:complexType mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:note"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="note">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="appliesTo" use="optional" type="xlf:appliesTo"/>
|
||||
<xs:attribute name="category" use="optional"/>
|
||||
<xs:attribute name="priority" use="optional" type="xlf:priorityValue" default="1"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="originalData">
|
||||
<xs:complexType mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:data"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="data">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" ref="xlf:cp"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dir" use="optional" type="xlf:dirValue" default="auto"/>
|
||||
<xs:attribute ref="xml:space" use="optional" fixed="preserve"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="source">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:attribute ref="xml:lang" use="optional"/>
|
||||
<xs:attribute ref="xml:space" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="target">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:attribute ref="xml:lang" use="optional"/>
|
||||
<xs:attribute ref="xml:space" use="optional"/>
|
||||
<xs:attribute name="order" use="optional" type="xs:positiveInteger"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<!-- Inline Elements -->
|
||||
|
||||
<xs:element name="cp">
|
||||
<!-- Code Point -->
|
||||
<xs:complexType mixed="false">
|
||||
<xs:attribute name="hex" use="required" type="xs:hexBinary"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="ph">
|
||||
<!-- Placeholder -->
|
||||
<xs:complexType mixed="false">
|
||||
<xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
|
||||
<xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="disp" use="optional"/>
|
||||
<xs:attribute name="equiv" use="optional"/>
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
|
||||
<xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
|
||||
<xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="pc">
|
||||
<!-- Paired Code -->
|
||||
<xs:complexType mixed="true">
|
||||
<xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canOverlap" use="optional" type="xlf:yesNo"/>
|
||||
<xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
|
||||
<xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dispEnd" use="optional"/>
|
||||
<xs:attribute name="dispStart" use="optional"/>
|
||||
<xs:attribute name="equivEnd" use="optional"/>
|
||||
<xs:attribute name="equivStart" use="optional"/>
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dataRefEnd" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dataRefStart" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="subFlowsEnd" use="optional" type="xs:NMTOKENS"/>
|
||||
<xs:attribute name="subFlowsStart" use="optional" type="xs:NMTOKENS"/>
|
||||
<xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
|
||||
<xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
|
||||
<xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="sc">
|
||||
<!-- Start Code -->
|
||||
<xs:complexType mixed="false">
|
||||
<xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
|
||||
<xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
|
||||
<xs:attribute name="disp" use="optional"/>
|
||||
<xs:attribute name="equiv" use="optional"/>
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
|
||||
<xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
|
||||
<xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
|
||||
<xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="ec">
|
||||
<!-- End Code -->
|
||||
<xs:complexType mixed="false">
|
||||
<xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
|
||||
<xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
|
||||
<xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
|
||||
<xs:attribute name="disp" use="optional"/>
|
||||
<xs:attribute name="equiv" use="optional"/>
|
||||
<xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
|
||||
<xs:attribute name="startRef" use="optional" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
|
||||
<xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
|
||||
<xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="mrk">
|
||||
<!-- Annotation Marker -->
|
||||
<xs:complexType mixed="true">
|
||||
<xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
|
||||
<xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
|
||||
<xs:attribute name="ref" use="optional" type="xs:anyURI"/>
|
||||
<xs:attribute name="value" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="sm">
|
||||
<!-- Start Annotation Marker -->
|
||||
<xs:complexType mixed="false">
|
||||
<xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
|
||||
<xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
|
||||
<xs:attribute name="ref" use="optional" type="xs:anyURI"/>
|
||||
<xs:attribute name="value" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="em">
|
||||
<!-- End Annotation Marker -->
|
||||
<xs:complexType mixed="false">
|
||||
<xs:attribute name="startRef" use="required" type="xs:NMTOKEN"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:schema>
|
|
@ -131,6 +131,7 @@ class PluralizationRules
|
|||
case 'fr':
|
||||
case 'gun':
|
||||
case 'hi':
|
||||
case 'hy':
|
||||
case 'ln':
|
||||
case 'mg':
|
||||
case 'nso':
|
||||
|
|
36
vendor/symfony/translation/README.md
vendored
36
vendor/symfony/translation/README.md
vendored
|
@ -1,37 +1,13 @@
|
|||
Translation Component
|
||||
=====================
|
||||
|
||||
Translation provides tools for loading translation files and generating
|
||||
translated strings from these including support for pluralization.
|
||||
|
||||
```php
|
||||
use Symfony\Component\Translation\Translator;
|
||||
use Symfony\Component\Translation\MessageSelector;
|
||||
use Symfony\Component\Translation\Loader\ArrayLoader;
|
||||
|
||||
$translator = new Translator('fr_FR', new MessageSelector());
|
||||
$translator->setFallbackLocales(array('fr'));
|
||||
$translator->addLoader('array', new ArrayLoader());
|
||||
$translator->addResource('array', array(
|
||||
'Hello World!' => 'Bonjour',
|
||||
), 'fr');
|
||||
|
||||
echo $translator->trans('Hello World!')."\n";
|
||||
```
|
||||
The Translation component provides tools to internationalize your application.
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
Silex integration:
|
||||
|
||||
https://github.com/silexphp/Silex/blob/master/src/Silex/Provider/TranslationServiceProvider.php
|
||||
|
||||
Documentation:
|
||||
|
||||
https://symfony.com/doc/2.7/book/translation.html
|
||||
|
||||
You can run the unit tests with the following command:
|
||||
|
||||
$ cd path/to/Symfony/Component/Translation/
|
||||
$ composer install
|
||||
$ phpunit
|
||||
* [Documentation](https://symfony.com/doc/current/components/translation/index.html)
|
||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||
in the [main Symfony repository](https://github.com/symfony/symfony)
|
||||
|
|
7
vendor/symfony/translation/Translator.php
vendored
7
vendor/symfony/translation/Translator.php
vendored
|
@ -267,9 +267,13 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
|
|||
* @param string|null $locale Locale of translations, by default is current locale
|
||||
*
|
||||
* @return array[array] indexed by catalog
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0. Use TranslatorBagInterface::getCatalogue() method instead.
|
||||
*/
|
||||
public function getMessages($locale = null)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use TranslatorBagInterface::getCatalogue() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
$catalogue = $this->getCatalogue($locale);
|
||||
$messages = $catalogue->all();
|
||||
while ($catalogue = $catalogue->getFallbackCatalogue()) {
|
||||
|
@ -424,6 +428,9 @@ EOF
|
|||
}
|
||||
|
||||
$fallbackCatalogue = new MessageCatalogue($fallback, $this->catalogues[$fallback]->all());
|
||||
foreach ($this->catalogues[$fallback]->getResources() as $resource) {
|
||||
$fallbackCatalogue->addResource($resource);
|
||||
}
|
||||
$current->addFallbackCatalogue($fallbackCatalogue);
|
||||
$current = $fallbackCatalogue;
|
||||
}
|
||||
|
|
99
vendor/symfony/translation/Util/ArrayConverter.php
vendored
Normal file
99
vendor/symfony/translation/Util/ArrayConverter.php
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?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\Util;
|
||||
|
||||
/**
|
||||
* ArrayConverter generates tree like structure from a message catalogue.
|
||||
* e.g. this
|
||||
* 'foo.bar1' => 'test1',
|
||||
* 'foo.bar2' => 'test2'
|
||||
* converts to follows:
|
||||
* foo:
|
||||
* bar1: test1
|
||||
* bar2: test2.
|
||||
*
|
||||
* @author Gennady Telegin <gtelegin@gmail.com>
|
||||
*/
|
||||
class ArrayConverter
|
||||
{
|
||||
/**
|
||||
* Converts linear messages array to tree-like array.
|
||||
* For example this rray('foo.bar' => 'value') will be converted to array('foo' => array('bar' => 'value')).
|
||||
*
|
||||
* @param array $messages Linear messages array
|
||||
*
|
||||
* @return array Tree-like messages array
|
||||
*/
|
||||
public static function expandToTree(array $messages)
|
||||
{
|
||||
$tree = array();
|
||||
|
||||
foreach ($messages as $id => $value) {
|
||||
$referenceToElement = &self::getElementByPath($tree, explode('.', $id));
|
||||
|
||||
$referenceToElement = $value;
|
||||
|
||||
unset($referenceToElement);
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
private static function &getElementByPath(array &$tree, array $parts)
|
||||
{
|
||||
$elem = &$tree;
|
||||
$parentOfElem = null;
|
||||
|
||||
foreach ($parts as $i => $part) {
|
||||
if (isset($elem[$part]) && is_string($elem[$part])) {
|
||||
/* Process next case:
|
||||
* 'foo': 'test1',
|
||||
* 'foo.bar': 'test2'
|
||||
*
|
||||
* $tree['foo'] was string before we found array {bar: test2}.
|
||||
* Treat new element as string too, e.g. add $tree['foo.bar'] = 'test2';
|
||||
*/
|
||||
$elem = &$elem[ implode('.', array_slice($parts, $i)) ];
|
||||
break;
|
||||
}
|
||||
$parentOfElem = &$elem;
|
||||
$elem = &$elem[$part];
|
||||
}
|
||||
|
||||
if (is_array($elem) && count($elem) > 0 && $parentOfElem) {
|
||||
/* Process next case:
|
||||
* 'foo.bar': 'test1'
|
||||
* 'foo': 'test2'
|
||||
*
|
||||
* $tree['foo'] was array = {bar: 'test1'} before we found string constant `foo`.
|
||||
* Cancel treating $tree['foo'] as array and cancel back it expansion,
|
||||
* e.g. make it $tree['foo.bar'] = 'test1' again.
|
||||
*/
|
||||
self::cancelExpand($parentOfElem, $part, $elem);
|
||||
}
|
||||
|
||||
return $elem;
|
||||
}
|
||||
|
||||
private static function cancelExpand(array &$tree, $prefix, array $node)
|
||||
{
|
||||
$prefix .= '.';
|
||||
|
||||
foreach ($node as $id => $value) {
|
||||
if (is_string($value)) {
|
||||
$tree[$prefix.$id] = $value;
|
||||
} else {
|
||||
self::cancelExpand($tree, $prefix.$id, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,7 +45,9 @@ class TranslationWriter
|
|||
public function disableBackup()
|
||||
{
|
||||
foreach ($this->dumpers as $dumper) {
|
||||
$dumper->setBackup(false);
|
||||
if (method_exists($dumper, 'setBackup')) {
|
||||
$dumper->setBackup(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,8 +79,8 @@ class TranslationWriter
|
|||
// get the right dumper
|
||||
$dumper = $this->dumpers[$format];
|
||||
|
||||
if (isset($options['path']) && !is_dir($options['path'])) {
|
||||
mkdir($options['path'], 0777, true);
|
||||
if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0777, true) && !is_dir($options['path'])) {
|
||||
throw new \RuntimeException(sprintf('Translation Writer was not able to create directory "%s"', $options['path']));
|
||||
}
|
||||
|
||||
// save
|
||||
|
|
16
vendor/symfony/translation/composer.json
vendored
16
vendor/symfony/translation/composer.json
vendored
|
@ -16,12 +16,13 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.9"
|
||||
"php": ">=5.3.9",
|
||||
"symfony/polyfill-mbstring": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/config": "~2.7",
|
||||
"symfony/intl": "~2.4",
|
||||
"symfony/yaml": "~2.2",
|
||||
"symfony/config": "~2.8",
|
||||
"symfony/intl": "~2.4|~3.0.0",
|
||||
"symfony/yaml": "~2.2|~3.0.0",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"conflict": {
|
||||
|
@ -33,12 +34,15 @@
|
|||
"psr/log": "To use logging capability in translator"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\Translation\\": "" }
|
||||
"psr-4": { "Symfony\\Component\\Translation\\": "" },
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
"dev-master": "2.8-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
vendor/symfony/translation/phpunit.xml.dist
vendored
2
vendor/symfony/translation/phpunit.xml.dist
vendored
|
@ -20,8 +20,8 @@
|
|||
<whitelist>
|
||||
<directory>./</directory>
|
||||
<exclude>
|
||||
<directory>./vendor</directory>
|
||||
<directory>./Tests</directory>
|
||||
<directory>./vendor</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
|
Reference in a new issue