diff options
Diffstat (limited to 'public/system/storage/vendor/symfony/translation')
147 files changed, 11718 insertions, 0 deletions
diff --git a/public/system/storage/vendor/symfony/translation/.gitignore b/public/system/storage/vendor/symfony/translation/.gitignore new file mode 100644 index 0000000..c49a5d8 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/public/system/storage/vendor/symfony/translation/CHANGELOG.md b/public/system/storage/vendor/symfony/translation/CHANGELOG.md new file mode 100644 index 0000000..b011f9e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/CHANGELOG.md @@ -0,0 +1,69 @@ +CHANGELOG +========= + +3.0.0 +----- + + * removed `FileDumper::format()` method. + * Changed the visibility of the locale property in `Translator` from protected to private. + +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 +----- + + * added DataCollectorTranslator for collecting the translated messages. + +2.6.0 +----- + + * added possibility to cache catalogues + * added TranslatorBagInterface + * added LoggingTranslator + * added Translator::getMessages() for retrieving the message catalogue as an array + +2.5.0 +----- + + * added relative file path template to the file dumpers + * added optional backup to the file dumpers + * changed IcuResFileDumper to extend FileDumper + +2.3.0 +----- + + * added classes to make operations on catalogues (like making a diff or a merge on 2 catalogues) + * added Translator::getFallbackLocales() + * deprecated Translator::setFallbackLocale() in favor of the new Translator::setFallbackLocales() method + +2.2.0 +----- + + * QtTranslationsLoader class renamed to QtFileLoader. QtTranslationsLoader is deprecated and will be removed in 2.3. + * [BC BREAK] uniformized the exception thrown by the load() method when an error occurs. The load() method now + throws Symfony\Component\Translation\Exception\NotFoundResourceException when a resource cannot be found + and Symfony\Component\Translation\Exception\InvalidResourceException when a resource is invalid. + * changed the exception class thrown by some load() methods from \RuntimeException to \InvalidArgumentException + (IcuDatFileLoader, IcuResFileLoader and QtFileLoader) + +2.1.0 +----- + + * added support for more than one fallback locale + * added support for extracting translation messages from templates (Twig and PHP) + * added dumpers for translation catalogs + * added support for QT, gettext, and ResourceBundles diff --git a/public/system/storage/vendor/symfony/translation/Catalogue/AbstractOperation.php b/public/system/storage/vendor/symfony/translation/Catalogue/AbstractOperation.php new file mode 100644 index 0000000..9598e17 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Catalogue/AbstractOperation.php @@ -0,0 +1,171 @@ +<?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; + +use Symfony\Component\Translation\MessageCatalogue; +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 The source catalogue + */ + protected $source; + + /** + * @var MessageCatalogueInterface The target catalogue + */ + protected $target; + + /** + * @var MessageCatalogue The result catalogue + */ + protected $result; + + /** + * @var null|array The domains affected by this operation + */ + private $domains; + + /** + * 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 The source catalogue + * @param MessageCatalogueInterface $target The target catalogue + * + * @throws \LogicException + */ + public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target) + { + if ($source->getLocale() !== $target->getLocale()) { + throw new \LogicException('Operated catalogues must belong to the same locale.'); + } + + $this->source = $source; + $this->target = $target; + $this->result = new MessageCatalogue($source->getLocale()); + $this->domains = null; + $this->messages = array(); + } + + /** + * {@inheritdoc} + */ + public function getDomains() + { + if (null === $this->domains) { + $this->domains = array_values(array_unique(array_merge($this->source->getDomains(), $this->target->getDomains()))); + } + + return $this->domains; + } + + /** + * {@inheritdoc} + */ + public function getMessages($domain) + { + if (!in_array($domain, $this->getDomains())) { + throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); + } + + if (!isset($this->messages[$domain]['all'])) { + $this->processDomain($domain); + } + + return $this->messages[$domain]['all']; + } + + /** + * {@inheritdoc} + */ + public function getNewMessages($domain) + { + if (!in_array($domain, $this->getDomains())) { + throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); + } + + if (!isset($this->messages[$domain]['new'])) { + $this->processDomain($domain); + } + + return $this->messages[$domain]['new']; + } + + /** + * {@inheritdoc} + */ + public function getObsoleteMessages($domain) + { + if (!in_array($domain, $this->getDomains())) { + throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); + } + + if (!isset($this->messages[$domain]['obsolete'])) { + $this->processDomain($domain); + } + + return $this->messages[$domain]['obsolete']; + } + + /** + * {@inheritdoc} + */ + public function getResult() + { + foreach ($this->getDomains() as $domain) { + if (!isset($this->messages[$domain])) { + $this->processDomain($domain); + } + } + + return $this->result; + } + + /** + * 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); +} diff --git a/public/system/storage/vendor/symfony/translation/Catalogue/MergeOperation.php b/public/system/storage/vendor/symfony/translation/Catalogue/MergeOperation.php new file mode 100644 index 0000000..6db3f80 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Catalogue/MergeOperation.php @@ -0,0 +1,55 @@ +<?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; + +/** + * 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> + */ +class MergeOperation extends AbstractOperation +{ + /** + * {@inheritdoc} + */ + protected function processDomain($domain) + { + $this->messages[$domain] = array( + 'all' => array(), + 'new' => array(), + 'obsolete' => array(), + ); + + foreach ($this->source->all($domain) as $id => $message) { + $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); + } + } + + 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); + } + } + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/Catalogue/OperationInterface.php b/public/system/storage/vendor/symfony/translation/Catalogue/OperationInterface.php new file mode 100644 index 0000000..87d888e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Catalogue/OperationInterface.php @@ -0,0 +1,77 @@ +<?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; + +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 +{ + /** + * Returns domains affected by operation. + * + * @return array + */ + public function getDomains(); + + /** + * Returns all valid messages ('all') after operation. + * + * @param string $domain + * + * @return array + */ + public function getMessages($domain); + + /** + * Returns new messages ('new') after operation. + * + * @param string $domain + * + * @return array + */ + public function getNewMessages($domain); + + /** + * Returns obsolete messages ('obsolete') after operation. + * + * @param string $domain + * + * @return array + */ + public function getObsoleteMessages($domain); + + /** + * Returns resulting catalogue ('result'). + * + * @return MessageCatalogueInterface + */ + public function getResult(); +} diff --git a/public/system/storage/vendor/symfony/translation/Catalogue/TargetOperation.php b/public/system/storage/vendor/symfony/translation/Catalogue/TargetOperation.php new file mode 100644 index 0000000..e081e13 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Catalogue/TargetOperation.php @@ -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); + } + } + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/DataCollector/TranslationDataCollector.php b/public/system/storage/vendor/symfony/translation/DataCollector/TranslationDataCollector.php new file mode 100644 index 0000000..cb59d0a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/DataCollector/TranslationDataCollector.php @@ -0,0 +1,150 @@ +<?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\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; +use Symfony\Component\Translation\DataCollectorTranslator; + +/** + * @author Abdellatif Ait boudad <a.aitboudad@gmail.com> + */ +class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface +{ + /** + * @var DataCollectorTranslator + */ + private $translator; + + /** + * @param DataCollectorTranslator $translator + */ + public function __construct(DataCollectorTranslator $translator) + { + $this->translator = $translator; + } + + /** + * {@inheritdoc} + */ + public function lateCollect() + { + $messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages()); + + $this->data = $this->computeCount($messages); + $this->data['messages'] = $messages; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + } + + /** + * @return array + */ + public function getMessages() + { + return isset($this->data['messages']) ? $this->data['messages'] : array(); + } + + /** + * @return int + */ + public function getCountMissings() + { + return isset($this->data[DataCollectorTranslator::MESSAGE_MISSING]) ? $this->data[DataCollectorTranslator::MESSAGE_MISSING] : 0; + } + + /** + * @return int + */ + public function getCountFallbacks() + { + return isset($this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK]) ? $this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK] : 0; + } + + /** + * @return int + */ + public function getCountDefines() + { + return isset($this->data[DataCollectorTranslator::MESSAGE_DEFINED]) ? $this->data[DataCollectorTranslator::MESSAGE_DEFINED] : 0; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'translation'; + } + + private function sanitizeCollectedMessages($messages) + { + $result = array(); + foreach ($messages as $key => $message) { + $messageId = $message['locale'].$message['domain'].$message['id']; + + 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']; + } + + unset($messages[$key]); + } + + return $result; + } + + private function computeCount($messages) + { + $count = array( + DataCollectorTranslator::MESSAGE_DEFINED => 0, + DataCollectorTranslator::MESSAGE_MISSING => 0, + DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK => 0, + ); + + foreach ($messages as $message) { + ++$count[$message['state']]; + } + + return $count; + } + + private function sanitizeString($string, $length = 80) + { + $string = trim(preg_replace('/\s+/', ' ', $string)); + + if (false !== $encoding = mb_detect_encoding($string, null, true)) { + if (mb_strlen($string, $encoding) > $length) { + return mb_substr($string, 0, $length - 3, $encoding).'...'; + } + } elseif (strlen($string) > $length) { + return substr($string, 0, $length - 3).'...'; + } + + return $string; + } +} diff --git a/public/system/storage/vendor/symfony/translation/DataCollectorTranslator.php b/public/system/storage/vendor/symfony/translation/DataCollectorTranslator.php new file mode 100644 index 0000000..2446723 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/DataCollectorTranslator.php @@ -0,0 +1,152 @@ +<?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; + +/** + * @author Abdellatif Ait boudad <a.aitboudad@gmail.com> + */ +class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface +{ + const MESSAGE_DEFINED = 0; + const MESSAGE_MISSING = 1; + const MESSAGE_EQUALS_FALLBACK = 2; + + /** + * @var TranslatorInterface|TranslatorBagInterface + */ + private $translator; + + /** + * @var array + */ + private $messages = array(); + + /** + * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface + */ + public function __construct(TranslatorInterface $translator) + { + if (!$translator instanceof TranslatorBagInterface) { + throw new \InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator))); + } + + $this->translator = $translator; + } + + /** + * {@inheritdoc} + */ + 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, $parameters); + + return $trans; + } + + /** + * {@inheritdoc} + */ + 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, $parameters, $number); + + return $trans; + } + + /** + * {@inheritdoc} + */ + public function setLocale($locale) + { + $this->translator->setLocale($locale); + } + + /** + * {@inheritdoc} + */ + public function getLocale() + { + return $this->translator->getLocale(); + } + + /** + * {@inheritdoc} + */ + public function getCatalogue($locale = null) + { + return $this->translator->getCatalogue($locale); + } + + /** + * Passes through all unknown calls onto the translator object. + */ + public function __call($method, $args) + { + return call_user_func_array(array($this->translator, $method), $args); + } + + /** + * @return array + */ + public function getCollectedMessages() + { + return $this->messages; + } + + /** + * @param string|null $locale + * @param string|null $domain + * @param string $id + * @param string $translation + * @param array|null $parameters + * @param int|null $number + */ + private function collectMessage($locale, $domain, $id, $translation, $parameters = array(), $number = null) + { + if (null === $domain) { + $domain = 'messages'; + } + + $id = (string) $id; + $catalogue = $this->translator->getCatalogue($locale); + $locale = $catalogue->getLocale(); + if ($catalogue->defines($id, $domain)) { + $state = self::MESSAGE_DEFINED; + } elseif ($catalogue->has($id, $domain)) { + $state = self::MESSAGE_EQUALS_FALLBACK; + + $fallbackCatalogue = $catalogue->getFallbackCatalogue(); + while ($fallbackCatalogue) { + if ($fallbackCatalogue->defines($id, $domain)) { + $locale = $fallbackCatalogue->getLocale(); + break; + } + + $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue(); + } + } else { + $state = self::MESSAGE_MISSING; + } + + $this->messages[] = array( + 'locale' => $locale, + 'domain' => $domain, + 'id' => $id, + 'translation' => $translation, + 'parameters' => $parameters, + 'transChoiceNumber' => $number, + 'state' => $state, + ); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/CsvFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/CsvFileDumper.php new file mode 100644 index 0000000..fe5dccb --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/CsvFileDumper.php @@ -0,0 +1,63 @@ +<?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; + +/** + * CsvFileDumper generates a csv formatted string representation of a message catalogue. + * + * @author Stealth35 + */ +class CsvFileDumper extends FileDumper +{ + private $delimiter = ';'; + private $enclosure = '"'; + + /** + * {@inheritdoc} + */ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + $handle = fopen('php://memory', 'rb+'); + + foreach ($messages->all($domain) as $source => $target) { + fputcsv($handle, array($source, $target), $this->delimiter, $this->enclosure); + } + + rewind($handle); + $output = stream_get_contents($handle); + fclose($handle); + + return $output; + } + + /** + * Sets the delimiter and escape character for CSV. + * + * @param string $delimiter delimiter character + * @param string $enclosure enclosure character + */ + public function setCsvControl($delimiter = ';', $enclosure = '"') + { + $this->delimiter = $delimiter; + $this->enclosure = $enclosure; + } + + /** + * {@inheritdoc} + */ + protected function getExtension() + { + return 'csv'; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/DumperInterface.php b/public/system/storage/vendor/symfony/translation/Dumper/DumperInterface.php new file mode 100644 index 0000000..cebc65e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/DumperInterface.php @@ -0,0 +1,31 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; + +/** + * DumperInterface is the interface implemented by all translation dumpers. + * There is no common option. + * + * @author Michel Salib <michelsalib@hotmail.com> + */ +interface DumperInterface +{ + /** + * Dumps the message catalogue. + * + * @param MessageCatalogue $messages The message catalogue + * @param array $options Options that are used by the dumper + */ + public function dump(MessageCatalogue $messages, $options = array()); +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/FileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/FileDumper.php new file mode 100644 index 0000000..9c9a8ee --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/FileDumper.php @@ -0,0 +1,123 @@ +<?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; + +/** + * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s). + * Performs backup of already existing files. + * + * Options: + * - path (mandatory): the directory where the files should be saved + * + * @author Michel Salib <michelsalib@hotmail.com> + */ +abstract class FileDumper implements DumperInterface +{ + /** + * A template for the relative paths to files. + * + * @var string + */ + protected $relativePathTemplate = '%domain%.%locale%.%extension%'; + + /** + * Make file backup before the dump. + * + * @var bool + */ + private $backup = true; + + /** + * Sets the template for the relative paths to files. + * + * @param string $relativePathTemplate A template for the relative paths to files + */ + public function setRelativePathTemplate($relativePathTemplate) + { + $this->relativePathTemplate = $relativePathTemplate; + } + + /** + * Sets backup flag. + * + * @param bool + */ + public function setBackup($backup) + { + $this->backup = $backup; + } + + /** + * {@inheritdoc} + */ + public function dump(MessageCatalogue $messages, $options = array()) + { + if (!array_key_exists('path', $options)) { + throw new \InvalidArgumentException('The file dumper needs a path option.'); + } + + // save a file for each domain + foreach ($messages->getDomains() as $domain) { + // backup + $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale()); + if (file_exists($fullpath)) { + if ($this->backup) { + copy($fullpath, $fullpath.'~'); + } + } else { + $directory = dirname($fullpath); + if (!file_exists($directory) && !@mkdir($directory, 0777, true)) { + throw new \RuntimeException(sprintf('Unable to create directory "%s".', $directory)); + } + } + // save file + file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options)); + } + } + + /** + * Transforms a domain of a message catalogue to its string representation. + * + * @param MessageCatalogue $messages + * @param string $domain + * @param array $options + * + * @return string representation + */ + abstract public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()); + + /** + * Gets the file extension of the dumper. + * + * @return string file extension + */ + abstract protected function getExtension(); + + /** + * Gets the relative file path using the template. + * + * @param string $domain The domain + * @param string $locale The locale + * + * @return string The relative file path + */ + private function getRelativePath($domain, $locale) + { + return strtr($this->relativePathTemplate, array( + '%domain%' => $domain, + '%locale%' => $locale, + '%extension%' => $this->getExtension(), + )); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/IcuResFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/IcuResFileDumper.php new file mode 100644 index 0000000..ceb4b42 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/IcuResFileDumper.php @@ -0,0 +1,106 @@ +<?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; + +/** + * IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue. + * + * @author Stealth35 + */ +class IcuResFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + protected $relativePathTemplate = '%domain%/%locale%.%extension%'; + + /** + * {@inheritdoc} + */ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + $data = $indexes = $resources = ''; + + foreach ($messages->all($domain) as $source => $target) { + $indexes .= pack('v', strlen($data) + 28); + $data .= $source."\0"; + } + + $data .= $this->writePadding($data); + + $keyTop = $this->getPosition($data); + + foreach ($messages->all($domain) as $source => $target) { + $resources .= pack('V', $this->getPosition($data)); + + $data .= pack('V', strlen($target)) + .mb_convert_encoding($target."\0", 'UTF-16LE', 'UTF-8') + .$this->writePadding($data) + ; + } + + $resOffset = $this->getPosition($data); + + $data .= pack('v', count($messages)) + .$indexes + .$this->writePadding($data) + .$resources + ; + + $bundleTop = $this->getPosition($data); + + $root = pack('V7', + $resOffset + (2 << 28), // Resource Offset + Resource Type + 6, // Index length + $keyTop, // Index keys top + $bundleTop, // Index resources top + $bundleTop, // Index bundle top + count($messages), // Index max table length + 0 // Index attributes + ); + + $header = pack('vC2v4C12@32', + 32, // Header size + 0xDA, 0x27, // Magic number 1 and 2 + 20, 0, 0, 2, // Rest of the header, ..., Size of a char + 0x52, 0x65, 0x73, 0x42, // Data format identifier + 1, 2, 0, 0, // Data version + 1, 4, 0, 0 // Unicode version + ); + + return $header.$root.$data; + } + + private function writePadding($data) + { + $padding = strlen($data) % 4; + + if ($padding) { + return str_repeat("\xAA", 4 - $padding); + } + } + + private function getPosition($data) + { + return (strlen($data) + 28) / 4; + } + + /** + * {@inheritdoc} + */ + protected function getExtension() + { + return 'res'; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/IniFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/IniFileDumper.php new file mode 100644 index 0000000..9ed3754 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/IniFileDumper.php @@ -0,0 +1,45 @@ +<?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; + +/** + * IniFileDumper generates an ini formatted string representation of a message catalogue. + * + * @author Stealth35 + */ +class IniFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + $output = ''; + + foreach ($messages->all($domain) as $source => $target) { + $escapeTarget = str_replace('"', '\"', $target); + $output .= $source.'="'.$escapeTarget."\"\n"; + } + + return $output; + } + + /** + * {@inheritdoc} + */ + protected function getExtension() + { + return 'ini'; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/JsonFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/JsonFileDumper.php new file mode 100644 index 0000000..08b538e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/JsonFileDumper.php @@ -0,0 +1,44 @@ +<?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; + +/** + * JsonFileDumper generates an json formatted string representation of a message catalogue. + * + * @author singles + */ +class JsonFileDumper extends FileDumper +{ + /** + * {@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); + } + + /** + * {@inheritdoc} + */ + protected function getExtension() + { + return 'json'; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/MoFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/MoFileDumper.php new file mode 100644 index 0000000..f9aae42 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/MoFileDumper.php @@ -0,0 +1,82 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Loader\MoFileLoader; + +/** + * MoFileDumper generates a gettext formatted string representation of a message catalogue. + * + * @author Stealth35 + */ +class MoFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + $output = $sources = $targets = $sourceOffsets = $targetOffsets = ''; + $offsets = array(); + $size = 0; + + foreach ($messages->all($domain) as $source => $target) { + $offsets[] = array_map('strlen', array($sources, $source, $targets, $target)); + $sources .= "\0".$source; + $targets .= "\0".$target; + ++$size; + } + + $header = array( + 'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC, + 'formatRevision' => 0, + 'count' => $size, + 'offsetId' => MoFileLoader::MO_HEADER_SIZE, + 'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size), + 'sizeHashes' => 0, + 'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size), + ); + + $sourcesSize = strlen($sources); + $sourcesStart = $header['offsetHashes'] + 1; + + foreach ($offsets as $offset) { + $sourceOffsets .= $this->writeLong($offset[1]) + .$this->writeLong($offset[0] + $sourcesStart); + $targetOffsets .= $this->writeLong($offset[3]) + .$this->writeLong($offset[2] + $sourcesStart + $sourcesSize); + } + + $output = implode(array_map(array($this, 'writeLong'), $header)) + .$sourceOffsets + .$targetOffsets + .$sources + .$targets + ; + + return $output; + } + + /** + * {@inheritdoc} + */ + protected function getExtension() + { + return 'mo'; + } + + private function writeLong($str) + { + return pack('V*', $str); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/PhpFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/PhpFileDumper.php new file mode 100644 index 0000000..c7c37aa --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/PhpFileDumper.php @@ -0,0 +1,38 @@ +<?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; + +/** + * PhpFileDumper generates PHP files from a message catalogue. + * + * @author Michel Salib <michelsalib@hotmail.com> + */ +class PhpFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + return "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n"; + } + + /** + * {@inheritdoc} + */ + protected function getExtension() + { + return 'php'; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/PoFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/PoFileDumper.php new file mode 100644 index 0000000..ed4418b --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/PoFileDumper.php @@ -0,0 +1,61 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; + +/** + * PoFileDumper generates a gettext formatted string representation of a message catalogue. + * + * @author Stealth35 + */ +class PoFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + $output = 'msgid ""'."\n"; + $output .= 'msgstr ""'."\n"; + $output .= '"Content-Type: text/plain; charset=UTF-8\n"'."\n"; + $output .= '"Content-Transfer-Encoding: 8bit\n"'."\n"; + $output .= '"Language: '.$messages->getLocale().'\n"'."\n"; + $output .= "\n"; + + $newLine = false; + foreach ($messages->all($domain) as $source => $target) { + if ($newLine) { + $output .= "\n"; + } else { + $newLine = true; + } + $output .= sprintf('msgid "%s"'."\n", $this->escape($source)); + $output .= sprintf('msgstr "%s"', $this->escape($target)); + } + + return $output; + } + + /** + * {@inheritdoc} + */ + protected function getExtension() + { + return 'po'; + } + + private function escape($str) + { + return addcslashes($str, "\0..\37\42\134"); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/QtFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/QtFileDumper.php new file mode 100644 index 0000000..a9073f2 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/QtFileDumper.php @@ -0,0 +1,50 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; + +/** + * QtFileDumper generates ts files from a message catalogue. + * + * @author Benjamin Eberlei <kontakt@beberlei.de> + */ +class QtFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + $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(); + } + + /** + * {@inheritdoc} + */ + protected function getExtension() + { + return 'ts'; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/XliffFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/XliffFileDumper.php new file mode 100644 index 0000000..915dbca --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/XliffFileDumper.php @@ -0,0 +1,183 @@ +<?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; + +/** + * XliffFileDumper generates xliff files from a message catalogue. + * + * @author Michel Salib <michelsalib@hotmail.com> + */ +class XliffFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + $xliffVersion = '1.2'; + if (array_key_exists('xliff_version', $options)) { + $xliffVersion = $options['xliff_version']; + } + + 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)); + } + + /** + * {@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; + + $xliff = $dom->appendChild($dom->createElement('xliff')); + $xliff->setAttribute('version', '1.2'); + $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2'); + + $xliffFile = $xliff->appendChild($dom->createElement('file')); + $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'); + + $translation->setAttribute('id', md5($source)); + $translation->setAttribute('resname', $source); + + $s = $translation->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 = $translation->appendChild($targetElement); + $t->appendChild($text); + + if ($this->hasMetadataArrayInfo('notes', $metadata)) { + foreach ($metadata['notes'] as $note) { + if (!isset($note['content'])) { + continue; + } + + $n = $translation->appendChild($dom->createElement('note')); + $n->appendChild($dom->createTextNode($note['content'])); + + if (isset($note['priority'])) { + $n->setAttribute('priority', $note['priority']); + } + + if (isset($note['from'])) { + $n->setAttribute('from', $note['from']); + } + } + } + + $xliffBody->appendChild($translation); + } + + return $dom->saveXML(); + } + + private function dumpXliff2($defaultLocale, MessageCatalogue $messages, $domain, array $options = array()) + { + $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])); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Dumper/YamlFileDumper.php b/public/system/storage/vendor/symfony/translation/Dumper/YamlFileDumper.php new file mode 100644 index 0000000..625953c --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Dumper/YamlFileDumper.php @@ -0,0 +1,54 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Util\ArrayConverter; +use Symfony\Component\Yaml\Yaml; + +/** + * YamlFileDumper generates yaml files from a message catalogue. + * + * @author Michel Salib <michelsalib@hotmail.com> + */ +class YamlFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + 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.'); + } + + $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 getExtension() + { + return 'yml'; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Exception/ExceptionInterface.php b/public/system/storage/vendor/symfony/translation/Exception/ExceptionInterface.php new file mode 100644 index 0000000..c85fb93 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ +<?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\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface ExceptionInterface +{ +} diff --git a/public/system/storage/vendor/symfony/translation/Exception/InvalidResourceException.php b/public/system/storage/vendor/symfony/translation/Exception/InvalidResourceException.php new file mode 100644 index 0000000..cf07943 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Exception/InvalidResourceException.php @@ -0,0 +1,21 @@ +<?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\Exception; + +/** + * Thrown when a resource cannot be loaded. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class InvalidResourceException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/public/system/storage/vendor/symfony/translation/Exception/NotFoundResourceException.php b/public/system/storage/vendor/symfony/translation/Exception/NotFoundResourceException.php new file mode 100644 index 0000000..cff73ae --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Exception/NotFoundResourceException.php @@ -0,0 +1,21 @@ +<?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\Exception; + +/** + * Thrown when a resource does not exist. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class NotFoundResourceException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/public/system/storage/vendor/symfony/translation/Extractor/AbstractFileExtractor.php b/public/system/storage/vendor/symfony/translation/Extractor/AbstractFileExtractor.php new file mode 100644 index 0000000..57fd493 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Extractor/AbstractFileExtractor.php @@ -0,0 +1,83 @@ +<?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\Extractor; + +/** + * Base class used by classes that extract translation messages from files. + * + * @author Marcos D. Sánchez <marcosdsanchez@gmail.com> + */ +abstract class AbstractFileExtractor +{ + /** + * @param string|array $resource files, a file or a directory + * + * @return array + */ + protected function extractFiles($resource) + { + if (is_array($resource) || $resource instanceof \Traversable) { + $files = array(); + foreach ($resource as $file) { + if ($this->canBeExtracted($file)) { + $files[] = $this->toSplFileInfo($file); + } + } + } elseif (is_file($resource)) { + $files = $this->canBeExtracted($resource) ? array($this->toSplFileInfo($resource)) : array(); + } else { + $files = $this->extractFromDirectory($resource); + } + + return $files; + } + + /** + * @param string $file + * + * @return \SplFileInfo + */ + private function toSplFileInfo($file) + { + return ($file instanceof \SplFileInfo) ? $file : new \SplFileInfo($file); + } + + /** + * @param string $file + * + * @return bool + * + * @throws \InvalidArgumentException + */ + protected function isFile($file) + { + if (!is_file($file)) { + throw new \InvalidArgumentException(sprintf('The "%s" file does not exist.', $file)); + } + + return true; + } + + /** + * @param string $file + * + * @return bool + */ + abstract protected function canBeExtracted($file); + + /** + * @param string|array $resource files, a file or a directory + * + * @return array files to be extracted + */ + abstract protected function extractFromDirectory($resource); +} diff --git a/public/system/storage/vendor/symfony/translation/Extractor/ChainExtractor.php b/public/system/storage/vendor/symfony/translation/Extractor/ChainExtractor.php new file mode 100644 index 0000000..50e3c84 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Extractor/ChainExtractor.php @@ -0,0 +1,60 @@ +<?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\Extractor; + +use Symfony\Component\Translation\MessageCatalogue; + +/** + * ChainExtractor extracts translation messages from template files. + * + * @author Michel Salib <michelsalib@hotmail.com> + */ +class ChainExtractor implements ExtractorInterface +{ + /** + * The extractors. + * + * @var ExtractorInterface[] + */ + private $extractors = array(); + + /** + * Adds a loader to the translation extractor. + * + * @param string $format The format of the loader + * @param ExtractorInterface $extractor The loader + */ + public function addExtractor($format, ExtractorInterface $extractor) + { + $this->extractors[$format] = $extractor; + } + + /** + * {@inheritdoc} + */ + public function setPrefix($prefix) + { + foreach ($this->extractors as $extractor) { + $extractor->setPrefix($prefix); + } + } + + /** + * {@inheritdoc} + */ + public function extract($directory, MessageCatalogue $catalogue) + { + foreach ($this->extractors as $extractor) { + $extractor->extract($directory, $catalogue); + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/Extractor/ExtractorInterface.php b/public/system/storage/vendor/symfony/translation/Extractor/ExtractorInterface.php new file mode 100644 index 0000000..438f80b --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Extractor/ExtractorInterface.php @@ -0,0 +1,38 @@ +<?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\Extractor; + +use Symfony\Component\Translation\MessageCatalogue; + +/** + * Extracts translation messages from a directory or files to the catalogue. + * New found messages are injected to the catalogue using the prefix. + * + * @author Michel Salib <michelsalib@hotmail.com> + */ +interface ExtractorInterface +{ + /** + * Extracts translation messages from files, a file or a directory to the catalogue. + * + * @param string|array $resource files, a file or a directory + * @param MessageCatalogue $catalogue The catalogue + */ + public function extract($resource, MessageCatalogue $catalogue); + + /** + * Sets the prefix that should be used for new found messages. + * + * @param string $prefix The prefix + */ + public function setPrefix($prefix); +} diff --git a/public/system/storage/vendor/symfony/translation/IdentityTranslator.php b/public/system/storage/vendor/symfony/translation/IdentityTranslator.php new file mode 100644 index 0000000..46a0463 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/IdentityTranslator.php @@ -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; + +/** + * IdentityTranslator does not translate anything. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class IdentityTranslator implements TranslatorInterface +{ + private $selector; + private $locale; + + /** + * Constructor. + * + * @param MessageSelector|null $selector The message selector for pluralization + */ + public function __construct(MessageSelector $selector = null) + { + $this->selector = $selector ?: new MessageSelector(); + } + + /** + * {@inheritdoc} + */ + public function setLocale($locale) + { + $this->locale = $locale; + } + + /** + * {@inheritdoc} + */ + public function getLocale() + { + return $this->locale ?: \Locale::getDefault(); + } + + /** + * {@inheritdoc} + */ + public function trans($id, array $parameters = array(), $domain = null, $locale = null) + { + return strtr((string) $id, $parameters); + } + + /** + * {@inheritdoc} + */ + public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) + { + return strtr($this->selector->choose((string) $id, (int) $number, $locale ?: $this->getLocale()), $parameters); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Interval.php b/public/system/storage/vendor/symfony/translation/Interval.php new file mode 100644 index 0000000..2a51156 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Interval.php @@ -0,0 +1,107 @@ +<?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; + +/** + * Tests if a given number belongs to a given math interval. + * + * An interval can represent a finite set of numbers: + * + * {1,2,3,4} + * + * An interval can represent numbers between two numbers: + * + * [1, +Inf] + * ]-1,2[ + * + * The left delimiter can be [ (inclusive) or ] (exclusive). + * The right delimiter can be [ (exclusive) or ] (inclusive). + * Beside numbers, you can use -Inf and +Inf for the infinite. + * + * @author Fabien Potencier <fabien@symfony.com> + * + * @see http://en.wikipedia.org/wiki/Interval_%28mathematics%29#The_ISO_notation + */ +class Interval +{ + /** + * Tests if the given number is in the math interval. + * + * @param int $number A number + * @param string $interval An interval + * + * @return bool + * + * @throws \InvalidArgumentException + */ + public static function test($number, $interval) + { + $interval = trim($interval); + + if (!preg_match('/^'.self::getIntervalRegexp().'$/x', $interval, $matches)) { + throw new \InvalidArgumentException(sprintf('"%s" is not a valid interval.', $interval)); + } + + if ($matches[1]) { + foreach (explode(',', $matches[2]) as $n) { + if ($number == $n) { + return true; + } + } + } else { + $leftNumber = self::convertNumber($matches['left']); + $rightNumber = self::convertNumber($matches['right']); + + return + ('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber) + && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber) + ; + } + + return false; + } + + /** + * Returns a Regexp that matches valid intervals. + * + * @return string A Regexp (without the delimiters) + */ + public static function getIntervalRegexp() + { + return <<<EOF + ({\s* + (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*) + \s*}) + + | + + (?P<left_delimiter>[\[\]]) + \s* + (?P<left>-Inf|\-?\d+(\.\d+)?) + \s*,\s* + (?P<right>\+?Inf|\-?\d+(\.\d+)?) + \s* + (?P<right_delimiter>[\[\]]) +EOF; + } + + private static function convertNumber($number) + { + if ('-Inf' === $number) { + return log(0); + } elseif ('+Inf' === $number || 'Inf' === $number) { + return -log(0); + } + + return (float) $number; + } +} diff --git a/public/system/storage/vendor/symfony/translation/LICENSE b/public/system/storage/vendor/symfony/translation/LICENSE new file mode 100644 index 0000000..12a7453 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/LICENSE @@ -0,0 +1,19 @@ +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 +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/public/system/storage/vendor/symfony/translation/Loader/ArrayLoader.php b/public/system/storage/vendor/symfony/translation/Loader/ArrayLoader.php new file mode 100644 index 0000000..9a595b7 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/ArrayLoader.php @@ -0,0 +1,66 @@ +<?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\MessageCatalogue; + +/** + * ArrayLoader loads translations from a PHP array. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class ArrayLoader implements LoaderInterface +{ + /** + * {@inheritdoc} + */ + public function load($resource, $locale, $domain = 'messages') + { + $this->flatten($resource); + $catalogue = new MessageCatalogue($locale); + $catalogue->add($resource, $domain); + + return $catalogue; + } + + /** + * Flattens an nested array of translations. + * + * The scheme used is: + * 'key' => array('key2' => array('key3' => 'value')) + * Becomes: + * 'key.key2.key3' => 'value' + * + * This function takes an array by reference and will modify it + * + * @param array &$messages The array that will be flattened + * @param array $subnode Current subnode being parsed, used internally for recursive calls + * @param string $path Current path being parsed, used internally for recursive calls + */ + private function flatten(array &$messages, array $subnode = null, $path = null) + { + if (null === $subnode) { + $subnode = &$messages; + } + foreach ($subnode as $key => $value) { + if (is_array($value)) { + $nodePath = $path ? $path.'.'.$key : $key; + $this->flatten($messages, $value, $nodePath); + if (null === $path) { + unset($messages[$key]); + } + } elseif (null !== $path) { + $messages[$path.'.'.$key] = $value; + } + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/CsvFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/CsvFileLoader.php new file mode 100644 index 0000000..f1d3443 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/CsvFileLoader.php @@ -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\NotFoundResourceException; + +/** + * CsvFileLoader loads translations from CSV files. + * + * @author Saša Stamenković <umpirsky@gmail.com> + */ +class CsvFileLoader extends FileLoader +{ + private $delimiter = ';'; + private $enclosure = '"'; + private $escape = '\\'; + + /** + * {@inheritdoc} + */ + protected function loadResource($resource) + { + $messages = array(); + + try { + $file = new \SplFileObject($resource, 'rb'); + } catch (\RuntimeException $e) { + throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e); + } + + $file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY); + $file->setCsvControl($this->delimiter, $this->enclosure, $this->escape); + + foreach ($file as $data) { + if ('#' !== substr($data[0], 0, 1) && isset($data[1]) && 2 === count($data)) { + $messages[$data[0]] = $data[1]; + } + } + + return $messages; + } + + /** + * Sets the delimiter, enclosure, and escape character for CSV. + * + * @param string $delimiter delimiter character + * @param string $enclosure enclosure character + * @param string $escape escape character + */ + public function setCsvControl($delimiter = ';', $enclosure = '"', $escape = '\\') + { + $this->delimiter = $delimiter; + $this->enclosure = $enclosure; + $this->escape = $escape; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/FileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/FileLoader.php new file mode 100644 index 0000000..a7f24f4 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/FileLoader.php @@ -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); +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/IcuDatFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/IcuDatFileLoader.php new file mode 100644 index 0000000..71ba90a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/IcuDatFileLoader.php @@ -0,0 +1,62 @@ +<?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\MessageCatalogue; +use Symfony\Component\Translation\Exception\InvalidResourceException; +use Symfony\Component\Translation\Exception\NotFoundResourceException; +use Symfony\Component\Config\Resource\FileResource; + +/** + * IcuResFileLoader loads translations from a resource bundle. + * + * @author stealth35 + */ +class IcuDatFileLoader extends IcuResFileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $locale, $domain = 'messages') + { + if (!stream_is_local($resource.'.dat')) { + throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource)); + } + + if (!file_exists($resource.'.dat')) { + throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource)); + } + + try { + $rb = new \ResourceBundle($locale, $resource); + } catch (\Exception $e) { + // HHVM compatibility: constructor throws on invalid resource + $rb = null; + } + + if (!$rb) { + throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource)); + } elseif (intl_is_failure($rb->getErrorCode())) { + throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode()); + } + + $messages = $this->flatten($rb); + $catalogue = new MessageCatalogue($locale); + $catalogue->add($messages, $domain); + + if (class_exists('Symfony\Component\Config\Resource\FileResource')) { + $catalogue->addResource(new FileResource($resource.'.dat')); + } + + return $catalogue; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/IcuResFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/IcuResFileLoader.php new file mode 100644 index 0000000..2f8037f --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/IcuResFileLoader.php @@ -0,0 +1,92 @@ +<?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\MessageCatalogue; +use Symfony\Component\Translation\Exception\InvalidResourceException; +use Symfony\Component\Translation\Exception\NotFoundResourceException; +use Symfony\Component\Config\Resource\DirectoryResource; + +/** + * IcuResFileLoader loads translations from a resource bundle. + * + * @author stealth35 + */ +class IcuResFileLoader implements LoaderInterface +{ + /** + * {@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 (!is_dir($resource)) { + throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource)); + } + + try { + $rb = new \ResourceBundle($locale, $resource); + } catch (\Exception $e) { + // HHVM compatibility: constructor throws on invalid resource + $rb = null; + } + + if (!$rb) { + throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource)); + } elseif (intl_is_failure($rb->getErrorCode())) { + throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode()); + } + + $messages = $this->flatten($rb); + $catalogue = new MessageCatalogue($locale); + $catalogue->add($messages, $domain); + + if (class_exists('Symfony\Component\Config\Resource\DirectoryResource')) { + $catalogue->addResource(new DirectoryResource($resource)); + } + + return $catalogue; + } + + /** + * Flattens an ResourceBundle. + * + * The scheme used is: + * key { key2 { key3 { "value" } } } + * Becomes: + * 'key.key2.key3' => 'value' + * + * This function takes an array by reference and will modify it + * + * @param \ResourceBundle $rb the ResourceBundle that will be flattened + * @param array $messages used internally for recursive calls + * @param string $path current path being parsed, used internally for recursive calls + * + * @return array the flattened ResourceBundle + */ + protected function flatten(\ResourceBundle $rb, array &$messages = array(), $path = null) + { + foreach ($rb as $key => $value) { + $nodePath = $path ? $path.'.'.$key : $key; + if ($value instanceof \ResourceBundle) { + $this->flatten($value, $messages, $nodePath); + } else { + $messages[$nodePath] = $value; + } + } + + return $messages; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/IniFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/IniFileLoader.php new file mode 100644 index 0000000..11d9b27 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/IniFileLoader.php @@ -0,0 +1,28 @@ +<?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; + +/** + * IniFileLoader loads translations from an ini file. + * + * @author stealth35 + */ +class IniFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + protected function loadResource($resource) + { + return parse_ini_file($resource, true); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/JsonFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/JsonFileLoader.php new file mode 100644 index 0000000..ce4e91f --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/JsonFileLoader.php @@ -0,0 +1,64 @@ +<?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; + +/** + * JsonFileLoader loads translations from an json file. + * + * @author singles + */ +class JsonFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + protected function loadResource($resource) + { + $messages = array(); + if ($data = file_get_contents($resource)) { + $messages = json_decode($data, true); + + if (0 < $errorCode = json_last_error()) { + throw new InvalidResourceException(sprintf('Error parsing JSON - %s', $this->getJSONErrorMessage($errorCode))); + } + } + + return $messages; + } + + /** + * Translates JSON_ERROR_* constant into meaningful message. + * + * @param int $errorCode Error code returned by json_last_error() call + * + * @return string Message string + */ + private function getJSONErrorMessage($errorCode) + { + switch ($errorCode) { + case JSON_ERROR_DEPTH: + return 'Maximum stack depth exceeded'; + case JSON_ERROR_STATE_MISMATCH: + return 'Underflow or the modes mismatch'; + case JSON_ERROR_CTRL_CHAR: + return 'Unexpected control character found'; + case JSON_ERROR_SYNTAX: + return 'Syntax error, malformed JSON'; + case JSON_ERROR_UTF8: + return 'Malformed UTF-8 characters, possibly incorrectly encoded'; + default: + return 'Unknown error'; + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/LoaderInterface.php b/public/system/storage/vendor/symfony/translation/Loader/LoaderInterface.php new file mode 100644 index 0000000..6b65fe3 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/LoaderInterface.php @@ -0,0 +1,38 @@ +<?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\MessageCatalogue; +use Symfony\Component\Translation\Exception\InvalidResourceException; +use Symfony\Component\Translation\Exception\NotFoundResourceException; + +/** + * LoaderInterface is the interface implemented by all translation loaders. + * + * @author Fabien Potencier <fabien@symfony.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 + * + * @throws NotFoundResourceException when the resource cannot be found + * @throws InvalidResourceException when the resource cannot be loaded + */ + public function load($resource, $locale, $domain = 'messages'); +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/MoFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/MoFileLoader.php new file mode 100644 index 0000000..2fcada2 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/MoFileLoader.php @@ -0,0 +1,154 @@ +<?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; + +/** + * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/) + */ +class MoFileLoader extends FileLoader +{ + /** + * Magic used for validating the format of a MO file as well as + * detecting if the machine used to create that file was little endian. + * + * @var float + */ + const MO_LITTLE_ENDIAN_MAGIC = 0x950412de; + + /** + * Magic used for validating the format of a MO file as well as + * detecting if the machine used to create that file was big endian. + * + * @var float + */ + const MO_BIG_ENDIAN_MAGIC = 0xde120495; + + /** + * The size of the header of a MO file in bytes. + * + * @var int Number of bytes + */ + const MO_HEADER_SIZE = 28; + + /** + * Parses machine object (MO) format, independent of the machine's endian it + * was created on. Both 32bit and 64bit systems are supported. + * + * {@inheritdoc} + */ + protected function loadResource($resource) + { + $stream = fopen($resource, 'r'); + + $stat = fstat($stream); + + if ($stat['size'] < self::MO_HEADER_SIZE) { + throw new InvalidResourceException('MO stream content has an invalid format.'); + } + $magic = unpack('V1', fread($stream, 4)); + $magic = hexdec(substr(dechex(current($magic)), -8)); + + if ($magic == self::MO_LITTLE_ENDIAN_MAGIC) { + $isBigEndian = false; + } elseif ($magic == self::MO_BIG_ENDIAN_MAGIC) { + $isBigEndian = true; + } else { + throw new InvalidResourceException('MO stream content has an invalid format.'); + } + + // formatRevision + $this->readLong($stream, $isBigEndian); + $count = $this->readLong($stream, $isBigEndian); + $offsetId = $this->readLong($stream, $isBigEndian); + $offsetTranslated = $this->readLong($stream, $isBigEndian); + // sizeHashes + $this->readLong($stream, $isBigEndian); + // offsetHashes + $this->readLong($stream, $isBigEndian); + + $messages = array(); + + for ($i = 0; $i < $count; ++$i) { + $singularId = $pluralId = null; + $translated = null; + + fseek($stream, $offsetId + $i * 8); + + $length = $this->readLong($stream, $isBigEndian); + $offset = $this->readLong($stream, $isBigEndian); + + if ($length < 1) { + continue; + } + + fseek($stream, $offset); + $singularId = fread($stream, $length); + + if (strpos($singularId, "\000") !== false) { + list($singularId, $pluralId) = explode("\000", $singularId); + } + + fseek($stream, $offsetTranslated + $i * 8); + $length = $this->readLong($stream, $isBigEndian); + $offset = $this->readLong($stream, $isBigEndian); + + if ($length < 1) { + continue; + } + + fseek($stream, $offset); + $translated = fread($stream, $length); + + if (strpos($translated, "\000") !== false) { + $translated = explode("\000", $translated); + } + + $ids = array('singular' => $singularId, 'plural' => $pluralId); + $item = compact('ids', 'translated'); + + if (is_array($item['translated'])) { + $messages[$item['ids']['singular']] = stripcslashes($item['translated'][0]); + if (isset($item['ids']['plural'])) { + $plurals = array(); + foreach ($item['translated'] as $plural => $translated) { + $plurals[] = sprintf('{%d} %s', $plural, $translated); + } + $messages[$item['ids']['plural']] = stripcslashes(implode('|', $plurals)); + } + } elseif (!empty($item['ids']['singular'])) { + $messages[$item['ids']['singular']] = stripcslashes($item['translated']); + } + } + + fclose($stream); + + return array_filter($messages); + } + + /** + * Reads an unsigned long from stream respecting endianess. + * + * @param resource $stream + * @param bool $isBigEndian + * + * @return int + */ + private function readLong($stream, $isBigEndian) + { + $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4)); + $result = current($result); + + return (int) substr($result, -8); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/PhpFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/PhpFileLoader.php new file mode 100644 index 0000000..a0050e8 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/PhpFileLoader.php @@ -0,0 +1,28 @@ +<?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; + +/** + * PhpFileLoader loads translations from PHP files returning an array of translations. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class PhpFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + protected function loadResource($resource) + { + return require $resource; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/PoFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/PoFileLoader.php new file mode 100644 index 0000000..40f5464 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/PoFileLoader.php @@ -0,0 +1,151 @@ +<?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; + +/** + * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/) + * @copyright Copyright (c) 2012, Clemens Tolboom + */ +class PoFileLoader extends FileLoader +{ + /** + * Parses portable object (PO) format. + * + * From http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files + * we should be able to parse files having: + * + * white-space + * # translator-comments + * #. extracted-comments + * #: reference... + * #, flag... + * #| msgid previous-untranslated-string + * msgid untranslated-string + * msgstr translated-string + * + * extra or different lines are: + * + * #| msgctxt previous-context + * #| msgid previous-untranslated-string + * msgctxt context + * + * #| msgid previous-untranslated-string-singular + * #| msgid_plural previous-untranslated-string-plural + * msgid untranslated-string-singular + * msgid_plural untranslated-string-plural + * msgstr[0] translated-string-case-0 + * ... + * msgstr[N] translated-string-case-n + * + * The definition states: + * - white-space and comments are optional. + * - msgid "" that an empty singleline defines a header. + * + * This parser sacrifices some features of the reference implementation the + * differences to that implementation are as follows. + * - No support for comments spanning multiple lines. + * - Translator and extracted comments are treated as being the same type. + * - Message IDs are allowed to have other encodings as just US-ASCII. + * + * Items with an empty id are ignored. + * + * {@inheritdoc} + */ + protected function loadResource($resource) + { + $stream = fopen($resource, 'r'); + + $defaults = array( + 'ids' => array(), + 'translated' => null, + ); + + $messages = array(); + $item = $defaults; + $flags = array(); + + while ($line = fgets($stream)) { + $line = trim($line); + + if ($line === '') { + // Whitespace indicated current item is done + 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 + $this->addMessage($messages, $item); + $item = $defaults; + $item['ids']['singular'] = substr($line, 7, -1); + } elseif (substr($line, 0, 8) === 'msgstr "') { + $item['translated'] = substr($line, 8, -1); + } elseif ($line[0] === '"') { + $continues = isset($item['translated']) ? 'translated' : 'ids'; + + if (is_array($item[$continues])) { + end($item[$continues]); + $item[$continues][key($item[$continues])] .= substr($line, 1, -1); + } else { + $item[$continues] .= substr($line, 1, -1); + } + } elseif (substr($line, 0, 14) === 'msgid_plural "') { + $item['ids']['plural'] = substr($line, 14, -1); + } elseif (substr($line, 0, 7) === 'msgstr[') { + $size = strpos($line, ']'); + $item['translated'][(int) substr($line, 7, 1)] = substr($line, $size + 3, -1); + } + } + // save last item + if (!in_array('fuzzy', $flags)) { + $this->addMessage($messages, $item); + } + fclose($stream); + + return $messages; + } + + /** + * Save a translation item to the messages. + * + * A .po file could contain by error missing plural indexes. We need to + * fix these before saving them. + * + * @param array $messages + * @param array $item + */ + private function addMessage(array &$messages, array $item) + { + if (is_array($item['translated'])) { + $messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated'][0]); + if (isset($item['ids']['plural'])) { + $plurals = $item['translated']; + // PO are by definition indexed so sort by index. + ksort($plurals); + // Make sure every index is filled. + end($plurals); + $count = key($plurals); + // Fill missing spots with '-'. + $empties = array_fill(0, $count + 1, '-'); + $plurals += $empties; + ksort($plurals); + $messages[stripcslashes($item['ids']['plural'])] = stripcslashes(implode('|', $plurals)); + } + } elseif (!empty($item['ids']['singular'])) { + $messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated']); + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/QtFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/QtFileLoader.php new file mode 100644 index 0000000..657bd6e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/QtFileLoader.php @@ -0,0 +1,77 @@ +<?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\Util\XmlUtils; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Exception\InvalidResourceException; +use Symfony\Component\Translation\Exception\NotFoundResourceException; +use Symfony\Component\Config\Resource\FileResource; + +/** + * QtFileLoader loads translations from QT Translations XML files. + * + * @author Benjamin Eberlei <kontakt@beberlei.de> + */ +class QtFileLoader implements LoaderInterface +{ + /** + * {@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)); + } + + try { + $dom = XmlUtils::loadFile($resource); + } catch (\InvalidArgumentException $e) { + throw new InvalidResourceException(sprintf('Unable to load "%s".', $resource), $e->getCode(), $e); + } + + $internalErrors = libxml_use_internal_errors(true); + libxml_clear_errors(); + + $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) { + $translationValue = (string) $translation->getElementsByTagName('translation')->item(0)->nodeValue; + + if (!empty($translationValue)) { + $catalogue->set( + (string) $translation->getElementsByTagName('source')->item(0)->nodeValue, + $translationValue, + $domain + ); + } + $translation = $translation->nextSibling; + } + + if (class_exists('Symfony\Component\Config\Resource\FileResource')) { + $catalogue->addResource(new FileResource($resource)); + } + } + + libxml_use_internal_errors($internalErrors); + + return $catalogue; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/XliffFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/XliffFileLoader.php new file mode 100644 index 0000000..d3fbec9 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/XliffFileLoader.php @@ -0,0 +1,321 @@ +<?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\Util\XmlUtils; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Exception\InvalidResourceException; +use Symfony\Component\Translation\Exception\NotFoundResourceException; +use Symfony\Component\Config\Resource\FileResource; + +/** + * XliffFileLoader loads translations from XLIFF files. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class XliffFileLoader implements LoaderInterface +{ + /** + * {@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)); + } + + $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(); + + if (!(isset($attributes['resname']) || isset($translation->source))) { + continue; + } + + $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->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($translation->target) ? $translation->target : $source), $encoding); + + $catalogue->set((string) $source, $target, $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; + } + } + + $catalogue->setMetadata((string) $source, $metadata, $domain); + } + } + + /** + * @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); + } + } + + /** + * Convert a UTF8 string to the specified encoding. + * + * @param string $content String to decode + * @param string $encoding Target encoding + * + * @return string + */ + private function utf8ToCharset($content, $encoding = null) + { + if ('UTF-8' !== $encoding && !empty($encoding)) { + return mb_convert_encoding($content, $encoding, 'UTF-8'); + } + + return $content; + } + + /** + * Validates and parses the given file into a DOMDocument. + * + * @param string $file + * @param \DOMDocument $dom + * @param string $schema source of the schema + * + * @throws InvalidResourceException + */ + private function validateSchema($file, \DOMDocument $dom, $schema) + { + $internalErrors = libxml_use_internal_errors(true); + + $disableEntities = libxml_disable_entity_loader(false); + + if (!@$dom->schemaValidateSource($schema)) { + libxml_disable_entity_loader($disableEntities); + + throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s', $file, implode("\n", $this->getXmlErrors($internalErrors)))); + } + + libxml_disable_entity_loader($disableEntities); + + $dom->normalizeDocument(); + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + } + + 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); + } + + /** + * Returns the XML errors of the internal XML parser. + * + * @param bool $internalErrors + * + * @return array An array of errors + */ + private function getXmlErrors($internalErrors) + { + $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 ?: 'n/a', + $error->line, + $error->column + ); + } + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + + 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; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/YamlFileLoader.php b/public/system/storage/vendor/symfony/translation/Loader/YamlFileLoader.php new file mode 100644 index 0000000..5d9a3ad --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/YamlFileLoader.php @@ -0,0 +1,48 @@ +<?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\Yaml\Parser as YamlParser; +use Symfony\Component\Yaml\Exception\ParseException; + +/** + * YamlFileLoader loads translations from Yaml files. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class YamlFileLoader extends FileLoader +{ + private $yamlParser; + + /** + * {@inheritdoc} + */ + protected function loadResource($resource) + { + 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(); + } + + try { + $messages = $this->yamlParser->parse(file_get_contents($resource)); + } catch (ParseException $e) { + throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s"', $resource), 0, $e); + } + + return $messages; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd b/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd new file mode 100644 index 0000000..3ce2a8e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd @@ -0,0 +1,2223 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + +May-19-2004: +- Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements +to <choice> itself. +- Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and +<alt-trans>. + +Oct-2005 +- updated version info to 1.2 +- equiv-trans attribute to <trans-unit> element +- merged-trans attribute for <group> element +- Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source> +- Create a new value "seg" for the mtype attribute of the <mrk> element +- Add mid as an optional attribute for the <alt-trans> element + +Nov-14-2005 +- Changed name attribute for <context-group> from required to optional +- Added extension point at <xliff> + +Jan-9-2006 +- Added alttranstype type attribute to <alt-trans>, and values + +Jan-10-2006 +- Corrected error with overwritten purposeValueList +- Corrected name="AttrType_Version", attribute should have been "name" + +--> +<xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en"> + <!-- Import for xml:lang and xml:space --> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/> + <!-- Attributes Lists --> + <xsd:simpleType name="XTend"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="x-[^\s]+"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="context-typeValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="database"> + <xsd:annotation> + <xsd:documentation>Indicates a database content.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="element"> + <xsd:annotation> + <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="elementtitle"> + <xsd:annotation> + <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="linenumber"> + <xsd:annotation> + <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the <source> is found.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="numparams"> + <xsd:annotation> + <xsd:documentation>Indicates a the number of parameters contained within the <source>.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="paramnotes"> + <xsd:annotation> + <xsd:documentation>Indicates notes pertaining to the parameters in the <source>.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="record"> + <xsd:annotation> + <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="recordtitle"> + <xsd:annotation> + <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="sourcefile"> + <xsd:annotation> + <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original <file> attribute in that this sourcefile is one of many that make up that file.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="count-typeValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="num-usages"> + <xsd:annotation> + <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="repetition"> + <xsd:annotation> + <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="total"> + <xsd:annotation> + <xsd:documentation>Indicates a total count.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="InlineDelimitersValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'ctype' when used other elements than <ph> or <x>.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="bold"> + <xsd:annotation> + <xsd:documentation>Indicates a run of bolded text.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="italic"> + <xsd:annotation> + <xsd:documentation>Indicates a run of text in italics.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="underlined"> + <xsd:annotation> + <xsd:documentation>Indicates a run of underlined text.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="link"> + <xsd:annotation> + <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="InlinePlaceholdersValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'ctype' when used with <ph> or <x>.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="image"> + <xsd:annotation> + <xsd:documentation>Indicates a inline image.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="pb"> + <xsd:annotation> + <xsd:documentation>Indicates a page break.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="lb"> + <xsd:annotation> + <xsd:documentation>Indicates a line break.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="mime-typeValueList"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="datatypeValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="asp"> + <xsd:annotation> + <xsd:documentation>Indicates Active Server Page data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="c"> + <xsd:annotation> + <xsd:documentation>Indicates C source file data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="cdf"> + <xsd:annotation> + <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="cfm"> + <xsd:annotation> + <xsd:documentation>Indicates ColdFusion data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="cpp"> + <xsd:annotation> + <xsd:documentation>Indicates C++ source file data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="csharp"> + <xsd:annotation> + <xsd:documentation>Indicates C-Sharp data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="cstring"> + <xsd:annotation> + <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="csv"> + <xsd:annotation> + <xsd:documentation>Indicates comma-separated values data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="database"> + <xsd:annotation> + <xsd:documentation>Indicates database data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="documentfooter"> + <xsd:annotation> + <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="documentheader"> + <xsd:annotation> + <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="filedialog"> + <xsd:annotation> + <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="form"> + <xsd:annotation> + <xsd:documentation>Indicates standard user input screen data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="html"> + <xsd:annotation> + <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="htmlbody"> + <xsd:annotation> + <xsd:documentation>Indicates content within an HTML document’s <body> element.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="ini"> + <xsd:annotation> + <xsd:documentation>Indicates Windows INI file data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="interleaf"> + <xsd:annotation> + <xsd:documentation>Indicates Interleaf data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="javaclass"> + <xsd:annotation> + <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="javapropertyresourcebundle"> + <xsd:annotation> + <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="javalistresourcebundle"> + <xsd:annotation> + <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="javascript"> + <xsd:annotation> + <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="jscript"> + <xsd:annotation> + <xsd:documentation>Indicates JScript source file data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="layout"> + <xsd:annotation> + <xsd:documentation>Indicates information relating to formatting.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="lisp"> + <xsd:annotation> + <xsd:documentation>Indicates LISP source file data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="margin"> + <xsd:annotation> + <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="menufile"> + <xsd:annotation> + <xsd:documentation>Indicates a file containing menu.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="messagefile"> + <xsd:annotation> + <xsd:documentation>Indicates numerically identified string table.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="mif"> + <xsd:annotation> + <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="mimetype"> + <xsd:annotation> + <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="mo"> + <xsd:annotation> + <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="msglib"> + <xsd:annotation> + <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="pagefooter"> + <xsd:annotation> + <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="pageheader"> + <xsd:annotation> + <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="parameters"> + <xsd:annotation> + <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="pascal"> + <xsd:annotation> + <xsd:documentation>Indicates Pascal source file data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="php"> + <xsd:annotation> + <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="plaintext"> + <xsd:annotation> + <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="po"> + <xsd:annotation> + <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="report"> + <xsd:annotation> + <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="resources"> + <xsd:annotation> + <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="resx"> + <xsd:annotation> + <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="rtf"> + <xsd:annotation> + <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="sgml"> + <xsd:annotation> + <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="sgmldtd"> + <xsd:annotation> + <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="svg"> + <xsd:annotation> + <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="vbscript"> + <xsd:annotation> + <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="warning"> + <xsd:annotation> + <xsd:documentation>Indicates warning message.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="winres"> + <xsd:annotation> + <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="xhtml"> + <xsd:annotation> + <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="xml"> + <xsd:annotation> + <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="xmldtd"> + <xsd:annotation> + <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="xsl"> + <xsd:annotation> + <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="xul"> + <xsd:annotation> + <xsd:documentation>Indicates XUL elements.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="mtypeValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="abbrev"> + <xsd:annotation> + <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="abbreviated-form"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="abbreviation"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="acronym"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="appellation"> + <xsd:annotation> + <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="collocation"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="common-name"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="datetime"> + <xsd:annotation> + <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="equation"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="expanded-form"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="formula"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="head-term"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="initialism"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="international-scientific-term"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="internationalism"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="logical-expression"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="materials-management-unit"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="name"> + <xsd:annotation> + <xsd:documentation>Indicates the marked text is a name.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="near-synonym"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="part-number"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="phrase"> + <xsd:annotation> + <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="phraseological-unit"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="protected"> + <xsd:annotation> + <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="romanized-form"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="seg"> + <xsd:annotation> + <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="set-phrase"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="short-form"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="sku"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="standard-text"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="symbol"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="synonym"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="synonymous-phrase"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="term"> + <xsd:annotation> + <xsd:documentation>Indicates the marked text is a term.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="transcribed-form"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="transliterated-form"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="truncated-term"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="variant"> + <xsd:annotation> + <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="restypeValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="auto3state"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="autocheckbox"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="autoradiobutton"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="bedit"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="bitmap"> + <xsd:annotation> + <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="button"> + <xsd:annotation> + <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="caption"> + <xsd:annotation> + <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="cell"> + <xsd:annotation> + <xsd:documentation>Indicates the cell in a table, for example the content of the <td> element in HTML.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="checkbox"> + <xsd:annotation> + <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="checkboxmenuitem"> + <xsd:annotation> + <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="checkedlistbox"> + <xsd:annotation> + <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="colorchooser"> + <xsd:annotation> + <xsd:documentation>Indicates a color selection dialog.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="combobox"> + <xsd:annotation> + <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="comboboxexitem"> + <xsd:annotation> + <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="comboboxitem"> + <xsd:annotation> + <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="component"> + <xsd:annotation> + <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="contextmenu"> + <xsd:annotation> + <xsd:documentation>Indicates a context menu.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="ctext"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="cursor"> + <xsd:annotation> + <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="datetimepicker"> + <xsd:annotation> + <xsd:documentation>Indicates a date/time picker.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="defpushbutton"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="dialog"> + <xsd:annotation> + <xsd:documentation>Indicates a dialog box.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="dlginit"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="edit"> + <xsd:annotation> + <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="file"> + <xsd:annotation> + <xsd:documentation>Indicates a filename.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="filechooser"> + <xsd:annotation> + <xsd:documentation>Indicates a file dialog.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="fn"> + <xsd:annotation> + <xsd:documentation>Indicates a footnote.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="font"> + <xsd:annotation> + <xsd:documentation>Indicates a font name.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="footer"> + <xsd:annotation> + <xsd:documentation>Indicates a footer.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="frame"> + <xsd:annotation> + <xsd:documentation>Indicates a frame object.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="grid"> + <xsd:annotation> + <xsd:documentation>Indicates a XUL grid element.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="groupbox"> + <xsd:annotation> + <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="header"> + <xsd:annotation> + <xsd:documentation>Indicates a header item.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="heading"> + <xsd:annotation> + <xsd:documentation>Indicates a heading, such has the content of <h1>, <h2>, etc. in HTML.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="hedit"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="hscrollbar"> + <xsd:annotation> + <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="icon"> + <xsd:annotation> + <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="iedit"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="keywords"> + <xsd:annotation> + <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="label"> + <xsd:annotation> + <xsd:documentation>Indicates a label object.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="linklabel"> + <xsd:annotation> + <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="list"> + <xsd:annotation> + <xsd:documentation>Indicates a list (a group of list-items, for example an <ol> or <ul> element in HTML).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="listbox"> + <xsd:annotation> + <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="listitem"> + <xsd:annotation> + <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="ltext"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="menu"> + <xsd:annotation> + <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="menubar"> + <xsd:annotation> + <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="menuitem"> + <xsd:annotation> + <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="menuseparator"> + <xsd:annotation> + <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="message"> + <xsd:annotation> + <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="monthcalendar"> + <xsd:annotation> + <xsd:documentation>Indicates a calendar control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="numericupdown"> + <xsd:annotation> + <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="panel"> + <xsd:annotation> + <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="popupmenu"> + <xsd:annotation> + <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="pushbox"> + <xsd:annotation> + <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="pushbutton"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="radio"> + <xsd:annotation> + <xsd:documentation>Indicates a radio button object.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="radiobuttonmenuitem"> + <xsd:annotation> + <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="rcdata"> + <xsd:annotation> + <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="row"> + <xsd:annotation> + <xsd:documentation>Indicates a row in a table.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="rtext"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="scrollpane"> + <xsd:annotation> + <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="separator"> + <xsd:annotation> + <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="shortcut"> + <xsd:annotation> + <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="spinner"> + <xsd:annotation> + <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="splitter"> + <xsd:annotation> + <xsd:documentation>Indicates a splitter bar.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="state3"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="statusbar"> + <xsd:annotation> + <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="string"> + <xsd:annotation> + <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="tabcontrol"> + <xsd:annotation> + <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="table"> + <xsd:annotation> + <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="textbox"> + <xsd:annotation> + <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="togglebutton"> + <xsd:annotation> + <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="toolbar"> + <xsd:annotation> + <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="tooltip"> + <xsd:annotation> + <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="trackbar"> + <xsd:annotation> + <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="tree"> + <xsd:annotation> + <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="uri"> + <xsd:annotation> + <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="userbutton"> + <xsd:annotation> + <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="usercontrol"> + <xsd:annotation> + <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="var"> + <xsd:annotation> + <xsd:documentation>Indicates the text of a variable.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="versioninfo"> + <xsd:annotation> + <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="vscrollbar"> + <xsd:annotation> + <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="window"> + <xsd:annotation> + <xsd:documentation>Indicates a graphical window.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="size-unitValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="byte"> + <xsd:annotation> + <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="char"> + <xsd:annotation> + <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="col"> + <xsd:annotation> + <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="cm"> + <xsd:annotation> + <xsd:documentation>Indicates a size in centimeters.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="dlgunit"> + <xsd:annotation> + <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="em"> + <xsd:annotation> + <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="ex"> + <xsd:annotation> + <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="glyph"> + <xsd:annotation> + <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="in"> + <xsd:annotation> + <xsd:documentation>Indicates a size in inches.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="mm"> + <xsd:annotation> + <xsd:documentation>Indicates a size in millimeters.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="percent"> + <xsd:annotation> + <xsd:documentation>Indicates a size in percentage.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="pixel"> + <xsd:annotation> + <xsd:documentation>Indicates a size in pixels.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="point"> + <xsd:annotation> + <xsd:documentation>Indicates a size in point.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="row"> + <xsd:annotation> + <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="stateValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'state'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="final"> + <xsd:annotation> + <xsd:documentation>Indicates the terminating state.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="needs-adaptation"> + <xsd:annotation> + <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="needs-l10n"> + <xsd:annotation> + <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="needs-review-adaptation"> + <xsd:annotation> + <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="needs-review-l10n"> + <xsd:annotation> + <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="needs-review-translation"> + <xsd:annotation> + <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="needs-translation"> + <xsd:annotation> + <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="new"> + <xsd:annotation> + <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="signed-off"> + <xsd:annotation> + <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="translated"> + <xsd:annotation> + <xsd:documentation>Indicates that the item has been translated.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="state-qualifierValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="exact-match"> + <xsd:annotation> + <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="fuzzy-match"> + <xsd:annotation> + <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="id-match"> + <xsd:annotation> + <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="leveraged-glossary"> + <xsd:annotation> + <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="leveraged-inherited"> + <xsd:annotation> + <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="leveraged-mt"> + <xsd:annotation> + <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="leveraged-repository"> + <xsd:annotation> + <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="leveraged-tm"> + <xsd:annotation> + <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="mt-suggestion"> + <xsd:annotation> + <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="rejected-grammar"> + <xsd:annotation> + <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="rejected-inaccurate"> + <xsd:annotation> + <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="rejected-length"> + <xsd:annotation> + <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="rejected-spelling"> + <xsd:annotation> + <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="tm-suggestion"> + <xsd:annotation> + <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="unitValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="word"> + <xsd:annotation> + <xsd:documentation>Refers to words.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="page"> + <xsd:annotation> + <xsd:documentation>Refers to pages.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="trans-unit"> + <xsd:annotation> + <xsd:documentation>Refers to <trans-unit> elements.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="bin-unit"> + <xsd:annotation> + <xsd:documentation>Refers to <bin-unit> elements.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="glyph"> + <xsd:annotation> + <xsd:documentation>Refers to glyphs.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="item"> + <xsd:annotation> + <xsd:documentation>Refers to <trans-unit> and/or <bin-unit> elements.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="instance"> + <xsd:annotation> + <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="character"> + <xsd:annotation> + <xsd:documentation>Refers to characters.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="line"> + <xsd:annotation> + <xsd:documentation>Refers to lines.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="sentence"> + <xsd:annotation> + <xsd:documentation>Refers to sentences.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="paragraph"> + <xsd:annotation> + <xsd:documentation>Refers to paragraphs.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="segment"> + <xsd:annotation> + <xsd:documentation>Refers to segments.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="placeable"> + <xsd:annotation> + <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="priorityValueList"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:positiveInteger"> + <xsd:enumeration value="1"> + <xsd:annotation> + <xsd:documentation>Highest priority.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="2"> + <xsd:annotation> + <xsd:documentation>High priority.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="3"> + <xsd:annotation> + <xsd:documentation>High priority, but not as important as 2.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="4"> + <xsd:annotation> + <xsd:documentation>High priority, but not as important as 3.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="5"> + <xsd:annotation> + <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="6"> + <xsd:annotation> + <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="7"> + <xsd:annotation> + <xsd:documentation>Low priority, but more important than 8.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="8"> + <xsd:annotation> + <xsd:documentation>Low priority, but more important than 9.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="9"> + <xsd:annotation> + <xsd:documentation>Low priority.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="10"> + <xsd:annotation> + <xsd:documentation>Lowest priority.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="reformatValueYesNo"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="yes"> + <xsd:annotation> + <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="no"> + <xsd:annotation> + <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="reformatValueList"> + <xsd:list> + <xsd:simpleType> + <xsd:union memberTypes="xlf:XTend"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="coord"> + <xsd:annotation> + <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="coord-x"> + <xsd:annotation> + <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="coord-y"> + <xsd:annotation> + <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="coord-cx"> + <xsd:annotation> + <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="coord-cy"> + <xsd:annotation> + <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="font"> + <xsd:annotation> + <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="font-name"> + <xsd:annotation> + <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="font-size"> + <xsd:annotation> + <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="font-weight"> + <xsd:annotation> + <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="css-style"> + <xsd:annotation> + <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="style"> + <xsd:annotation> + <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="ex-style"> + <xsd:annotation> + <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + </xsd:union> + </xsd:simpleType> + </xsd:list> + </xsd:simpleType> + <xsd:simpleType name="purposeValueList"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="information"> + <xsd:annotation> + <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="location"> + <xsd:annotation> + <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="match"> + <xsd:annotation> + <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="alttranstypeValueList"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="proposal"> + <xsd:annotation> + <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="previous-version"> + <xsd:annotation> + <xsd:documentation>Represents a previous version of the target element.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="rejected"> + <xsd:annotation> + <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="reference"> + <xsd:annotation> + <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="accepted"> + <xsd:annotation> + <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + <!-- Other Types --> + <xsd:complexType name="ElemType_ExternalReference"> + <xsd:choice> + <xsd:element ref="xlf:internal-file"/> + <xsd:element ref="xlf:external-file"/> + </xsd:choice> + </xsd:complexType> + <xsd:simpleType name="AttrType_purpose"> + <xsd:list> + <xsd:simpleType> + <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/> + </xsd:simpleType> + </xsd:list> + </xsd:simpleType> + <xsd:simpleType name="AttrType_datatype"> + <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_restype"> + <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_alttranstype"> + <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_context-type"> + <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_state"> + <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_state-qualifier"> + <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_count-type"> + <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_InlineDelimiters"> + <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_InlinePlaceholders"> + <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_size-unit"> + <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_mtype"> + <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_unit"> + <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_priority"> + <xsd:union memberTypes="xlf:priorityValueList"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_reformat"> + <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/> + </xsd:simpleType> + <xsd:simpleType name="AttrType_YesNo"> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="yes"/> + <xsd:enumeration value="no"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="AttrType_Position"> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="open"/> + <xsd:enumeration value="close"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="AttrType_assoc"> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="preceding"/> + <xsd:enumeration value="following"/> + <xsd:enumeration value="both"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="AttrType_annotates"> + <xsd:restriction base="xsd:NMTOKEN"> + <xsd:enumeration value="source"/> + <xsd:enumeration value="target"/> + <xsd:enumeration value="general"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="AttrType_Coordinates"> + <xsd:annotation> + <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="AttrType_Version"> + <xsd:annotation> + <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation> + </xsd:annotation> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="1.2"/> + <xsd:enumeration value="1.1"/> + <xsd:enumeration value="1.0"/> + </xsd:restriction> + </xsd:simpleType> + <!-- Groups --> + <xsd:group name="ElemGroup_TextContent"> + <xsd:choice> + <xsd:element ref="xlf:g"/> + <xsd:element ref="xlf:bpt"/> + <xsd:element ref="xlf:ept"/> + <xsd:element ref="xlf:ph"/> + <xsd:element ref="xlf:it"/> + <xsd:element ref="xlf:mrk"/> + <xsd:element ref="xlf:x"/> + <xsd:element ref="xlf:bx"/> + <xsd:element ref="xlf:ex"/> + </xsd:choice> + </xsd:group> + <xsd:attributeGroup name="AttrGroup_TextContent"> + <xsd:attribute name="id" type="xsd:string" use="required"/> + <xsd:attribute name="xid" type="xsd:string" use="optional"/> + <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:attributeGroup> + <!-- XLIFF Structure --> + <xsd:element name="xliff"> + <xsd:complexType> + <xsd:sequence maxOccurs="unbounded"> + <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/> + <xsd:element ref="xlf:file"/> + </xsd:sequence> + <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/> + <xsd:attribute ref="xml:lang" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="file"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" ref="xlf:header"/> + <xsd:element ref="xlf:body"/> + </xsd:sequence> + <xsd:attribute name="original" type="xsd:string" use="required"/> + <xsd:attribute name="source-language" type="xsd:language" use="required"/> + <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/> + <xsd:attribute name="tool-id" type="xsd:string" use="optional"/> + <xsd:attribute name="date" type="xsd:dateTime" use="optional"/> + <xsd:attribute ref="xml:space" use="optional"/> + <xsd:attribute name="category" type="xsd:string" use="optional"/> + <xsd:attribute name="target-language" type="xsd:language" use="optional"/> + <xsd:attribute name="product-name" type="xsd:string" use="optional"/> + <xsd:attribute name="product-version" type="xsd:string" use="optional"/> + <xsd:attribute name="build-num" type="xsd:string" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + <xsd:unique name="U_group_id"> + <xsd:selector xpath=".//xlf:group"/> + <xsd:field xpath="@id"/> + </xsd:unique> + <xsd:key name="K_unit_id"> + <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/> + <xsd:field xpath="@id"/> + </xsd:key> + <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id"> + <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/> + <xsd:field xpath="@xid"/> + </xsd:keyref> + <xsd:key name="K_tool-id"> + <xsd:selector xpath="xlf:header/xlf:tool"/> + <xsd:field xpath="@tool-id"/> + </xsd:key> + <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id"> + <xsd:selector xpath="."/> + <xsd:field xpath="@tool-id"/> + </xsd:keyref> + <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id"> + <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/> + <xsd:field xpath="@tool-id"/> + </xsd:keyref> + <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id"> + <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/> + <xsd:field xpath="@tool-id"/> + </xsd:keyref> + <xsd:key name="K_count-group_name"> + <xsd:selector xpath=".//xlf:count-group"/> + <xsd:field xpath="@name"/> + </xsd:key> + <xsd:unique name="U_context-group_name"> + <xsd:selector xpath=".//xlf:context-group"/> + <xsd:field xpath="@name"/> + </xsd:unique> + <xsd:key name="K_phase-name"> + <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/> + <xsd:field xpath="@phase-name"/> + </xsd:key> + <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name"> + <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/> + <xsd:field xpath="@phase-name"/> + </xsd:keyref> + <xsd:unique name="U_uid"> + <xsd:selector xpath=".//xlf:external-file"/> + <xsd:field xpath="@uid"/> + </xsd:unique> + </xsd:element> + <xsd:element name="header"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/> + <xsd:element minOccurs="0" ref="xlf:phase-group"/> + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/> + <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/> + <xsd:element ref="xlf:count-group"/> + <xsd:element ref="xlf:note"/> + <xsd:element ref="xlf:tool"/> + </xsd:choice> + <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="internal-file"> + <xsd:complexType> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <xsd:attribute name="form" type="xsd:string"/> + <xsd:attribute name="crc" type="xsd:NMTOKEN"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + </xsd:element> + <xsd:element name="external-file"> + <xsd:complexType> + <xsd:attribute name="href" type="xsd:string" use="required"/> + <xsd:attribute name="crc" type="xsd:NMTOKEN"/> + <xsd:attribute name="uid" type="xsd:NMTOKEN"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="note"> + <xsd:complexType> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <xsd:attribute ref="xml:lang" use="optional"/> + <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/> + <xsd:attribute name="from" type="xsd:string" use="optional"/> + <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + </xsd:element> + <xsd:element name="phase-group"> + <xsd:complexType> + <xsd:sequence maxOccurs="unbounded"> + <xsd:element ref="xlf:phase"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="phase"> + <xsd:complexType> + <xsd:sequence maxOccurs="unbounded" minOccurs="0"> + <xsd:element ref="xlf:note"/> + </xsd:sequence> + <xsd:attribute name="phase-name" type="xsd:string" use="required"/> + <xsd:attribute name="process-name" type="xsd:string" use="required"/> + <xsd:attribute name="company-name" type="xsd:string" use="optional"/> + <xsd:attribute name="tool-id" type="xsd:string" use="optional"/> + <xsd:attribute name="date" type="xsd:dateTime" use="optional"/> + <xsd:attribute name="job-id" type="xsd:string" use="optional"/> + <xsd:attribute name="contact-name" type="xsd:string" use="optional"/> + <xsd:attribute name="contact-email" type="xsd:string" use="optional"/> + <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="count-group"> + <xsd:complexType> + <xsd:sequence maxOccurs="unbounded" minOccurs="0"> + <xsd:element ref="xlf:count"/> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="count"> + <xsd:complexType> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/> + <xsd:attribute name="phase-name" type="xsd:string" use="optional"/> + <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + </xsd:element> + <xsd:element name="context-group"> + <xsd:complexType> + <xsd:sequence maxOccurs="unbounded"> + <xsd:element ref="xlf:context"/> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="optional"/> + <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="context"> + <xsd:complexType> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/> + <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + </xsd:element> + <xsd:element name="tool"> + <xsd:complexType mixed="true"> + <xsd:sequence> + <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + <xsd:attribute name="tool-id" type="xsd:string" use="required"/> + <xsd:attribute name="tool-name" type="xsd:string" use="required"/> + <xsd:attribute name="tool-version" type="xsd:string" use="optional"/> + <xsd:attribute name="tool-company" type="xsd:string" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="body"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/> + </xsd:choice> + </xsd:complexType> + </xsd:element> + <xsd:element name="group"> + <xsd:complexType> + <xsd:sequence> + <xsd:sequence> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/> + <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/> + </xsd:sequence> + <xsd:choice maxOccurs="unbounded"> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/> + </xsd:choice> + </xsd:sequence> + <xsd:attribute name="id" type="xsd:string" use="optional"/> + <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/> + <xsd:attribute default="default" ref="xml:space" use="optional"/> + <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/> + <xsd:attribute name="resname" type="xsd:string" use="optional"/> + <xsd:attribute name="extradata" type="xsd:string" use="optional"/> + <xsd:attribute name="extype" type="xsd:string" use="optional"/> + <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="menu" type="xsd:string" use="optional"/> + <xsd:attribute name="menu-option" type="xsd:string" use="optional"/> + <xsd:attribute name="menu-name" type="xsd:string" use="optional"/> + <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/> + <xsd:attribute name="font" type="xsd:string" use="optional"/> + <xsd:attribute name="css-style" type="xsd:string" use="optional"/> + <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/> + <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/> + <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="charclass" type="xsd:string" use="optional"/> + <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="trans-unit"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="xlf:source"/> + <xsd:element minOccurs="0" ref="xlf:seg-source"/> + <xsd:element minOccurs="0" ref="xlf:target"/> + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element ref="xlf:context-group"/> + <xsd:element ref="xlf:count-group"/> + <xsd:element ref="xlf:note"/> + <xsd:element ref="xlf:alt-trans"/> + </xsd:choice> + <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/> + </xsd:sequence> + <xsd:attribute name="id" type="xsd:string" use="required"/> + <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/> + <xsd:attribute default="default" ref="xml:space" use="optional"/> + <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/> + <xsd:attribute name="phase-name" type="xsd:string" use="optional"/> + <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/> + <xsd:attribute name="resname" type="xsd:string" use="optional"/> + <xsd:attribute name="extradata" type="xsd:string" use="optional"/> + <xsd:attribute name="extype" type="xsd:string" use="optional"/> + <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="menu" type="xsd:string" use="optional"/> + <xsd:attribute name="menu-option" type="xsd:string" use="optional"/> + <xsd:attribute name="menu-name" type="xsd:string" use="optional"/> + <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/> + <xsd:attribute name="font" type="xsd:string" use="optional"/> + <xsd:attribute name="css-style" type="xsd:string" use="optional"/> + <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/> + <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="charclass" type="xsd:string" use="optional"/> + <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + <xsd:unique name="U_tu_segsrc_mid"> + <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/> + <xsd:field xpath="@mid"/> + </xsd:unique> + <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid"> + <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/> + <xsd:field xpath="@mid"/> + </xsd:keyref> + </xsd:element> + <xsd:element name="source"> + <xsd:complexType mixed="true"> + <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/> + <xsd:attribute ref="xml:lang" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + <xsd:unique name="U_source_bpt_rid"> + <xsd:selector xpath=".//xlf:bpt"/> + <xsd:field xpath="@rid"/> + </xsd:unique> + <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid"> + <xsd:selector xpath=".//xlf:ept"/> + <xsd:field xpath="@rid"/> + </xsd:keyref> + <xsd:unique name="U_source_bx_rid"> + <xsd:selector xpath=".//xlf:bx"/> + <xsd:field xpath="@rid"/> + </xsd:unique> + <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid"> + <xsd:selector xpath=".//xlf:ex"/> + <xsd:field xpath="@rid"/> + </xsd:keyref> + </xsd:element> + <xsd:element name="seg-source"> + <xsd:complexType mixed="true"> + <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/> + <xsd:attribute ref="xml:lang" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + <xsd:unique name="U_segsrc_bpt_rid"> + <xsd:selector xpath=".//xlf:bpt"/> + <xsd:field xpath="@rid"/> + </xsd:unique> + <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid"> + <xsd:selector xpath=".//xlf:ept"/> + <xsd:field xpath="@rid"/> + </xsd:keyref> + <xsd:unique name="U_segsrc_bx_rid"> + <xsd:selector xpath=".//xlf:bx"/> + <xsd:field xpath="@rid"/> + </xsd:unique> + <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid"> + <xsd:selector xpath=".//xlf:ex"/> + <xsd:field xpath="@rid"/> + </xsd:keyref> + </xsd:element> + <xsd:element name="target"> + <xsd:complexType mixed="true"> + <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/> + <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/> + <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/> + <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute ref="xml:lang" use="optional"/> + <xsd:attribute name="resname" type="xsd:string" use="optional"/> + <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/> + <xsd:attribute name="font" type="xsd:string" use="optional"/> + <xsd:attribute name="css-style" type="xsd:string" use="optional"/> + <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + <xsd:unique name="U_target_bpt_rid"> + <xsd:selector xpath=".//xlf:bpt"/> + <xsd:field xpath="@rid"/> + </xsd:unique> + <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid"> + <xsd:selector xpath=".//xlf:ept"/> + <xsd:field xpath="@rid"/> + </xsd:keyref> + <xsd:unique name="U_target_bx_rid"> + <xsd:selector xpath=".//xlf:bx"/> + <xsd:field xpath="@rid"/> + </xsd:unique> + <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid"> + <xsd:selector xpath=".//xlf:ex"/> + <xsd:field xpath="@rid"/> + </xsd:keyref> + </xsd:element> + <xsd:element name="alt-trans"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" ref="xlf:source"/> + <xsd:element minOccurs="0" ref="xlf:seg-source"/> + <xsd:element maxOccurs="1" ref="xlf:target"/> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/> + <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/> + <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/> + </xsd:sequence> + <xsd:attribute name="match-quality" type="xsd:string" use="optional"/> + <xsd:attribute name="tool-id" type="xsd:string" use="optional"/> + <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute ref="xml:lang" use="optional"/> + <xsd:attribute name="origin" type="xsd:string" use="optional"/> + <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/> + <xsd:attribute default="default" ref="xml:space" use="optional"/> + <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/> + <xsd:attribute name="resname" type="xsd:string" use="optional"/> + <xsd:attribute name="extradata" type="xsd:string" use="optional"/> + <xsd:attribute name="extype" type="xsd:string" use="optional"/> + <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="menu" type="xsd:string" use="optional"/> + <xsd:attribute name="menu-option" type="xsd:string" use="optional"/> + <xsd:attribute name="menu-name" type="xsd:string" use="optional"/> + <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/> + <xsd:attribute name="font" type="xsd:string" use="optional"/> + <xsd:attribute name="css-style" type="xsd:string" use="optional"/> + <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + <xsd:unique name="U_at_segsrc_mid"> + <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/> + <xsd:field xpath="@mid"/> + </xsd:unique> + <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid"> + <xsd:selector xpath="./xlf:target/xlf:mrk"/> + <xsd:field xpath="@mid"/> + </xsd:keyref> + </xsd:element> + <xsd:element name="bin-unit"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="xlf:bin-source"/> + <xsd:element minOccurs="0" ref="xlf:bin-target"/> + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element ref="xlf:context-group"/> + <xsd:element ref="xlf:count-group"/> + <xsd:element ref="xlf:note"/> + <xsd:element ref="xlf:trans-unit"/> + </xsd:choice> + <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/> + </xsd:sequence> + <xsd:attribute name="id" type="xsd:string" use="required"/> + <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/> + <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/> + <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/> + <xsd:attribute name="resname" type="xsd:string" use="optional"/> + <xsd:attribute name="phase-name" type="xsd:string" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="bin-source"> + <xsd:complexType> + <xsd:choice> + <xsd:element ref="xlf:internal-file"/> + <xsd:element ref="xlf:external-file"/> + </xsd:choice> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="bin-target"> + <xsd:complexType> + <xsd:choice> + <xsd:element ref="xlf:internal-file"/> + <xsd:element ref="xlf:external-file"/> + </xsd:choice> + <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/> + <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/> + <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/> + <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/> + <xsd:attribute name="resname" type="xsd:string" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + </xsd:element> + <!-- Element for inline codes --> + <xsd:element name="g"> + <xsd:complexType mixed="true"> + <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/> + <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/> + <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="x"> + <xsd:complexType> + <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/> + <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="bx"> + <xsd:complexType> + <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/> + <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/> + <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="ex"> + <xsd:complexType> + <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/> + <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="ph"> + <xsd:complexType mixed="true"> + <xsd:sequence maxOccurs="unbounded" minOccurs="0"> + <xsd:element ref="xlf:sub"/> + </xsd:sequence> + <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/> + <xsd:attribute name="crc" type="xsd:string" use="optional"/> + <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/> + <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="bpt"> + <xsd:complexType mixed="true"> + <xsd:sequence maxOccurs="unbounded" minOccurs="0"> + <xsd:element ref="xlf:sub"/> + </xsd:sequence> + <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/> + <xsd:attribute name="crc" type="xsd:string" use="optional"/> + <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="ept"> + <xsd:complexType mixed="true"> + <xsd:sequence maxOccurs="unbounded" minOccurs="0"> + <xsd:element ref="xlf:sub"/> + </xsd:sequence> + <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="crc" type="xsd:string" use="optional"/> + <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="it"> + <xsd:complexType mixed="true"> + <xsd:sequence maxOccurs="unbounded" minOccurs="0"> + <xsd:element ref="xlf:sub"/> + </xsd:sequence> + <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/> + <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/> + <xsd:attribute name="crc" type="xsd:string" use="optional"/> + <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="sub"> + <xsd:complexType mixed="true"> + <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/> + <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/> + <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/> + <xsd:attribute name="xid" type="xsd:string" use="optional"/> + </xsd:complexType> + </xsd:element> + <xsd:element name="mrk"> + <xsd:complexType mixed="true"> + <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/> + <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/> + <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/> + <xsd:attribute name="comment" type="xsd:string" use="optional"/> + <xsd:anyAttribute namespace="##other" processContents="strict"/> + </xsd:complexType> + </xsd:element> +</xsd:schema> diff --git a/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsd b/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsd new file mode 100644 index 0000000..963232f --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsd @@ -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> diff --git a/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd b/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd new file mode 100644 index 0000000..a46162a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd @@ -0,0 +1,309 @@ +<?xml version='1.0'?> +<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?> +<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns ="http://www.w3.org/1999/xhtml" + xml:lang="en"> + + <xs:annotation> + <xs:documentation> + <div> + <h1>About the XML namespace</h1> + + <div class="bodytext"> + <p> + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + </p> + <p> + See <a href="http://www.w3.org/XML/1998/namespace.html"> + http://www.w3.org/XML/1998/namespace.html</a> and + <a href="http://www.w3.org/TR/REC-xml"> + http://www.w3.org/TR/REC-xml</a> for information + about this namespace. + </p> + + <p> + Note that local names in this namespace are intended to be + defined only by the World Wide Web Consortium or its subgroups. + The names currently defined in this namespace are listed below. + They should not be used with conflicting semantics by any Working + Group, specification, or document instance. + </p> + <p> + See further below in this document for more information about <a + href="#usage">how to refer to this schema document from your own + XSD schema documents</a> and about <a href="#nsversioning">the + namespace-versioning policy governing this schema document</a>. + </p> + </div> + </div> + + </xs:documentation> + </xs:annotation> + + <xs:attribute name="lang"> + <xs:annotation> + <xs:documentation> + <div> + + <h3>lang (as an attribute name)</h3> + <p> + + denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification.</p> + + </div> + <div> + <h4>Notes</h4> + <p> + Attempting to install the relevant ISO 2- and 3-letter + codes as the enumerated possible values is probably never + going to be a realistic possibility. + </p> + <p> + + See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt"> + http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a> + and the IANA language subtag registry at + <a href="http://www.iana.org/assignments/language-subtag-registry"> + http://www.iana.org/assignments/language-subtag-registry</a> + for further information. + </p> + <p> + + The union allows for the 'un-declaration' of xml:lang with + the empty string. + </p> + </div> + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:union memberTypes="xs:language"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value=""/> + + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="space"> + <xs:annotation> + <xs:documentation> + + <div> + + <h3>space (as an attribute name)</h3> + <p> + denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification.</p> + + </div> + </xs:documentation> + </xs:annotation> + <xs:simpleType> + + <xs:restriction base="xs:NCName"> + <xs:enumeration value="default"/> + <xs:enumeration value="preserve"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="base" type="xs:anyURI"> <xs:annotation> + <xs:documentation> + + <div> + + <h3>base (as an attribute name)</h3> + <p> + denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification.</p> + + <p> + See <a + href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a> + for information about this attribute. + </p> + + </div> + </xs:documentation> + </xs:annotation> + </xs:attribute> + + <xs:attribute name="id" type="xs:ID"> + <xs:annotation> + <xs:documentation> + <div> + + <h3>id (as an attribute name)</h3> + <p> + + denotes an attribute whose value + should be interpreted as if declared to be of type ID. + This name is reserved by virtue of its definition in the + xml:id specification.</p> + + <p> + See <a + href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a> + for information about this attribute. + </p> + </div> + </xs:documentation> + </xs:annotation> + + </xs:attribute> + + <xs:attributeGroup name="specialAttrs"> + <xs:attribute ref="xml:base"/> + <xs:attribute ref="xml:lang"/> + <xs:attribute ref="xml:space"/> + <xs:attribute ref="xml:id"/> + </xs:attributeGroup> + + <xs:annotation> + + <xs:documentation> + <div> + + <h3>Father (in any context at all)</h3> + + <div class="bodytext"> + <p> + denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + </p> + <blockquote> + <p> + + In appreciation for his vision, leadership and + dedication the W3C XML Plenary on this 10th day of + February, 2000, reserves for Jon Bosak in perpetuity + the XML name "xml:Father". + </p> + </blockquote> + </div> + </div> + </xs:documentation> + </xs:annotation> + + <xs:annotation> + <xs:documentation> + + <div xml:id="usage" id="usage"> + <h2><a name="usage">About this schema document</a></h2> + + <div class="bodytext"> + <p> + This schema defines attributes and an attribute group suitable + for use by schemas wishing to allow <code>xml:base</code>, + <code>xml:lang</code>, <code>xml:space</code> or + <code>xml:id</code> attributes on elements they define. + </p> + + <p> + To enable this, such a schema must import this schema for + the XML namespace, e.g. as follows: + </p> + <pre> + <schema.. .> + .. . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/xml.xsd"/> + </pre> + <p> + or + </p> + <pre> + + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2009/01/xml.xsd"/> + </pre> + <p> + Subsequently, qualified reference to any of the attributes or the + group defined below will have the desired effect, e.g. + </p> + <pre> + <type.. .> + .. . + <attributeGroup ref="xml:specialAttrs"/> + </pre> + <p> + will define a type which will schema-validate an instance element + with any of those attributes. + </p> + + </div> + </div> + </xs:documentation> + </xs:annotation> + + <xs:annotation> + <xs:documentation> + <div id="nsversioning" xml:id="nsversioning"> + <h2><a name="nsversioning">Versioning policy for this schema document</a></h2> + + <div class="bodytext"> + <p> + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + <a href="http://www.w3.org/2009/01/xml.xsd"> + http://www.w3.org/2009/01/xml.xsd</a>. + </p> + <p> + At the date of issue it can also be found at + <a href="http://www.w3.org/2001/xml.xsd"> + http://www.w3.org/2001/xml.xsd</a>. + </p> + + <p> + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML + Schema itself, or with the XML namespace itself. In other words, + if the XML Schema or XML namespaces change, the version of this + document at <a href="http://www.w3.org/2001/xml.xsd"> + http://www.w3.org/2001/xml.xsd + </a> + will change accordingly; the version at + <a href="http://www.w3.org/2009/01/xml.xsd"> + http://www.w3.org/2009/01/xml.xsd + </a> + will not change. + </p> + <p> + + Previous dated (and unchanging) versions of this schema + document are at: + </p> + <ul> + <li><a href="http://www.w3.org/2009/01/xml.xsd"> + http://www.w3.org/2009/01/xml.xsd</a></li> + <li><a href="http://www.w3.org/2007/08/xml.xsd"> + http://www.w3.org/2007/08/xml.xsd</a></li> + <li><a href="http://www.w3.org/2004/10/xml.xsd"> + + http://www.w3.org/2004/10/xml.xsd</a></li> + <li><a href="http://www.w3.org/2001/03/xml.xsd"> + http://www.w3.org/2001/03/xml.xsd</a></li> + </ul> + </div> + </div> + </xs:documentation> + </xs:annotation> + +</xs:schema> diff --git a/public/system/storage/vendor/symfony/translation/LoggingTranslator.php b/public/system/storage/vendor/symfony/translation/LoggingTranslator.php new file mode 100644 index 0000000..fa5c5cc --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/LoggingTranslator.php @@ -0,0 +1,124 @@ +<?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; + +use Psr\Log\LoggerInterface; + +/** + * @author Abdellatif Ait boudad <a.aitboudad@gmail.com> + */ +class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface +{ + /** + * @var TranslatorInterface|TranslatorBagInterface + */ + private $translator; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface + * @param LoggerInterface $logger + */ + public function __construct(TranslatorInterface $translator, LoggerInterface $logger) + { + if (!$translator instanceof TranslatorBagInterface) { + throw new \InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator))); + } + + $this->translator = $translator; + $this->logger = $logger; + } + + /** + * {@inheritdoc} + */ + public function trans($id, array $parameters = array(), $domain = null, $locale = null) + { + $trans = $this->translator->trans($id, $parameters, $domain, $locale); + $this->log($id, $domain, $locale); + + return $trans; + } + + /** + * {@inheritdoc} + */ + public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) + { + $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale); + $this->log($id, $domain, $locale); + + return $trans; + } + + /** + * {@inheritdoc} + */ + public function setLocale($locale) + { + $this->translator->setLocale($locale); + } + + /** + * {@inheritdoc} + */ + public function getLocale() + { + return $this->translator->getLocale(); + } + + /** + * {@inheritdoc} + */ + public function getCatalogue($locale = null) + { + return $this->translator->getCatalogue($locale); + } + + /** + * Passes through all unknown calls onto the translator object. + */ + public function __call($method, $args) + { + return call_user_func_array(array($this->translator, $method), $args); + } + + /** + * Logs for missing translations. + * + * @param string $id + * @param string|null $domain + * @param string|null $locale + */ + private function log($id, $domain, $locale) + { + if (null === $domain) { + $domain = 'messages'; + } + + $id = (string) $id; + $catalogue = $this->translator->getCatalogue($locale); + if ($catalogue->defines($id, $domain)) { + return; + } + + if ($catalogue->has($id, $domain)) { + $this->logger->debug('Translation use fallback catalogue.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale())); + } else { + $this->logger->warning('Translation not found.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale())); + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/MessageCatalogue.php b/public/system/storage/vendor/symfony/translation/MessageCatalogue.php new file mode 100644 index 0000000..dd354a8 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/MessageCatalogue.php @@ -0,0 +1,270 @@ +<?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; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * MessageCatalogue. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface +{ + private $messages = array(); + private $metadata = array(); + private $resources = array(); + private $locale; + private $fallbackCatalogue; + private $parent; + + /** + * Constructor. + * + * @param string $locale The locale + * @param array $messages An array of messages classified by domain + */ + public function __construct($locale, array $messages = array()) + { + $this->locale = $locale; + $this->messages = $messages; + } + + /** + * {@inheritdoc} + */ + public function getLocale() + { + return $this->locale; + } + + /** + * {@inheritdoc} + */ + public function getDomains() + { + return array_keys($this->messages); + } + + /** + * {@inheritdoc} + */ + public function all($domain = null) + { + if (null === $domain) { + return $this->messages; + } + + return isset($this->messages[$domain]) ? $this->messages[$domain] : array(); + } + + /** + * {@inheritdoc} + */ + public function set($id, $translation, $domain = 'messages') + { + $this->add(array($id => $translation), $domain); + } + + /** + * {@inheritdoc} + */ + public function has($id, $domain = 'messages') + { + if (isset($this->messages[$domain][$id])) { + return true; + } + + if (null !== $this->fallbackCatalogue) { + return $this->fallbackCatalogue->has($id, $domain); + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function defines($id, $domain = 'messages') + { + return isset($this->messages[$domain][$id]); + } + + /** + * {@inheritdoc} + */ + public function get($id, $domain = 'messages') + { + if (isset($this->messages[$domain][$id])) { + return $this->messages[$domain][$id]; + } + + if (null !== $this->fallbackCatalogue) { + return $this->fallbackCatalogue->get($id, $domain); + } + + return $id; + } + + /** + * {@inheritdoc} + */ + public function replace($messages, $domain = 'messages') + { + $this->messages[$domain] = array(); + + $this->add($messages, $domain); + } + + /** + * {@inheritdoc} + */ + public function add($messages, $domain = 'messages') + { + if (!isset($this->messages[$domain])) { + $this->messages[$domain] = $messages; + } else { + $this->messages[$domain] = array_replace($this->messages[$domain], $messages); + } + } + + /** + * {@inheritdoc} + */ + public function addCatalogue(MessageCatalogueInterface $catalogue) + { + if ($catalogue->getLocale() !== $this->locale) { + throw new \LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale)); + } + + foreach ($catalogue->all() as $domain => $messages) { + $this->add($messages, $domain); + } + + foreach ($catalogue->getResources() as $resource) { + $this->addResource($resource); + } + + if ($catalogue instanceof MetadataAwareInterface) { + $metadata = $catalogue->getMetadata('', ''); + $this->addMetadata($metadata); + } + } + + /** + * {@inheritdoc} + */ + public function addFallbackCatalogue(MessageCatalogueInterface $catalogue) + { + // detect circular references + $c = $catalogue; + while ($c = $c->getFallbackCatalogue()) { + if ($c->getLocale() === $this->getLocale()) { + throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale())); + } + } + + $c = $this; + do { + if ($c->getLocale() === $catalogue->getLocale()) { + throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale())); + } + } while ($c = $c->parent); + + $catalogue->parent = $this; + $this->fallbackCatalogue = $catalogue; + + foreach ($catalogue->getResources() as $resource) { + $this->addResource($resource); + } + } + + /** + * {@inheritdoc} + */ + public function getFallbackCatalogue() + { + return $this->fallbackCatalogue; + } + + /** + * {@inheritdoc} + */ + public function getResources() + { + return array_values($this->resources); + } + + /** + * {@inheritdoc} + */ + public function addResource(ResourceInterface $resource) + { + $this->resources[$resource->__toString()] = $resource; + } + + /** + * {@inheritdoc} + */ + public function getMetadata($key = '', $domain = 'messages') + { + if ('' == $domain) { + return $this->metadata; + } + + if (isset($this->metadata[$domain])) { + if ('' == $key) { + return $this->metadata[$domain]; + } + + if (isset($this->metadata[$domain][$key])) { + return $this->metadata[$domain][$key]; + } + } + } + + /** + * {@inheritdoc} + */ + public function setMetadata($key, $value, $domain = 'messages') + { + $this->metadata[$domain][$key] = $value; + } + + /** + * {@inheritdoc} + */ + public function deleteMetadata($key = '', $domain = 'messages') + { + if ('' == $domain) { + $this->metadata = array(); + } elseif ('' == $key) { + unset($this->metadata[$domain]); + } else { + unset($this->metadata[$domain][$key]); + } + } + + /** + * Adds current values with the new values. + * + * @param array $values Values to add + */ + private function addMetadata(array $values) + { + foreach ($values as $domain => $keys) { + foreach ($keys as $key => $value) { + $this->setMetadata($key, $value, $domain); + } + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/MessageCatalogueInterface.php b/public/system/storage/vendor/symfony/translation/MessageCatalogueInterface.php new file mode 100644 index 0000000..b1b516d --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/MessageCatalogueInterface.php @@ -0,0 +1,142 @@ +<?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; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * MessageCatalogueInterface. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface MessageCatalogueInterface +{ + /** + * Gets the catalogue locale. + * + * @return string The locale + */ + public function getLocale(); + + /** + * Gets the domains. + * + * @return array An array of domains + */ + public function getDomains(); + + /** + * Gets the messages within a given domain. + * + * If $domain is null, it returns all messages. + * + * @param string $domain The domain name + * + * @return array An array of messages + */ + public function all($domain = null); + + /** + * Sets a message translation. + * + * @param string $id The message id + * @param string $translation The messages translation + * @param string $domain The domain name + */ + public function set($id, $translation, $domain = 'messages'); + + /** + * Checks if a message has a translation. + * + * @param string $id The message id + * @param string $domain The domain name + * + * @return bool true if the message has a translation, false otherwise + */ + public function has($id, $domain = 'messages'); + + /** + * Checks if a message has a translation (it does not take into account the fallback mechanism). + * + * @param string $id The message id + * @param string $domain The domain name + * + * @return bool true if the message has a translation, false otherwise + */ + public function defines($id, $domain = 'messages'); + + /** + * Gets a message translation. + * + * @param string $id The message id + * @param string $domain The domain name + * + * @return string The message translation + */ + public function get($id, $domain = 'messages'); + + /** + * Sets translations for a given domain. + * + * @param array $messages An array of translations + * @param string $domain The domain name + */ + public function replace($messages, $domain = 'messages'); + + /** + * Adds translations for a given domain. + * + * @param array $messages An array of translations + * @param string $domain The domain name + */ + public function add($messages, $domain = 'messages'); + + /** + * Merges translations from the given Catalogue into the current one. + * + * The two catalogues must have the same locale. + * + * @param MessageCatalogueInterface $catalogue A MessageCatalogueInterface instance + */ + public function addCatalogue(MessageCatalogueInterface $catalogue); + + /** + * Merges translations from the given Catalogue into the current one + * only when the translation does not exist. + * + * This is used to provide default translations when they do not exist for the current locale. + * + * @param MessageCatalogueInterface $catalogue A MessageCatalogueInterface instance + */ + public function addFallbackCatalogue(MessageCatalogueInterface $catalogue); + + /** + * Gets the fallback catalogue. + * + * @return MessageCatalogueInterface|null A MessageCatalogueInterface instance or null when no fallback has been set + */ + public function getFallbackCatalogue(); + + /** + * Returns an array of resources loaded to build this collection. + * + * @return ResourceInterface[] An array of resources + */ + public function getResources(); + + /** + * Adds a resource for this collection. + * + * @param ResourceInterface $resource A resource instance + */ + public function addResource(ResourceInterface $resource); +} diff --git a/public/system/storage/vendor/symfony/translation/MessageSelector.php b/public/system/storage/vendor/symfony/translation/MessageSelector.php new file mode 100644 index 0000000..bdbb0f9 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/MessageSelector.php @@ -0,0 +1,86 @@ +<?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; + +/** + * MessageSelector. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Bernhard Schussek <bschussek@gmail.com> + */ +class MessageSelector +{ + /** + * Given a message with different plural translations separated by a + * pipe (|), this method returns the correct portion of the message based + * on the given number, locale and the pluralization rules in the message + * itself. + * + * The message supports two different types of pluralization rules: + * + * interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples + * indexed: There is one apple|There are %count% apples + * + * The indexed solution can also contain labels (e.g. one: There is one apple). + * This is purely for making the translations more clear - it does not + * affect the functionality. + * + * The two methods can also be mixed: + * {0} There are no apples|one: There is one apple|more: There are %count% apples + * + * @param string $message The message being translated + * @param int $number The number of items represented for the message + * @param string $locale The locale to use for choosing + * + * @return string + * + * @throws \InvalidArgumentException + */ + public function choose($message, $number, $locale) + { + $parts = explode('|', $message); + $explicitRules = array(); + $standardRules = array(); + foreach ($parts as $part) { + $part = trim($part); + + if (preg_match('/^(?P<interval>'.Interval::getIntervalRegexp().')\s*(?P<message>.*?)$/xs', $part, $matches)) { + $explicitRules[$matches['interval']] = $matches['message']; + } elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) { + $standardRules[] = $matches[1]; + } else { + $standardRules[] = $part; + } + } + + // try to match an explicit rule, then fallback to the standard ones + foreach ($explicitRules as $interval => $m) { + if (Interval::test($number, $interval)) { + return $m; + } + } + + $position = PluralizationRules::get($number, $locale); + + if (!isset($standardRules[$position])) { + // when there's exactly one rule given, and that rule is a standard + // rule, use this rule + if (1 === count($parts) && isset($standardRules[0])) { + return $standardRules[0]; + } + + throw new \InvalidArgumentException(sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $message, $locale, $number)); + } + + return $standardRules[$position]; + } +} diff --git a/public/system/storage/vendor/symfony/translation/MetadataAwareInterface.php b/public/system/storage/vendor/symfony/translation/MetadataAwareInterface.php new file mode 100644 index 0000000..e93c6fb --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/MetadataAwareInterface.php @@ -0,0 +1,54 @@ +<?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; + +/** + * MetadataAwareInterface. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface MetadataAwareInterface +{ + /** + * Gets metadata for the given domain and key. + * + * Passing an empty domain will return an array with all metadata indexed by + * domain and then by key. Passing an empty key will return an array with all + * metadata for the given domain. + * + * @param string $key The key + * @param string $domain The domain name + * + * @return mixed The value that was set or an array with the domains/keys or null + */ + public function getMetadata($key = '', $domain = 'messages'); + + /** + * Adds metadata to a message domain. + * + * @param string $key The key + * @param mixed $value The value + * @param string $domain The domain name + */ + public function setMetadata($key, $value, $domain = 'messages'); + + /** + * Deletes metadata for the given key and domain. + * + * Passing an empty domain will delete all metadata. Passing an empty key will + * delete all metadata for the given domain. + * + * @param string $key The key + * @param string $domain The domain name + */ + public function deleteMetadata($key = '', $domain = 'messages'); +} diff --git a/public/system/storage/vendor/symfony/translation/PluralizationRules.php b/public/system/storage/vendor/symfony/translation/PluralizationRules.php new file mode 100644 index 0000000..ef2be70 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/PluralizationRules.php @@ -0,0 +1,209 @@ +<?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; + +/** + * Returns the plural rules for a given locale. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class PluralizationRules +{ + private static $rules = array(); + + /** + * Returns the plural position to use for the given locale and number. + * + * @param int $number The number + * @param string $locale The locale + * + * @return int The plural position + */ + public static function get($number, $locale) + { + if ('pt_BR' === $locale) { + // temporary set a locale for brazilian + $locale = 'xbr'; + } + + if (strlen($locale) > 3) { + $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); + } + + if (isset(self::$rules[$locale])) { + $return = call_user_func(self::$rules[$locale], $number); + + if (!is_int($return) || $return < 0) { + return 0; + } + + return $return; + } + + /* + * The plural rules are derived from code of the Zend Framework (2010-09-25), + * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd). + * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + */ + switch ($locale) { + case 'az': + case 'bo': + case 'dz': + case 'id': + case 'ja': + case 'jv': + case 'ka': + case 'km': + case 'kn': + case 'ko': + case 'ms': + case 'th': + case 'tr': + case 'vi': + case 'zh': + return 0; + break; + + case 'af': + case 'bn': + case 'bg': + case 'ca': + case 'da': + case 'de': + case 'el': + case 'en': + case 'eo': + case 'es': + case 'et': + case 'eu': + case 'fa': + case 'fi': + case 'fo': + case 'fur': + case 'fy': + case 'gl': + case 'gu': + case 'ha': + case 'he': + case 'hu': + case 'is': + case 'it': + case 'ku': + case 'lb': + case 'ml': + case 'mn': + case 'mr': + case 'nah': + case 'nb': + case 'ne': + case 'nl': + case 'nn': + case 'no': + case 'om': + case 'or': + case 'pa': + case 'pap': + case 'ps': + case 'pt': + case 'so': + case 'sq': + case 'sv': + case 'sw': + case 'ta': + case 'te': + case 'tk': + case 'ur': + case 'zu': + return ($number == 1) ? 0 : 1; + + case 'am': + case 'bh': + case 'fil': + case 'fr': + case 'gun': + case 'hi': + case 'hy': + case 'ln': + case 'mg': + case 'nso': + case 'xbr': + case 'ti': + case 'wa': + return (($number == 0) || ($number == 1)) ? 0 : 1; + + case 'be': + case 'bs': + case 'hr': + case 'ru': + case 'sr': + case 'uk': + return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); + + case 'cs': + case 'sk': + return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2); + + case 'ga': + return ($number == 1) ? 0 : (($number == 2) ? 1 : 2); + + case 'lt': + return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); + + case 'sl': + return ($number % 100 == 1) ? 0 : (($number % 100 == 2) ? 1 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3)); + + case 'mk': + return ($number % 10 == 1) ? 0 : 1; + + case 'mt': + return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3)); + + case 'lv': + return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2); + + case 'pl': + return ($number == 1) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2); + + case 'cy': + return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3)); + + case 'ro': + return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2); + + case 'ar': + return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5)))); + + default: + return 0; + } + } + + /** + * Overrides the default plural rule for a given locale. + * + * @param callable $rule A PHP callable + * @param string $locale The locale + */ + public static function set(callable $rule, $locale) + { + if ('pt_BR' === $locale) { + // temporary set a locale for brazilian + $locale = 'xbr'; + } + + if (strlen($locale) > 3) { + $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); + } + + self::$rules[$locale] = $rule; + } +} diff --git a/public/system/storage/vendor/symfony/translation/README.md b/public/system/storage/vendor/symfony/translation/README.md new file mode 100644 index 0000000..46f3d1f --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/README.md @@ -0,0 +1,13 @@ +Translation Component +===================== + +The Translation component provides tools to internationalize your application. + +Resources +--------- + + * [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) diff --git a/public/system/storage/vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php b/public/system/storage/vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php new file mode 100644 index 0000000..30c21af --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php @@ -0,0 +1,73 @@ +<?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\Tests\Catalogue; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\MessageCatalogueInterface; + +abstract class AbstractOperationTest extends \PHPUnit_Framework_TestCase +{ + public function testGetEmptyDomains() + { + $this->assertEquals( + array(), + $this->createOperation( + new MessageCatalogue('en'), + new MessageCatalogue('en') + )->getDomains() + ); + } + + public function testGetMergedDomains() + { + $this->assertEquals( + array('a', 'b', 'c'), + $this->createOperation( + new MessageCatalogue('en', array('a' => array(), 'b' => array())), + new MessageCatalogue('en', array('b' => array(), 'c' => array())) + )->getDomains() + ); + } + + public function testGetMessagesFromUnknownDomain() + { + $this->setExpectedException('InvalidArgumentException'); + $this->createOperation( + new MessageCatalogue('en'), + new MessageCatalogue('en') + )->getMessages('domain'); + } + + public function testGetEmptyMessages() + { + $this->assertEquals( + array(), + $this->createOperation( + new MessageCatalogue('en', array('a' => array())), + new MessageCatalogue('en') + )->getMessages('a') + ); + } + + public function testGetEmptyResult() + { + $this->assertEquals( + new MessageCatalogue('en'), + $this->createOperation( + new MessageCatalogue('en'), + new MessageCatalogue('en') + )->getResult() + ); + } + + abstract protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target); +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php b/public/system/storage/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php new file mode 100644 index 0000000..8b51c15 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php @@ -0,0 +1,83 @@ +<?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\Tests\Catalogue; + +use Symfony\Component\Translation\Catalogue\MergeOperation; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\MessageCatalogueInterface; + +class MergeOperationTest extends AbstractOperationTest +{ + public function testGetMessagesFromSingleDomain() + { + $operation = $this->createOperation( + new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))), + new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c'))) + ); + + $this->assertEquals( + array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'), + $operation->getMessages('messages') + ); + + $this->assertEquals( + array('c' => 'new_c'), + $operation->getNewMessages('messages') + ); + + $this->assertEquals( + array(), + $operation->getObsoleteMessages('messages') + ); + } + + public function testGetResultFromSingleDomain() + { + $this->assertEquals( + new MessageCatalogue('en', array( + 'messages' => array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'), + )), + $this->createOperation( + new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))), + new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c'))) + )->getResult() + ); + } + + public function testGetResultWithMetadata() + { + $leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))); + $leftCatalogue->setMetadata('a', 'foo', 'messages'); + $leftCatalogue->setMetadata('b', 'bar', 'messages'); + $rightCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'new_b', 'c' => 'new_c'))); + $rightCatalogue->setMetadata('b', 'baz', 'messages'); + $rightCatalogue->setMetadata('c', 'qux', 'messages'); + + $mergedCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'))); + $mergedCatalogue->setMetadata('a', 'foo', 'messages'); + $mergedCatalogue->setMetadata('b', 'bar', 'messages'); + $mergedCatalogue->setMetadata('c', 'qux', 'messages'); + + $this->assertEquals( + $mergedCatalogue, + $this->createOperation( + $leftCatalogue, + $rightCatalogue + )->getResult() + ); + } + + protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target) + { + return new MergeOperation($source, $target); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Catalogue/TargetOperationTest.php b/public/system/storage/vendor/symfony/translation/Tests/Catalogue/TargetOperationTest.php new file mode 100644 index 0000000..271d17f --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Catalogue/TargetOperationTest.php @@ -0,0 +1,82 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Tests\Catalogue; + +use Symfony\Component\Translation\Catalogue\TargetOperation; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\MessageCatalogueInterface; + +class TargetOperationTest extends AbstractOperationTest +{ + public function testGetMessagesFromSingleDomain() + { + $operation = $this->createOperation( + new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))), + new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c'))) + ); + + $this->assertEquals( + array('a' => 'old_a', 'c' => 'new_c'), + $operation->getMessages('messages') + ); + + $this->assertEquals( + array('c' => 'new_c'), + $operation->getNewMessages('messages') + ); + + $this->assertEquals( + array('b' => 'old_b'), + $operation->getObsoleteMessages('messages') + ); + } + + public function testGetResultFromSingleDomain() + { + $this->assertEquals( + new MessageCatalogue('en', array( + 'messages' => array('a' => 'old_a', 'c' => 'new_c'), + )), + $this->createOperation( + new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))), + new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c'))) + )->getResult() + ); + } + + public function testGetResultWithMetadata() + { + $leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))); + $leftCatalogue->setMetadata('a', 'foo', 'messages'); + $leftCatalogue->setMetadata('b', 'bar', 'messages'); + $rightCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'new_b', 'c' => 'new_c'))); + $rightCatalogue->setMetadata('b', 'baz', 'messages'); + $rightCatalogue->setMetadata('c', 'qux', 'messages'); + + $diffCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'old_b', 'c' => 'new_c'))); + $diffCatalogue->setMetadata('b', 'bar', 'messages'); + $diffCatalogue->setMetadata('c', 'qux', 'messages'); + + $this->assertEquals( + $diffCatalogue, + $this->createOperation( + $leftCatalogue, + $rightCatalogue + )->getResult() + ); + } + + protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target) + { + return new TargetOperation($source, $target); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php b/public/system/storage/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php new file mode 100644 index 0000000..3d1e86e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php @@ -0,0 +1,148 @@ +<?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\Tests\DataCollector; + +use Symfony\Component\Translation\DataCollectorTranslator; +use Symfony\Component\Translation\DataCollector\TranslationDataCollector; + +class TranslationDataCollectorTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\HttpKernel\DataCollector\DataCollector')) { + $this->markTestSkipped('The "DataCollector" is not available'); + } + } + + public function testCollectEmptyMessages() + { + $translator = $this->getTranslator(); + $translator->expects($this->any())->method('getCollectedMessages')->will($this->returnValue(array())); + + $dataCollector = new TranslationDataCollector($translator); + $dataCollector->lateCollect(); + + $this->assertEquals(0, $dataCollector->getCountMissings()); + $this->assertEquals(0, $dataCollector->getCountFallbacks()); + $this->assertEquals(0, $dataCollector->getCountDefines()); + $this->assertEquals(array(), $dataCollector->getMessages()); + } + + public function testCollect() + { + $collectedMessages = array( + array( + 'id' => 'foo', + 'translation' => 'foo (en)', + 'locale' => 'en', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_DEFINED, + 'parameters' => array(), + 'transChoiceNumber' => null, + ), + array( + 'id' => 'bar', + 'translation' => 'bar (fr)', + 'locale' => 'fr', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK, + 'parameters' => array(), + 'transChoiceNumber' => null, + ), + array( + 'id' => 'choice', + 'translation' => 'choice', + 'locale' => 'en', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_MISSING, + 'parameters' => array('%count%' => 3), + 'transChoiceNumber' => 3, + ), + array( + 'id' => 'choice', + 'translation' => 'choice', + 'locale' => 'en', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_MISSING, + 'parameters' => array('%count%' => 3), + 'transChoiceNumber' => 3, + ), + array( + 'id' => 'choice', + 'translation' => 'choice', + 'locale' => 'en', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_MISSING, + 'parameters' => array('%count%' => 4, '%foo%' => 'bar'), + 'transChoiceNumber' => 4, + ), + ); + $expectedMessages = array( + array( + 'id' => 'foo', + 'translation' => 'foo (en)', + 'locale' => 'en', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_DEFINED, + 'count' => 1, + 'parameters' => array(), + 'transChoiceNumber' => null, + ), + array( + 'id' => 'bar', + 'translation' => 'bar (fr)', + 'locale' => 'fr', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK, + 'count' => 1, + 'parameters' => array(), + 'transChoiceNumber' => null, + ), + array( + 'id' => 'choice', + 'translation' => 'choice', + 'locale' => 'en', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_MISSING, + 'count' => 3, + 'parameters' => array( + array('%count%' => 3), + array('%count%' => 3), + array('%count%' => 4, '%foo%' => 'bar'), + ), + 'transChoiceNumber' => 3, + ), + ); + + $translator = $this->getTranslator(); + $translator->expects($this->any())->method('getCollectedMessages')->will($this->returnValue($collectedMessages)); + + $dataCollector = new TranslationDataCollector($translator); + $dataCollector->lateCollect(); + + $this->assertEquals(1, $dataCollector->getCountMissings()); + $this->assertEquals(1, $dataCollector->getCountFallbacks()); + $this->assertEquals(1, $dataCollector->getCountDefines()); + $this->assertEquals($expectedMessages, array_values($dataCollector->getMessages())); + } + + private function getTranslator() + { + $translator = $this + ->getMockBuilder('Symfony\Component\Translation\DataCollectorTranslator') + ->disableOriginalConstructor() + ->getMock() + ; + + return $translator; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php b/public/system/storage/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php new file mode 100644 index 0000000..5ef8171 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php @@ -0,0 +1,93 @@ +<?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\Tests; + +use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\DataCollectorTranslator; +use Symfony\Component\Translation\Loader\ArrayLoader; + +class DataCollectorTranslatorTest extends \PHPUnit_Framework_TestCase +{ + public function testCollectMessages() + { + $collector = $this->createCollector(); + $collector->setFallbackLocales(array('fr', 'ru')); + + $collector->trans('foo'); + $collector->trans('bar'); + $collector->transChoice('choice', 0); + $collector->trans('bar_ru'); + $collector->trans('bar_ru', array('foo' => 'bar')); + + $expectedMessages = array(); + $expectedMessages[] = array( + 'id' => 'foo', + 'translation' => 'foo (en)', + 'locale' => 'en', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_DEFINED, + 'parameters' => array(), + 'transChoiceNumber' => null, + ); + $expectedMessages[] = array( + 'id' => 'bar', + 'translation' => 'bar (fr)', + 'locale' => 'fr', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK, + 'parameters' => array(), + 'transChoiceNumber' => null, + ); + $expectedMessages[] = array( + 'id' => 'choice', + 'translation' => 'choice', + 'locale' => 'en', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_MISSING, + 'parameters' => array(), + 'transChoiceNumber' => 0, + ); + $expectedMessages[] = array( + 'id' => 'bar_ru', + 'translation' => 'bar (ru)', + 'locale' => 'ru', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK, + 'parameters' => array(), + 'transChoiceNumber' => null, + ); + $expectedMessages[] = array( + 'id' => 'bar_ru', + 'translation' => 'bar (ru)', + 'locale' => 'ru', + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK, + 'parameters' => array('foo' => 'bar'), + 'transChoiceNumber' => null, + ); + + $this->assertEquals($expectedMessages, $collector->getCollectedMessages()); + } + + private function createCollector() + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foo (en)'), 'en'); + $translator->addResource('array', array('bar' => 'bar (fr)'), 'fr'); + $translator->addResource('array', array('bar_ru' => 'bar (ru)'), 'ru'); + + $collector = new DataCollectorTranslator($translator); + + return $collector; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/CsvFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/CsvFileDumperTest.php new file mode 100644 index 0000000..9613192 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/CsvFileDumperTest.php @@ -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\Component\Translation\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\CsvFileDumper; + +class CsvFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar', 'bar' => 'foo +foo', 'foo;foo' => 'bar')); + + $dumper = new CsvFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/valid.csv', $dumper->formatCatalogue($catalogue, 'messages')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php new file mode 100644 index 0000000..ed58546 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php @@ -0,0 +1,83 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\FileDumper; + +class FileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testDump() + { + $tempDir = sys_get_temp_dir(); + + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new ConcreteFileDumper(); + $dumper->dump($catalogue, array('path' => $tempDir)); + + $this->assertTrue(file_exists($tempDir.'/messages.en.concrete')); + } + + public function testDumpBackupsFileIfExisting() + { + $tempDir = sys_get_temp_dir(); + $file = $tempDir.'/messages.en.concrete'; + $backupFile = $file.'~'; + + @touch($file); + + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new ConcreteFileDumper(); + $dumper->dump($catalogue, array('path' => $tempDir)); + + $this->assertTrue(file_exists($backupFile)); + + @unlink($file); + @unlink($backupFile); + } + + public function testDumpCreatesNestedDirectoriesAndFile() + { + $tempDir = sys_get_temp_dir(); + $translationsDir = $tempDir.'/test/translations'; + $file = $translationsDir.'/messages.en.concrete'; + + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new ConcreteFileDumper(); + $dumper->setRelativePathTemplate('test/translations/%domain%.%locale%.%extension%'); + $dumper->dump($catalogue, array('path' => $tempDir)); + + $this->assertTrue(file_exists($file)); + + @unlink($file); + @rmdir($translationsDir); + } +} + +class ConcreteFileDumper extends FileDumper +{ + public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) + { + return ''; + } + + protected function getExtension() + { + return 'concrete'; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/IcuResFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/IcuResFileDumperTest.php new file mode 100644 index 0000000..618783c --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/IcuResFileDumperTest.php @@ -0,0 +1,28 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\IcuResFileDumper; + +class IcuResFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new IcuResFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resourcebundle/res/en.res', $dumper->formatCatalogue($catalogue, 'messages')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/IniFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/IniFileDumperTest.php new file mode 100644 index 0000000..d8ae4b5 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/IniFileDumperTest.php @@ -0,0 +1,28 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\IniFileDumper; + +class IniFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new IniFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.ini', $dumper->formatCatalogue($catalogue, 'messages')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php new file mode 100644 index 0000000..27e9f4d --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php @@ -0,0 +1,38 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\JsonFileDumper; + +class JsonFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new JsonFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.json', $dumper->formatCatalogue($catalogue, 'messages')); + } + + public function testDumpWithCustomEncoding() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => '"bar"')); + + $dumper = new JsonFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.dump.json', $dumper->formatCatalogue($catalogue, 'messages', array('json_encoding' => JSON_HEX_QUOT))); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/MoFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/MoFileDumperTest.php new file mode 100644 index 0000000..c47656c --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/MoFileDumperTest.php @@ -0,0 +1,28 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\MoFileDumper; + +class MoFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new MoFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.mo', $dumper->formatCatalogue($catalogue, 'messages')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/PhpFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/PhpFileDumperTest.php new file mode 100644 index 0000000..d24cd2b --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/PhpFileDumperTest.php @@ -0,0 +1,28 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\PhpFileDumper; + +class PhpFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new PhpFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.php', $dumper->formatCatalogue($catalogue, 'messages')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php new file mode 100644 index 0000000..445961a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php @@ -0,0 +1,28 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\PoFileDumper; + +class PoFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new PoFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.po', $dumper->formatCatalogue($catalogue, 'messages')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php new file mode 100644 index 0000000..690a4d0 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php @@ -0,0 +1,28 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\QtFileDumper; + +class QtFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add(array('foo' => 'bar'), 'resources'); + + $dumper = new QtFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.ts', $dumper->formatCatalogue($catalogue, 'resources')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php new file mode 100644 index 0000000..072b605 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php @@ -0,0 +1,89 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\XliffFileDumper; + +class XliffFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testFormatCatalogue() + { + $catalogue = new MessageCatalogue('en_US'); + $catalogue->add(array( + 'foo' => 'bar', + 'key' => '', + 'key.with.cdata' => '<source> & <target>', + )); + $catalogue->setMetadata('foo', array('notes' => array(array('priority' => 1, 'from' => 'bar', 'content' => 'baz')))); + $catalogue->setMetadata('key', array('notes' => array(array('content' => 'baz'), array('content' => 'qux')))); + + $dumper = new XliffFileDumper(); + + $this->assertStringEqualsFile( + __DIR__.'/../fixtures/resources-clean.xlf', + $dumper->formatCatalogue($catalogue, 'messages', array('default_locale' => 'fr_FR')) + ); + } + + public function testFormatCatalogueXliff2() + { + $catalogue = new MessageCatalogue('en_US'); + $catalogue->add(array( + 'foo' => 'bar', + 'key' => '', + 'key.with.cdata' => '<source> & <target>', + )); + $catalogue->setMetadata('key', array('target-attributes' => array('order' => 1))); + + $dumper = new XliffFileDumper(); + + $this->assertStringEqualsFile( + __DIR__.'/../fixtures/resources-2.0-clean.xlf', + $dumper->formatCatalogue($catalogue, 'messages', array('default_locale' => 'fr_FR', 'xliff_version' => '2.0')) + ); + } + + public function testFormatCatalogueWithCustomToolInfo() + { + $options = array( + 'default_locale' => 'en_US', + 'tool_info' => array('tool-id' => 'foo', 'tool-name' => 'foo', 'tool-version' => '0.0', 'tool-company' => 'Foo'), + ); + + $catalogue = new MessageCatalogue('en_US'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new XliffFileDumper(); + + $this->assertStringEqualsFile( + __DIR__.'/../fixtures/resources-tool-info.xlf', + $dumper->formatCatalogue($catalogue, 'messages', $options) + ); + } + + public function testFormatCatalogueWithTargetAttributesMetadata() + { + $catalogue = new MessageCatalogue('en_US'); + $catalogue->add(array( + 'foo' => 'bar', + )); + $catalogue->setMetadata('foo', array('target-attributes' => array('state' => 'needs-translation'))); + + $dumper = new XliffFileDumper(); + + $this->assertStringEqualsFile( + __DIR__.'/../fixtures/resources-target-attributes.xlf', + $dumper->formatCatalogue($catalogue, 'messages', array('default_locale' => 'fr_FR')) + ); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Dumper/YamlFileDumperTest.php b/public/system/storage/vendor/symfony/translation/Tests/Dumper/YamlFileDumperTest.php new file mode 100644 index 0000000..d6bb477 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Dumper/YamlFileDumperTest.php @@ -0,0 +1,46 @@ +<?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\Tests\Dumper; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\YamlFileDumper; + +class YamlFileDumperTest extends \PHPUnit_Framework_TestCase +{ + public function testTreeFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add( + array( + 'foo.bar1' => 'value1', + 'foo.bar2' => 'value2', + )); + + $dumper = new YamlFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/messages.yml', $dumper->formatCatalogue($catalogue, 'messages', array('as_tree' => true, 'inline' => 999))); + } + + public function testLinearFormatCatalogue() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->add( + array( + 'foo.bar1' => 'value1', + 'foo.bar2' => 'value2', + )); + + $dumper = new YamlFileDumper(); + + $this->assertStringEqualsFile(__DIR__.'/../fixtures/messages_linear.yml', $dumper->formatCatalogue($catalogue, 'messages')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/IdentityTranslatorTest.php b/public/system/storage/vendor/symfony/translation/Tests/IdentityTranslatorTest.php new file mode 100644 index 0000000..352dd31 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/IdentityTranslatorTest.php @@ -0,0 +1,95 @@ +<?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\Tests; + +use Symfony\Component\Intl\Util\IntlTestHelper; +use Symfony\Component\Translation\IdentityTranslator; + +class IdentityTranslatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getTransTests + */ + public function testTrans($expected, $id, $parameters) + { + $translator = new IdentityTranslator(); + + $this->assertEquals($expected, $translator->trans($id, $parameters)); + } + + /** + * @dataProvider getTransChoiceTests + */ + public function testTransChoiceWithExplicitLocale($expected, $id, $number, $parameters) + { + $translator = new IdentityTranslator(); + $translator->setLocale('en'); + + $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters)); + } + + /** + * @dataProvider getTransChoiceTests + */ + public function testTransChoiceWithDefaultLocale($expected, $id, $number, $parameters) + { + \Locale::setDefault('en'); + + $translator = new IdentityTranslator(); + + $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters)); + } + + public function testGetSetLocale() + { + $translator = new IdentityTranslator(); + $translator->setLocale('en'); + + $this->assertEquals('en', $translator->getLocale()); + } + + public function testGetLocaleReturnsDefaultLocaleIfNotSet() + { + // in order to test with "pt_BR" + IntlTestHelper::requireFullIntl($this); + + $translator = new IdentityTranslator(); + + \Locale::setDefault('en'); + $this->assertEquals('en', $translator->getLocale()); + + \Locale::setDefault('pt_BR'); + $this->assertEquals('pt_BR', $translator->getLocale()); + } + + public function getTransTests() + { + return array( + array('Symfony is great!', 'Symfony is great!', array()), + array('Symfony is awesome!', 'Symfony is %what%!', array('%what%' => 'awesome')), + ); + } + + public function getTransChoiceTests() + { + return array( + array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0, array('%count%' => 0)), + array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1, array('%count%' => 1)), + array('There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10, array('%count%' => 10)), + array('There are 0 apples', 'There is 1 apple|There are %count% apples', 0, array('%count%' => 0)), + array('There is 1 apple', 'There is 1 apple|There are %count% apples', 1, array('%count%' => 1)), + array('There are 10 apples', 'There is 1 apple|There are %count% apples', 10, array('%count%' => 10)), + // custom validation messages may be coded with a fixed value + array('There are 2 apples', 'There are 2 apples', 2, array('%count%' => 2)), + ); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/IntervalTest.php b/public/system/storage/vendor/symfony/translation/Tests/IntervalTest.php new file mode 100644 index 0000000..075c98b --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/IntervalTest.php @@ -0,0 +1,48 @@ +<?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\Tests; + +use Symfony\Component\Translation\Interval; + +class IntervalTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getTests + */ + public function testTest($expected, $number, $interval) + { + $this->assertEquals($expected, Interval::test($number, $interval)); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testTestException() + { + Interval::test(1, 'foobar'); + } + + public function getTests() + { + return array( + array(true, 3, '{1,2, 3 ,4}'), + array(false, 10, '{1,2, 3 ,4}'), + array(false, 3, '[1,2]'), + array(true, 1, '[1,2]'), + array(true, 2, '[1,2]'), + array(false, 1, ']1,2['), + array(false, 2, ']1,2['), + array(true, log(0), '[-Inf,2['), + array(true, -log(0), '[-2,+Inf]'), + ); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/CsvFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/CsvFileLoaderTest.php new file mode 100644 index 0000000..463d3b5 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/CsvFileLoaderTest.php @@ -0,0 +1,60 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\CsvFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class CsvFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new CsvFileLoader(); + $resource = __DIR__.'/../fixtures/resources.csv'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testLoadDoesNothingIfEmpty() + { + $loader = new CsvFileLoader(); + $resource = __DIR__.'/../fixtures/empty.csv'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array(), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new CsvFileLoader(); + $resource = __DIR__.'/../fixtures/not-exists.csv'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadNonLocalResource() + { + $loader = new CsvFileLoader(); + $resource = 'http://example.com/resources.csv'; + $loader->load($resource, 'en', 'domain1'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/IcuDatFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/IcuDatFileLoaderTest.php new file mode 100644 index 0000000..888fb61 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/IcuDatFileLoaderTest.php @@ -0,0 +1,64 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\IcuDatFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +/** + * @requires extension intl + */ +class IcuDatFileLoaderTest extends LocalizedTestCase +{ + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadInvalidResource() + { + $loader = new IcuDatFileLoader(); + $loader->load(__DIR__.'/../fixtures/resourcebundle/corrupted/resources', 'es', 'domain2'); + } + + public function testDatEnglishLoad() + { + // bundled resource is build using pkgdata command which at least in ICU 4.2 comes in extremely! buggy form + // you must specify an temporary build directory which is not the same as current directory and + // MUST reside on the same partition. pkgdata -p resources -T /srv -d.packagelist.txt + $loader = new IcuDatFileLoader(); + $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('symfony' => 'Symfony 2 is great'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources()); + } + + public function testDatFrenchLoad() + { + $loader = new IcuDatFileLoader(); + $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources'; + $catalogue = $loader->load($resource, 'fr', 'domain1'); + + $this->assertEquals(array('symfony' => 'Symfony 2 est génial'), $catalogue->all('domain1')); + $this->assertEquals('fr', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new IcuDatFileLoader(); + $loader->load(__DIR__.'/../fixtures/non-existing.txt', 'en', 'domain1'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/IcuResFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/IcuResFileLoaderTest.php new file mode 100644 index 0000000..8d9ed19 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/IcuResFileLoaderTest.php @@ -0,0 +1,51 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\IcuResFileLoader; +use Symfony\Component\Config\Resource\DirectoryResource; + +/** + * @requires extension intl + */ +class IcuResFileLoaderTest extends LocalizedTestCase +{ + public function testLoad() + { + // resource is build using genrb command + $loader = new IcuResFileLoader(); + $resource = __DIR__.'/../fixtures/resourcebundle/res'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new DirectoryResource($resource)), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new IcuResFileLoader(); + $loader->load(__DIR__.'/../fixtures/non-existing.txt', 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadInvalidResource() + { + $loader = new IcuResFileLoader(); + $loader->load(__DIR__.'/../fixtures/resourcebundle/corrupted', 'en', 'domain1'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/IniFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/IniFileLoaderTest.php new file mode 100644 index 0000000..1a5de0e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/IniFileLoaderTest.php @@ -0,0 +1,50 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Tests\Loader; + +use Symfony\Component\Translation\Loader\IniFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class IniFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new IniFileLoader(); + $resource = __DIR__.'/../fixtures/resources.ini'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testLoadDoesNothingIfEmpty() + { + $loader = new IniFileLoader(); + $resource = __DIR__.'/../fixtures/empty.ini'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array(), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new IniFileLoader(); + $resource = __DIR__.'/../fixtures/non-existing.ini'; + $loader->load($resource, 'en', 'domain1'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php new file mode 100644 index 0000000..cd5d633 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php @@ -0,0 +1,61 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\JsonFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class JsonFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new JsonFileLoader(); + $resource = __DIR__.'/../fixtures/resources.json'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testLoadDoesNothingIfEmpty() + { + $loader = new JsonFileLoader(); + $resource = __DIR__.'/../fixtures/empty.json'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array(), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new JsonFileLoader(); + $resource = __DIR__.'/../fixtures/non-existing.json'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + * @expectedExceptionMessage Error parsing JSON - Syntax error, malformed JSON + */ + public function testParseException() + { + $loader = new JsonFileLoader(); + $resource = __DIR__.'/../fixtures/malformed.json'; + $loader->load($resource, 'en', 'domain1'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php new file mode 100644 index 0000000..0d1fff7 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php @@ -0,0 +1,22 @@ +<?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\Tests\Loader; + +abstract class LocalizedTestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!extension_loaded('intl')) { + $this->markTestSkipped('Extension intl is required.'); + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/MoFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/MoFileLoaderTest.php new file mode 100644 index 0000000..34078d0 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/MoFileLoaderTest.php @@ -0,0 +1,71 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\MoFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class MoFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new MoFileLoader(); + $resource = __DIR__.'/../fixtures/resources.mo'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testLoadPlurals() + { + $loader = new MoFileLoader(); + $resource = __DIR__.'/../fixtures/plurals.mo'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar', 'foos' => '{0} bar|{1} bars'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new MoFileLoader(); + $resource = __DIR__.'/../fixtures/non-existing.mo'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadInvalidResource() + { + $loader = new MoFileLoader(); + $resource = __DIR__.'/../fixtures/empty.mo'; + $loader->load($resource, 'en', 'domain1'); + } + + public function testLoadEmptyTranslation() + { + $loader = new MoFileLoader(); + $resource = __DIR__.'/../fixtures/empty-translation.mo'; + $catalogue = $loader->load($resource, 'en', 'message'); + + $this->assertEquals(array(), $catalogue->all('message')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/PhpFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/PhpFileLoaderTest.php new file mode 100644 index 0000000..0816b0f --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/PhpFileLoaderTest.php @@ -0,0 +1,49 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\PhpFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new PhpFileLoader(); + $resource = __DIR__.'/../fixtures/resources.php'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new PhpFileLoader(); + $resource = __DIR__.'/../fixtures/non-existing.php'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadThrowsAnExceptionIfFileNotLocal() + { + $loader = new PhpFileLoader(); + $resource = 'http://example.com/resources.php'; + $loader->load($resource, 'en', 'domain1'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/PoFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/PoFileLoaderTest.php new file mode 100644 index 0000000..5d340c7 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/PoFileLoaderTest.php @@ -0,0 +1,108 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\PoFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class PoFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/resources.po'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testLoadPlurals() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/plurals.po'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar', 'foos' => 'bar|bars'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testLoadDoesNothingIfEmpty() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/empty.po'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array(), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/non-existing.po'; + $loader->load($resource, 'en', 'domain1'); + } + + public function testLoadEmptyTranslation() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/empty-translation.po'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => ''), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testEscapedId() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/escaped-id.po'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $messages = $catalogue->all('domain1'); + $this->assertArrayHasKey('escaped "foo"', $messages); + $this->assertEquals('escaped "bar"', $messages['escaped "foo"']); + } + + public function testEscapedIdPlurals() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/escaped-id-plurals.po'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $messages = $catalogue->all('domain1'); + $this->assertArrayHasKey('escaped "foo"', $messages); + $this->assertArrayHasKey('escaped "foos"', $messages); + $this->assertEquals('escaped "bar"', $messages['escaped "foo"']); + $this->assertEquals('escaped "bar"|escaped "bars"', $messages['escaped "foos"']); + } + + public function testSkipFuzzyTranslations() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/fuzzy-translations.po'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $messages = $catalogue->all('domain1'); + $this->assertArrayHasKey('foo1', $messages); + $this->assertArrayNotHasKey('foo2', $messages); + $this->assertArrayHasKey('foo3', $messages); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php new file mode 100644 index 0000000..3aca86a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php @@ -0,0 +1,67 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\QtFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class QtFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new QtFileLoader(); + $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()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new QtFileLoader(); + $resource = __DIR__.'/../fixtures/non-existing.ts'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadNonLocalResource() + { + $loader = new QtFileLoader(); + $resource = 'http://domain1.com/resources.ts'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadInvalidResource() + { + $loader = new QtFileLoader(); + $resource = __DIR__.'/../fixtures/invalid-xml-resources.xlf'; + $loader->load($resource, 'en', 'domain1'); + } + + public function testLoadEmptyResource() + { + $loader = new QtFileLoader(); + $resource = __DIR__.'/../fixtures/empty.xlf'; + $this->setExpectedException('Symfony\Component\Translation\Exception\InvalidResourceException', sprintf('Unable to load "%s".', $resource)); + $loader->load($resource, 'en', 'domain1'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php new file mode 100644 index 0000000..2f466d8 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php @@ -0,0 +1,183 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\XliffFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new XliffFileLoader(); + $resource = __DIR__.'/../fixtures/resources.xlf'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + $this->assertSame(array(), libxml_get_errors()); + $this->assertContainsOnly('string', $catalogue->all('domain1')); + } + + public function testLoadWithInternalErrorsEnabled() + { + $internalErrors = libxml_use_internal_errors(true); + + $this->assertSame(array(), libxml_get_errors()); + + $loader = new XliffFileLoader(); + $resource = __DIR__.'/../fixtures/resources.xlf'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + $this->assertSame(array(), libxml_get_errors()); + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + } + + public function testLoadWithExternalEntitiesDisabled() + { + $disableEntities = libxml_disable_entity_loader(true); + + $loader = new XliffFileLoader(); + $resource = __DIR__.'/../fixtures/resources.xlf'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + libxml_disable_entity_loader($disableEntities); + + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testLoadWithResname() + { + $loader = new XliffFileLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/resname.xlf', 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar', 'bar' => 'baz', 'baz' => 'foo'), $catalogue->all('domain1')); + } + + public function testIncompleteResource() + { + $loader = new XliffFileLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/resources.xlf', 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar', 'extra' => 'extra', 'key' => '', 'test' => 'with'), $catalogue->all('domain1')); + } + + public function testEncoding() + { + $loader = new XliffFileLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/encoding.xlf', 'en', 'domain1'); + + $this->assertEquals(utf8_decode('föö'), $catalogue->get('bar', 'domain1')); + $this->assertEquals(utf8_decode('bär'), $catalogue->get('foo', 'domain1')); + $this->assertEquals(array('notes' => array(array('content' => utf8_decode('bäz')))), $catalogue->getMetadata('foo', 'domain1')); + } + + public function testTargetAttributesAreStoredCorrectly() + { + $loader = new XliffFileLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/with-attributes.xlf', 'en', 'domain1'); + + $metadata = $catalogue->getMetadata('foo', 'domain1'); + $this->assertEquals('translated', $metadata['target-attributes']['state']); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadInvalidResource() + { + $loader = new XliffFileLoader(); + $loader->load(__DIR__.'/../fixtures/resources.php', 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadResourceDoesNotValidate() + { + $loader = new XliffFileLoader(); + $loader->load(__DIR__.'/../fixtures/non-valid.xlf', 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new XliffFileLoader(); + $resource = __DIR__.'/../fixtures/non-existing.xlf'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadThrowsAnExceptionIfFileNotLocal() + { + $loader = new XliffFileLoader(); + $resource = 'http://example.com/resources.xlf'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + * @expectedExceptionMessage Document types are not allowed. + */ + public function testDocTypeIsNotAllowed() + { + $loader = new XliffFileLoader(); + $loader->load(__DIR__.'/../fixtures/withdoctype.xlf', 'en', 'domain1'); + } + + public function testParseEmptyFile() + { + $loader = new XliffFileLoader(); + $resource = __DIR__.'/../fixtures/empty.xlf'; + $this->setExpectedException('Symfony\Component\Translation\Exception\InvalidResourceException', sprintf('Unable to load "%s":', $resource)); + $loader->load($resource, 'en', 'domain1'); + } + + public function testLoadNotes() + { + $loader = new XliffFileLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/withnote.xlf', 'en', 'domain1'); + + $this->assertEquals(array('notes' => array(array('priority' => 1, 'content' => 'foo'))), $catalogue->getMetadata('foo', 'domain1')); + // message without target + $this->assertEquals(array('notes' => array(array('content' => 'bar', 'from' => 'foo'))), $catalogue->getMetadata('extra', 'domain1')); + // message with empty target + $this->assertEquals(array('notes' => array(array('content' => 'baz'), array('priority' => 2, 'from' => 'bar', 'content' => 'qux'))), $catalogue->getMetadata('key', 'domain1')); + } + + public function testLoadVersion2() + { + $loader = new XliffFileLoader(); + $resource = __DIR__.'/../fixtures/resources-2.0.xlf'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + $this->assertSame(array(), libxml_get_errors()); + + $domains = $catalogue->all(); + $this->assertCount(3, $domains['domain1']); + $this->assertContainsOnly('string', $catalogue->all('domain1')); + + // target attributes + $this->assertEquals(array('target-attributes' => array('order' => 1)), $catalogue->getMetadata('bar', 'domain1')); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Loader/YamlFileLoaderTest.php b/public/system/storage/vendor/symfony/translation/Tests/Loader/YamlFileLoaderTest.php new file mode 100644 index 0000000..00f7163 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Loader/YamlFileLoaderTest.php @@ -0,0 +1,70 @@ +<?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\Tests\Loader; + +use Symfony\Component\Translation\Loader\YamlFileLoader; +use Symfony\Component\Config\Resource\FileResource; + +class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoad() + { + $loader = new YamlFileLoader(); + $resource = __DIR__.'/../fixtures/resources.yml'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + public function testLoadDoesNothingIfEmpty() + { + $loader = new YamlFileLoader(); + $resource = __DIR__.'/../fixtures/empty.yml'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array(), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources()); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testLoadNonExistingResource() + { + $loader = new YamlFileLoader(); + $resource = __DIR__.'/../fixtures/non-existing.yml'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadThrowsAnExceptionIfFileNotLocal() + { + $loader = new YamlFileLoader(); + $resource = 'http://example.com/resources.yml'; + $loader->load($resource, 'en', 'domain1'); + } + + /** + * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException + */ + public function testLoadThrowsAnExceptionIfNotAnArray() + { + $loader = new YamlFileLoader(); + $resource = __DIR__.'/../fixtures/non-valid.yml'; + $loader->load($resource, 'en', 'domain1'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/LoggingTranslatorTest.php b/public/system/storage/vendor/symfony/translation/Tests/LoggingTranslatorTest.php new file mode 100644 index 0000000..9f3e849 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/LoggingTranslatorTest.php @@ -0,0 +1,49 @@ +<?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\Tests; + +use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\LoggingTranslator; +use Symfony\Component\Translation\Loader\ArrayLoader; + +class LoggingTranslatorTest extends \PHPUnit_Framework_TestCase +{ + public function testTransWithNoTranslationIsLogged() + { + $logger = $this->getMock('Psr\Log\LoggerInterface'); + $logger->expects($this->exactly(2)) + ->method('warning') + ->with('Translation not found.') + ; + + $translator = new Translator('ar'); + $loggableTranslator = new LoggingTranslator($translator, $logger); + $loggableTranslator->transChoice('some_message2', 10, array('%count%' => 10)); + $loggableTranslator->trans('bar'); + } + + public function testTransChoiceFallbackIsLogged() + { + $logger = $this->getMock('Psr\Log\LoggerInterface'); + $logger->expects($this->once()) + ->method('debug') + ->with('Translation use fallback catalogue.') + ; + + $translator = new Translator('ar'); + $translator->setFallbackLocales(array('en')); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en'); + $loggableTranslator = new LoggingTranslator($translator, $logger); + $loggableTranslator->transChoice('some_message2', 10, array('%count%' => 10)); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/MessageCatalogueTest.php b/public/system/storage/vendor/symfony/translation/Tests/MessageCatalogueTest.php new file mode 100644 index 0000000..6f55b8c --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/MessageCatalogueTest.php @@ -0,0 +1,214 @@ +<?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\Tests; + +use Symfony\Component\Translation\MessageCatalogue; + +class MessageCatalogueTest extends \PHPUnit_Framework_TestCase +{ + public function testGetLocale() + { + $catalogue = new MessageCatalogue('en'); + + $this->assertEquals('en', $catalogue->getLocale()); + } + + public function testGetDomains() + { + $catalogue = new MessageCatalogue('en', array('domain1' => array(), 'domain2' => array())); + + $this->assertEquals(array('domain1', 'domain2'), $catalogue->getDomains()); + } + + public function testAll() + { + $catalogue = new MessageCatalogue('en', $messages = array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar'))); + + $this->assertEquals(array('foo' => 'foo'), $catalogue->all('domain1')); + $this->assertEquals(array(), $catalogue->all('domain88')); + $this->assertEquals($messages, $catalogue->all()); + } + + public function testHas() + { + $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar'))); + + $this->assertTrue($catalogue->has('foo', 'domain1')); + $this->assertFalse($catalogue->has('bar', 'domain1')); + $this->assertFalse($catalogue->has('foo', 'domain88')); + } + + public function testGetSet() + { + $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar'))); + $catalogue->set('foo1', 'foo1', 'domain1'); + + $this->assertEquals('foo', $catalogue->get('foo', 'domain1')); + $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1')); + } + + public function testAdd() + { + $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar'))); + $catalogue->add(array('foo1' => 'foo1'), 'domain1'); + + $this->assertEquals('foo', $catalogue->get('foo', 'domain1')); + $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1')); + + $catalogue->add(array('foo' => 'bar'), 'domain1'); + $this->assertEquals('bar', $catalogue->get('foo', 'domain1')); + $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1')); + + $catalogue->add(array('foo' => 'bar'), 'domain88'); + $this->assertEquals('bar', $catalogue->get('foo', 'domain88')); + } + + public function testReplace() + { + $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar'))); + $catalogue->replace($messages = array('foo1' => 'foo1'), 'domain1'); + + $this->assertEquals($messages, $catalogue->all('domain1')); + } + + public function testAddCatalogue() + { + $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface'); + $r->expects($this->any())->method('__toString')->will($this->returnValue('r')); + + $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface'); + $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1')); + + $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar'))); + $catalogue->addResource($r); + + $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo1' => 'foo1'))); + $catalogue1->addResource($r1); + + $catalogue->addCatalogue($catalogue1); + + $this->assertEquals('foo', $catalogue->get('foo', 'domain1')); + $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1')); + + $this->assertEquals(array($r, $r1), $catalogue->getResources()); + } + + public function testAddFallbackCatalogue() + { + $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface'); + $r->expects($this->any())->method('__toString')->will($this->returnValue('r')); + + $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface'); + $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1')); + + $catalogue = new MessageCatalogue('en_US', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar'))); + $catalogue->addResource($r); + + $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo' => 'bar', 'foo1' => 'foo1'))); + $catalogue1->addResource($r1); + + $catalogue->addFallbackCatalogue($catalogue1); + + $this->assertEquals('foo', $catalogue->get('foo', 'domain1')); + $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1')); + + $this->assertEquals(array($r, $r1), $catalogue->getResources()); + } + + /** + * @expectedException \LogicException + */ + public function testAddFallbackCatalogueWithParentCircularReference() + { + $main = new MessageCatalogue('en_US'); + $fallback = new MessageCatalogue('fr_FR'); + + $fallback->addFallbackCatalogue($main); + $main->addFallbackCatalogue($fallback); + } + + /** + * @expectedException \LogicException + */ + public function testAddFallbackCatalogueWithFallbackCircularReference() + { + $fr = new MessageCatalogue('fr'); + $en = new MessageCatalogue('en'); + $es = new MessageCatalogue('es'); + + $fr->addFallbackCatalogue($en); + $es->addFallbackCatalogue($en); + $en->addFallbackCatalogue($fr); + } + + /** + * @expectedException \LogicException + */ + public function testAddCatalogueWhenLocaleIsNotTheSameAsTheCurrentOne() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->addCatalogue(new MessageCatalogue('fr', array())); + } + + public function testGetAddResource() + { + $catalogue = new MessageCatalogue('en'); + $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface'); + $r->expects($this->any())->method('__toString')->will($this->returnValue('r')); + $catalogue->addResource($r); + $catalogue->addResource($r); + $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface'); + $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1')); + $catalogue->addResource($r1); + + $this->assertEquals(array($r, $r1), $catalogue->getResources()); + } + + public function testMetadataDelete() + { + $catalogue = new MessageCatalogue('en'); + $this->assertEquals(array(), $catalogue->getMetadata('', ''), 'Metadata is empty'); + $catalogue->deleteMetadata('key', 'messages'); + $catalogue->deleteMetadata('', 'messages'); + $catalogue->deleteMetadata(); + } + + public function testMetadataSetGetDelete() + { + $catalogue = new MessageCatalogue('en'); + $catalogue->setMetadata('key', 'value'); + $this->assertEquals('value', $catalogue->getMetadata('key', 'messages'), "Metadata 'key' = 'value'"); + + $catalogue->setMetadata('key2', array()); + $this->assertEquals(array(), $catalogue->getMetadata('key2', 'messages'), 'Metadata key2 is array'); + + $catalogue->deleteMetadata('key2', 'messages'); + $this->assertNull($catalogue->getMetadata('key2', 'messages'), 'Metadata key2 should is deleted.'); + + $catalogue->deleteMetadata('key2', 'domain'); + $this->assertNull($catalogue->getMetadata('key2', 'domain'), 'Metadata key2 should is deleted.'); + } + + public function testMetadataMerge() + { + $cat1 = new MessageCatalogue('en'); + $cat1->setMetadata('a', 'b'); + $this->assertEquals(array('messages' => array('a' => 'b')), $cat1->getMetadata('', ''), 'Cat1 contains messages metadata.'); + + $cat2 = new MessageCatalogue('en'); + $cat2->setMetadata('b', 'c', 'domain'); + $this->assertEquals(array('domain' => array('b' => 'c')), $cat2->getMetadata('', ''), 'Cat2 contains domain metadata.'); + + $cat1->addCatalogue($cat2); + $this->assertEquals(array('messages' => array('a' => 'b'), 'domain' => array('b' => 'c')), $cat1->getMetadata('', ''), 'Cat1 contains merged metadata.'); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/MessageSelectorTest.php b/public/system/storage/vendor/symfony/translation/Tests/MessageSelectorTest.php new file mode 100644 index 0000000..f89bed1 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/MessageSelectorTest.php @@ -0,0 +1,130 @@ +<?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\Tests; + +use Symfony\Component\Translation\MessageSelector; + +class MessageSelectorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getChooseTests + */ + public function testChoose($expected, $id, $number) + { + $selector = new MessageSelector(); + + $this->assertEquals($expected, $selector->choose($id, $number, 'en')); + } + + public function testReturnMessageIfExactlyOneStandardRuleIsGiven() + { + $selector = new MessageSelector(); + + $this->assertEquals('There are two apples', $selector->choose('There are two apples', 2, 'en')); + } + + /** + * @dataProvider getNonMatchingMessages + * @expectedException \InvalidArgumentException + */ + public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number) + { + $selector = new MessageSelector(); + + $selector->choose($id, $number, 'en'); + } + + public function getNonMatchingMessages() + { + return array( + array('{0} There are no apples|{1} There is one apple', 2), + array('{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('{1} There is one apple|]2,Inf] There are %count% apples', 2), + array('{0} There are no apples|There is one apple', 2), + ); + } + + public function getChooseTests() + { + return array( + array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0), + + array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1), + + array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10), + array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10), + array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10), + + array('There are %count% apples', 'There is one apple|There are %count% apples', 0), + array('There is one apple', 'There is one apple|There are %count% apples', 1), + array('There are %count% apples', 'There is one apple|There are %count% apples', 10), + + array('There are %count% apples', 'one: There is one apple|more: There are %count% apples', 0), + array('There is one apple', 'one: There is one apple|more: There are %count% apples', 1), + array('There are %count% apples', 'one: There is one apple|more: There are %count% apples', 10), + + array('There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0), + array('There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1), + array('There are %count% apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10), + + array('', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1), + + // Indexed only tests which are Gettext PoFile* compatible strings. + array('There are %count% apples', 'There is one apple|There are %count% apples', 0), + array('There is one apple', 'There is one apple|There are %count% apples', 1), + array('There are %count% apples', 'There is one apple|There are %count% apples', 2), + + // Tests for float numbers + array('There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7), + array('There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1), + array('There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7), + array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0), + array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0), + array('There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0), + + // Test texts with new-lines + // with double-quotes and \n in id & double-quotes and actual newlines in text + array("This is a text with a\n new-line in it. Selector = 0.", '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 0), + // with double-quotes and \n in id and single-quotes and actual newlines in text + array("This is a text with a\n new-line in it. Selector = 1.", '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 1), + array("This is a text with a\n new-line in it. Selector > 1.", '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 5), + // with double-quotes and id split accros lines + array('This is a text with a + new-line in it. Selector = 1.', '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 1), + // with single-quotes and id split accros lines + array('This is a text with a + new-line in it. Selector > 1.', '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 5), + // with single-quotes and \n in text + array('This is a text with a\nnew-line in it. Selector = 0.', '{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.', 0), + // with double-quotes and id split accros lines + array("This is a text with a\nnew-line in it. Selector = 1.", "{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.", 1), + ); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/PluralizationRulesTest.php b/public/system/storage/vendor/symfony/translation/Tests/PluralizationRulesTest.php new file mode 100644 index 0000000..78bbc87 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/PluralizationRulesTest.php @@ -0,0 +1,123 @@ +<?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\Tests; + +use Symfony\Component\Translation\PluralizationRules; + +/** + * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms + * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms. + * + * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms. + * The mozilla code is also interesting to check for. + * + * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199 + * + * The goal to cover all languages is to far fetched so this test case is smaller. + * + * @author Clemens Tolboom clemens@build2be.nl + */ +class PluralizationRulesTest extends \PHPUnit_Framework_TestCase +{ + /** + * We test failed langcode here. + * + * TODO: The languages mentioned in the data provide need to get fixed somehow within PluralizationRules. + * + * @dataProvider failingLangcodes + */ + public function testFailedLangcodes($nplural, $langCodes) + { + $matrix = $this->generateTestData($langCodes); + $this->validateMatrix($nplural, $matrix, false); + } + + /** + * @dataProvider successLangcodes + */ + public function testLangcodes($nplural, $langCodes) + { + $matrix = $this->generateTestData($langCodes); + $this->validateMatrix($nplural, $matrix); + } + + /** + * This array should contain all currently known langcodes. + * + * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete. + * + * @return array + */ + public function successLangcodes() + { + return array( + array('1', array('ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky')), + array('2', array('nl', 'fr', 'en', 'de', 'de_GE', 'hy', 'hy_AM')), + array('3', array('be', 'bs', 'cs', 'hr')), + array('4', array('cy', 'mt', 'sl')), + array('5', array()), + array('6', array('ar')), + ); + } + + /** + * This array should be at least empty within the near future. + * + * This both depends on a complete list trying to add above as understanding + * the plural rules of the current failing languages. + * + * @return array with nplural together with langcodes + */ + public function failingLangcodes() + { + return array( + array('1', array('fa')), + array('2', array('jbo')), + array('3', array('cbs')), + array('4', array('gd', 'kw')), + array('5', array('ga')), + array('6', array()), + ); + } + + /** + * We validate only on the plural coverage. Thus the real rules is not tested. + * + * @param string $nplural plural expected + * @param array $matrix containing langcodes and their plural index values + * @param bool $expectSuccess + */ + protected function validateMatrix($nplural, $matrix, $expectSuccess = true) + { + foreach ($matrix as $langCode => $data) { + $indexes = array_flip($data); + if ($expectSuccess) { + $this->assertEquals($nplural, count($indexes), "Langcode '$langCode' has '$nplural' plural forms."); + } else { + $this->assertNotEquals((int) $nplural, count($indexes), "Langcode '$langCode' has '$nplural' plural forms."); + } + } + } + + protected function generateTestData($langCodes) + { + $matrix = array(); + foreach ($langCodes as $langCode) { + for ($count = 0; $count < 200; ++$count) { + $plural = PluralizationRules::get($count, $langCode); + $matrix[$langCode][$count] = $plural; + } + } + + return $matrix; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/TranslatorCacheTest.php b/public/system/storage/vendor/symfony/translation/Tests/TranslatorCacheTest.php new file mode 100644 index 0000000..7509358 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/TranslatorCacheTest.php @@ -0,0 +1,299 @@ +<?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\Tests; + +use Symfony\Component\Config\Resource\SelfCheckingResourceInterface; +use Symfony\Component\Translation\Loader\ArrayLoader; +use Symfony\Component\Translation\Loader\LoaderInterface; +use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\MessageCatalogue; + +class TranslatorCacheTest extends \PHPUnit_Framework_TestCase +{ + protected $tmpDir; + + protected function setUp() + { + $this->tmpDir = sys_get_temp_dir().'/sf2_translation'; + $this->deleteTmpDir(); + } + + protected function tearDown() + { + $this->deleteTmpDir(); + } + + protected function deleteTmpDir() + { + if (!file_exists($dir = $this->tmpDir)) { + return; + } + + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->tmpDir), \RecursiveIteratorIterator::CHILD_FIRST); + foreach ($iterator as $path) { + if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) { + continue; + } + if ($path->isDir()) { + rmdir($path->__toString()); + } else { + unlink($path->__toString()); + } + } + rmdir($this->tmpDir); + } + + /** + * @dataProvider runForDebugAndProduction + */ + public function testThatACacheIsUsed($debug) + { + $locale = 'any_locale'; + $format = 'some_format'; + $msgid = 'test'; + + // Prime the cache + $translator = new Translator($locale, null, $this->tmpDir, $debug); + $translator->addLoader($format, new ArrayLoader()); + $translator->addResource($format, array($msgid => 'OK'), $locale); + $translator->trans($msgid); + + // Try again and see we get a valid result whilst no loader can be used + $translator = new Translator($locale, null, $this->tmpDir, $debug); + $translator->addLoader($format, $this->createFailingLoader()); + $translator->addResource($format, array($msgid => 'OK'), $locale); + $this->assertEquals('OK', $translator->trans($msgid), '-> caching does not work in '.($debug ? 'debug' : 'production')); + } + + public function testCatalogueIsReloadedWhenResourcesAreNoLongerFresh() + { + /* + * The testThatACacheIsUsed() test showed that we don't need the loader as long as the cache + * is fresh. + * + * Now we add a Resource that is never fresh and make sure that the + * cache is discarded (the loader is called twice). + * + * We need to run this for debug=true only because in production the cache + * will never be revalidated. + */ + + $locale = 'any_locale'; + $format = 'some_format'; + $msgid = 'test'; + + $catalogue = new MessageCatalogue($locale, array()); + $catalogue->addResource(new StaleResource()); // better use a helper class than a mock, because it gets serialized in the cache and re-loaded + + /** @var LoaderInterface|\PHPUnit_Framework_MockObject_MockObject $loader */ + $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface'); + $loader + ->expects($this->exactly(2)) + ->method('load') + ->will($this->returnValue($catalogue)) + ; + + // 1st pass + $translator = new Translator($locale, null, $this->tmpDir, true); + $translator->addLoader($format, $loader); + $translator->addResource($format, null, $locale); + $translator->trans($msgid); + + // 2nd pass + $translator = new Translator($locale, null, $this->tmpDir, true); + $translator->addLoader($format, $loader); + $translator->addResource($format, null, $locale); + $translator->trans($msgid); + } + + /** + * @dataProvider runForDebugAndProduction + */ + public function testDifferentTranslatorsForSameLocaleDoNotOverwriteEachOthersCache($debug) + { + /* + * Similar to the previous test. After we used the second translator, make + * sure there's still a useable cache for the first one. + */ + + $locale = 'any_locale'; + $format = 'some_format'; + $msgid = 'test'; + + // Create a Translator and prime its cache + $translator = new Translator($locale, null, $this->tmpDir, $debug); + $translator->addLoader($format, new ArrayLoader()); + $translator->addResource($format, array($msgid => 'OK'), $locale); + $translator->trans($msgid); + + // Create another Translator with a different catalogue for the same locale + $translator = new Translator($locale, null, $this->tmpDir, $debug); + $translator->addLoader($format, new ArrayLoader()); + $translator->addResource($format, array($msgid => 'FAIL'), $locale); + $translator->trans($msgid); + + // Now the first translator must still have a useable cache. + $translator = new Translator($locale, null, $this->tmpDir, $debug); + $translator->addLoader($format, $this->createFailingLoader()); + $translator->addResource($format, array($msgid => 'OK'), $locale); + $this->assertEquals('OK', $translator->trans($msgid), '-> the cache was overwritten by another translator instance in '.($debug ? 'debug' : 'production')); + } + + public function testDifferentCacheFilesAreUsedForDifferentSetsOfFallbackLocales() + { + /* + * Because the cache file contains a catalogue including all of its fallback + * catalogues, we must take the set of fallback locales into consideration when + * loading a catalogue from the cache. + */ + $translator = new Translator('a', null, $this->tmpDir); + $translator->setFallbackLocales(array('b')); + + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foo (a)'), 'a'); + $translator->addResource('array', array('bar' => 'bar (b)'), 'b'); + + $this->assertEquals('bar (b)', $translator->trans('bar')); + + // Remove fallback locale + $translator->setFallbackLocales(array()); + $this->assertEquals('bar', $translator->trans('bar')); + + // Use a fresh translator with no fallback locales, result should be the same + $translator = new Translator('a', null, $this->tmpDir); + + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foo (a)'), 'a'); + $translator->addResource('array', array('bar' => 'bar (b)'), 'b'); + + $this->assertEquals('bar', $translator->trans('bar')); + } + + public function testPrimaryAndFallbackCataloguesContainTheSameMessagesRegardlessOfCaching() + { + /* + * As a safeguard against potential BC breaks, make sure that primary and fallback + * catalogues (reachable via getFallbackCatalogue()) always contain the full set of + * messages provided by the loader. This must also be the case when these catalogues + * are (internally) read from a cache. + * + * Optimizations inside the translator must not change this behaviour. + */ + + /* + * Create a translator that loads two catalogues for two different locales. + * The catalogues contain distinct sets of messages. + */ + $translator = new Translator('a', null, $this->tmpDir); + $translator->setFallbackLocales(array('b')); + + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foo (a)'), 'a'); + $translator->addResource('array', array('foo' => 'foo (b)'), 'b'); + $translator->addResource('array', array('bar' => 'bar (b)'), 'b'); + + $catalogue = $translator->getCatalogue('a'); + $this->assertFalse($catalogue->defines('bar')); // Sure, the "a" catalogue does not contain that message. + + $fallback = $catalogue->getFallbackCatalogue(); + $this->assertTrue($fallback->defines('foo')); // "foo" is present in "a" and "b" + + /* + * Now, repeat the same test. + * Behind the scenes, the cache is used. But that should not matter, right? + */ + $translator = new Translator('a', null, $this->tmpDir); + $translator->setFallbackLocales(array('b')); + + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foo (a)'), 'a'); + $translator->addResource('array', array('foo' => 'foo (b)'), 'b'); + $translator->addResource('array', array('bar' => 'bar (b)'), 'b'); + + $catalogue = $translator->getCatalogue('a'); + $this->assertFalse($catalogue->defines('bar')); + + $fallback = $catalogue->getFallbackCatalogue(); + $this->assertTrue($fallback->defines('foo')); + } + + public function testRefreshCacheWhenResourcesAreNoLongerFresh() + { + $resource = $this->getMock('Symfony\Component\Config\Resource\SelfCheckingResourceInterface'); + $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface'); + $resource->method('isFresh')->will($this->returnValue(false)); + $loader + ->expects($this->exactly(2)) + ->method('load') + ->will($this->returnValue($this->getCatalogue('fr', array(), array($resource)))); + + // prime the cache + $translator = new Translator('fr', null, $this->tmpDir, true); + $translator->addLoader('loader', $loader); + $translator->addResource('loader', 'foo', 'fr'); + $translator->trans('foo'); + + // prime the cache second time + $translator = new Translator('fr', null, $this->tmpDir, true); + $translator->addLoader('loader', $loader); + $translator->addResource('loader', 'foo', 'fr'); + $translator->trans('foo'); + } + + protected function getCatalogue($locale, $messages, $resources = array()) + { + $catalogue = new MessageCatalogue($locale); + foreach ($messages as $key => $translation) { + $catalogue->set($key, $translation); + } + foreach ($resources as $resource) { + $catalogue->addResource($resource); + } + + return $catalogue; + } + + public function runForDebugAndProduction() + { + return array(array(true), array(false)); + } + + /** + * @return LoaderInterface + */ + private function createFailingLoader() + { + $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface'); + $loader + ->expects($this->never()) + ->method('load'); + + return $loader; + } +} + +class StaleResource implements SelfCheckingResourceInterface +{ + public function isFresh($timestamp) + { + return false; + } + + public function getResource() + { + } + + public function __toString() + { + return ''; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/TranslatorTest.php b/public/system/storage/vendor/symfony/translation/Tests/TranslatorTest.php new file mode 100644 index 0000000..0f65d3e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/TranslatorTest.php @@ -0,0 +1,533 @@ +<?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\Tests; + +use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\MessageSelector; +use Symfony\Component\Translation\Loader\ArrayLoader; +use Symfony\Component\Translation\MessageCatalogue; + +class TranslatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getInvalidLocalesTests + * @expectedException \InvalidArgumentException + */ + public function testConstructorInvalidLocale($locale) + { + $translator = new Translator($locale, new MessageSelector()); + } + + /** + * @dataProvider getValidLocalesTests + */ + public function testConstructorValidLocale($locale) + { + $translator = new Translator($locale, new MessageSelector()); + + $this->assertEquals($locale, $translator->getLocale()); + } + + public function testConstructorWithoutLocale() + { + $translator = new Translator(null, new MessageSelector()); + + $this->assertNull($translator->getLocale()); + } + + public function testSetGetLocale() + { + $translator = new Translator('en'); + + $this->assertEquals('en', $translator->getLocale()); + + $translator->setLocale('fr'); + $this->assertEquals('fr', $translator->getLocale()); + } + + /** + * @dataProvider getInvalidLocalesTests + * @expectedException \InvalidArgumentException + */ + public function testSetInvalidLocale($locale) + { + $translator = new Translator('fr', new MessageSelector()); + $translator->setLocale($locale); + } + + /** + * @dataProvider getValidLocalesTests + */ + public function testSetValidLocale($locale) + { + $translator = new Translator($locale, new MessageSelector()); + $translator->setLocale($locale); + + $this->assertEquals($locale, $translator->getLocale()); + } + + public function testGetCatalogue() + { + $translator = new Translator('en'); + + $this->assertEquals(new MessageCatalogue('en'), $translator->getCatalogue()); + + $translator->setLocale('fr'); + $this->assertEquals(new MessageCatalogue('fr'), $translator->getCatalogue('fr')); + } + + public function testGetCatalogueReturnsConsolidatedCatalogue() + { + /* + * This will be useful once we refactor so that different domains will be loaded lazily (on-demand). + * In that case, getCatalogue() will probably have to load all missing domains in order to return + * one complete catalogue. + */ + + $locale = 'whatever'; + $translator = new Translator($locale); + $translator->addLoader('loader-a', new ArrayLoader()); + $translator->addLoader('loader-b', new ArrayLoader()); + $translator->addResource('loader-a', array('foo' => 'foofoo'), $locale, 'domain-a'); + $translator->addResource('loader-b', array('bar' => 'foobar'), $locale, 'domain-b'); + + /* + * Test that we get a single catalogue comprising messages + * from different loaders and different domains + */ + $catalogue = $translator->getCatalogue($locale); + $this->assertTrue($catalogue->defines('foo', 'domain-a')); + $this->assertTrue($catalogue->defines('bar', 'domain-b')); + } + + public function testSetFallbackLocales() + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foofoo'), 'en'); + $translator->addResource('array', array('bar' => 'foobar'), 'fr'); + + // force catalogue loading + $translator->trans('bar'); + + $translator->setFallbackLocales(array('fr')); + $this->assertEquals('foobar', $translator->trans('bar')); + } + + public function testSetFallbackLocalesMultiple() + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foo (en)'), 'en'); + $translator->addResource('array', array('bar' => 'bar (fr)'), 'fr'); + + // force catalogue loading + $translator->trans('bar'); + + $translator->setFallbackLocales(array('fr_FR', 'fr')); + $this->assertEquals('bar (fr)', $translator->trans('bar')); + } + + /** + * @dataProvider getInvalidLocalesTests + * @expectedException \InvalidArgumentException + */ + public function testSetFallbackInvalidLocales($locale) + { + $translator = new Translator('fr', new MessageSelector()); + $translator->setFallbackLocales(array('fr', $locale)); + } + + /** + * @dataProvider getValidLocalesTests + */ + public function testSetFallbackValidLocales($locale) + { + $translator = new Translator($locale, new MessageSelector()); + $translator->setFallbackLocales(array('fr', $locale)); + // no assertion. this method just asserts that no exception is thrown + } + + public function testTransWithFallbackLocale() + { + $translator = new Translator('fr_FR'); + $translator->setFallbackLocales(array('en')); + + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('bar' => 'foobar'), 'en'); + + $this->assertEquals('foobar', $translator->trans('bar')); + } + + /** + * @dataProvider getInvalidLocalesTests + * @expectedException \InvalidArgumentException + */ + public function testAddResourceInvalidLocales($locale) + { + $translator = new Translator('fr', new MessageSelector()); + $translator->addResource('array', array('foo' => 'foofoo'), $locale); + } + + /** + * @dataProvider getValidLocalesTests + */ + public function testAddResourceValidLocales($locale) + { + $translator = new Translator('fr', new MessageSelector()); + $translator->addResource('array', array('foo' => 'foofoo'), $locale); + // no assertion. this method just asserts that no exception is thrown + } + + public function testAddResourceAfterTrans() + { + $translator = new Translator('fr'); + $translator->addLoader('array', new ArrayLoader()); + + $translator->setFallbackLocales(array('en')); + + $translator->addResource('array', array('foo' => 'foofoo'), 'en'); + $this->assertEquals('foofoo', $translator->trans('foo')); + + $translator->addResource('array', array('bar' => 'foobar'), 'en'); + $this->assertEquals('foobar', $translator->trans('bar')); + } + + /** + * @dataProvider getTransFileTests + * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException + */ + public function testTransWithoutFallbackLocaleFile($format, $loader) + { + $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader; + $translator = new Translator('en'); + $translator->addLoader($format, new $loaderClass()); + $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en'); + $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en'); + + // force catalogue loading + $translator->trans('foo'); + } + + /** + * @dataProvider getTransFileTests + */ + public function testTransWithFallbackLocaleFile($format, $loader) + { + $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader; + $translator = new Translator('en_GB'); + $translator->addLoader($format, new $loaderClass()); + $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en_GB'); + $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en', 'resources'); + + $this->assertEquals('bar', $translator->trans('foo', array(), 'resources')); + } + + public function testTransWithFallbackLocaleBis() + { + $translator = new Translator('en_US'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foofoo'), 'en_US'); + $translator->addResource('array', array('bar' => 'foobar'), 'en'); + $this->assertEquals('foobar', $translator->trans('bar')); + } + + public function testTransWithFallbackLocaleTer() + { + $translator = new Translator('fr_FR'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foo (en_US)'), 'en_US'); + $translator->addResource('array', array('bar' => 'bar (en)'), 'en'); + + $translator->setFallbackLocales(array('en_US', 'en')); + + $this->assertEquals('foo (en_US)', $translator->trans('foo')); + $this->assertEquals('bar (en)', $translator->trans('bar')); + } + + public function testTransNonExistentWithFallback() + { + $translator = new Translator('fr'); + $translator->setFallbackLocales(array('en')); + $translator->addLoader('array', new ArrayLoader()); + $this->assertEquals('non-existent', $translator->trans('non-existent')); + } + + /** + * @expectedException \RuntimeException + */ + public function testWhenAResourceHasNoRegisteredLoader() + { + $translator = new Translator('en'); + $translator->addResource('array', array('foo' => 'foofoo'), 'en'); + + $translator->trans('foo'); + } + + public function testFallbackCatalogueResources() + { + $translator = new Translator('en_GB', new MessageSelector()); + $translator->addLoader('yml', new \Symfony\Component\Translation\Loader\YamlFileLoader()); + $translator->addResource('yml', __DIR__.'/fixtures/empty.yml', 'en_GB'); + $translator->addResource('yml', __DIR__.'/fixtures/resources.yml', 'en'); + + // force catalogue loading + $this->assertEquals('bar', $translator->trans('foo', array())); + + $resources = $translator->getCatalogue('en')->getResources(); + $this->assertCount(1, $resources); + $this->assertContains(__DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'resources.yml', $resources); + + $resources = $translator->getCatalogue('en_GB')->getResources(); + $this->assertCount(2, $resources); + $this->assertContains(__DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'empty.yml', $resources); + $this->assertContains(__DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'resources.yml', $resources); + } + + /** + * @dataProvider getTransTests + */ + public function testTrans($expected, $id, $translation, $parameters, $locale, $domain) + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array((string) $id => $translation), $locale, $domain); + + $this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale)); + } + + /** + * @dataProvider getInvalidLocalesTests + * @expectedException \InvalidArgumentException + */ + public function testTransInvalidLocale($locale) + { + $translator = new Translator('en', new MessageSelector()); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foofoo'), 'en'); + + $translator->trans('foo', array(), '', $locale); + } + + /** + * @dataProvider getValidLocalesTests + */ + public function testTransValidLocale($locale) + { + $translator = new Translator($locale, new MessageSelector()); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('test' => 'OK'), $locale); + + $this->assertEquals('OK', $translator->trans('test')); + $this->assertEquals('OK', $translator->trans('test', array(), null, $locale)); + } + + /** + * @dataProvider getFlattenedTransTests + */ + public function testFlattenedTrans($expected, $messages, $id) + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', $messages, 'fr', ''); + + $this->assertEquals($expected, $translator->trans($id, array(), '', 'fr')); + } + + /** + * @dataProvider getTransChoiceTests + */ + public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain) + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array((string) $id => $translation), $locale, $domain); + + $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale)); + } + + /** + * @dataProvider getInvalidLocalesTests + * @expectedException \InvalidArgumentException + */ + public function testTransChoiceInvalidLocale($locale) + { + $translator = new Translator('en', new MessageSelector()); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foofoo'), 'en'); + + $translator->transChoice('foo', 1, array(), '', $locale); + } + + /** + * @dataProvider getValidLocalesTests + */ + public function testTransChoiceValidLocale($locale) + { + $translator = new Translator('en', new MessageSelector()); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foofoo'), 'en'); + + $translator->transChoice('foo', 1, array(), '', $locale); + // no assertion. this method just asserts that no exception is thrown + } + + public function getTransFileTests() + { + return array( + array('csv', 'CsvFileLoader'), + array('ini', 'IniFileLoader'), + array('mo', 'MoFileLoader'), + array('po', 'PoFileLoader'), + array('php', 'PhpFileLoader'), + array('ts', 'QtFileLoader'), + array('xlf', 'XliffFileLoader'), + array('yml', 'YamlFileLoader'), + array('json', 'JsonFileLoader'), + ); + } + + public function getTransTests() + { + return array( + array('Symfony est super !', 'Symfony is great!', 'Symfony est super !', array(), 'fr', ''), + array('Symfony est awesome !', 'Symfony is %what%!', 'Symfony est %what% !', array('%what%' => 'awesome'), 'fr', ''), + array('Symfony est super !', new StringClass('Symfony is great!'), 'Symfony est super !', array(), 'fr', ''), + ); + } + + public function getFlattenedTransTests() + { + $messages = array( + 'symfony' => array( + 'is' => array( + 'great' => 'Symfony est super!', + ), + ), + 'foo' => array( + 'bar' => array( + 'baz' => 'Foo Bar Baz', + ), + 'baz' => 'Foo Baz', + ), + ); + + return array( + array('Symfony est super!', $messages, 'symfony.is.great'), + array('Foo Bar Baz', $messages, 'foo.bar.baz'), + array('Foo Baz', $messages, 'foo.baz'), + ); + } + + public function getTransChoiceTests() + { + return array( + array('Il y a 0 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''), + array('Il y a 1 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''), + array('Il y a 10 pommes', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''), + + array('Il y a 0 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''), + array('Il y a 1 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''), + array('Il y a 10 pommes', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''), + + array('Il y a 0 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''), + array('Il y a 1 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''), + array('Il y a 10 pommes', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''), + + array('Il n\'y a aucune pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''), + array('Il y a 1 pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''), + array('Il y a 10 pommes', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''), + + array('Il y a 0 pomme', new StringClass('{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples'), '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''), + ); + } + + public function getInvalidLocalesTests() + { + return array( + array('fr FR'), + array('français'), + array('fr+en'), + array('utf#8'), + array('fr&en'), + array('fr~FR'), + array(' fr'), + array('fr '), + array('fr*'), + array('fr/FR'), + array('fr\\FR'), + ); + } + + public function getValidLocalesTests() + { + return array( + array(''), + array(null), + array('fr'), + array('francais'), + array('FR'), + array('frFR'), + array('fr-FR'), + array('fr_FR'), + array('fr.FR'), + array('fr-FR.UTF8'), + array('sr@latin'), + ); + } + + public function testTransChoiceFallback() + { + $translator = new Translator('ru'); + $translator->setFallbackLocales(array('en')); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en'); + + $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10))); + } + + public function testTransChoiceFallbackBis() + { + $translator = new Translator('ru'); + $translator->setFallbackLocales(array('en_US', 'en')); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en_US'); + + $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10))); + } + + public function testTransChoiceFallbackWithNoTranslation() + { + $translator = new Translator('ru'); + $translator->setFallbackLocales(array('en')); + $translator->addLoader('array', new ArrayLoader()); + + // consistent behavior with Translator::trans(), which returns the string + // unchanged if it can't be found + $this->assertEquals('some_message2', $translator->transChoice('some_message2', 10, array('%count%' => 10))); + } +} + +class StringClass +{ + protected $str; + + public function __construct($str) + { + $this->str = $str; + } + + public function __toString() + { + return $this->str; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Util/ArrayConverterTest.php b/public/system/storage/vendor/symfony/translation/Tests/Util/ArrayConverterTest.php new file mode 100644 index 0000000..9eea275 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Util/ArrayConverterTest.php @@ -0,0 +1,73 @@ +<?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\Tests\Util; + +use Symfony\Component\Translation\Util\ArrayConverter; + +class ArrayConverterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider messsagesData + */ + public function testDump($input, $expectedOutput) + { + $this->assertEquals($expectedOutput, ArrayConverter::expandToTree($input)); + } + + public function messsagesData() + { + return array( + array( + // input + array( + 'foo1' => 'bar', + 'foo.bar' => 'value', + ), + // expected output + array( + 'foo1' => 'bar', + 'foo' => array('bar' => 'value'), + ), + ), + array( + // input + array( + 'foo.bar' => 'value1', + 'foo.bar.test' => 'value2', + ), + // expected output + array( + 'foo' => array( + 'bar' => 'value1', + 'bar.test' => 'value2', + ), + ), + ), + array( + // input + array( + 'foo.level2.level3.level4' => 'value1', + 'foo.level2' => 'value2', + 'foo.bar' => 'value3', + ), + // expected output + array( + 'foo' => array( + 'level2' => 'value2', + 'level2.level3.level4' => 'value1', + 'bar' => 'value3', + ), + ), + ), + ); + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/Writer/TranslationWriterTest.php b/public/system/storage/vendor/symfony/translation/Tests/Writer/TranslationWriterTest.php new file mode 100644 index 0000000..f7a8a83 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/Writer/TranslationWriterTest.php @@ -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\Tests\Writer; + +use Symfony\Component\Translation\Dumper\DumperInterface; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Writer\TranslationWriter; + +class TranslationWriterTest extends \PHPUnit_Framework_TestCase +{ + public function testWriteTranslations() + { + $dumper = $this->getMock('Symfony\Component\Translation\Dumper\DumperInterface'); + $dumper + ->expects($this->once()) + ->method('dump'); + + $writer = new TranslationWriter(); + $writer->addDumper('test', $dumper); + $writer->writeTranslations(new MessageCatalogue(array()), 'test'); + } + + public function testDisableBackup() + { + $nonBackupDumper = new NonBackupDumper(); + $backupDumper = new BackupDumper(); + + $writer = new TranslationWriter(); + $writer->addDumper('non_backup', $nonBackupDumper); + $writer->addDumper('backup', $backupDumper); + $writer->disableBackup(); + + $this->assertFalse($backupDumper->backup, 'backup can be disabled if setBackup() method does exist'); + } +} + +class NonBackupDumper implements DumperInterface +{ + public function dump(MessageCatalogue $messages, $options = array()) + { + } +} + +class BackupDumper implements DumperInterface +{ + public $backup = true; + + public function dump(MessageCatalogue $messages, $options = array()) + { + } + + public function setBackup($backup) + { + $this->backup = $backup; + } +} diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty-translation.mo b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty-translation.mo Binary files differnew file mode 100644 index 0000000..ed01000 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty-translation.mo diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty-translation.po b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty-translation.po new file mode 100644 index 0000000..ff6f22a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty-translation.po @@ -0,0 +1,3 @@ +msgid "foo" +msgstr "" + diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.csv b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.csv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.csv diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.ini b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.ini new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.ini diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.json b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.json new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.json diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.mo b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.mo new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.mo diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.po b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.po new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.po diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.xlf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.xlf diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.yml b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.yml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/empty.yml diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/encoding.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/encoding.xlf new file mode 100644 index 0000000..0a88f92 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/encoding.xlf @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="en" datatype="plaintext" original="file.ext"> + <body> + <trans-unit id="1" resname="foo"> + <source>foo</source> + <target>br</target> + <note>bz</note> + </trans-unit> + <trans-unit id="2" resname="bar"> + <source>bar</source> + <target>f</target> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/escaped-id-plurals.po b/public/system/storage/vendor/symfony/translation/Tests/fixtures/escaped-id-plurals.po new file mode 100644 index 0000000..c412aa2 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/escaped-id-plurals.po @@ -0,0 +1,10 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" + +msgid "escaped \"foo\"" +msgid_plural "escaped \"foos\"" +msgstr[0] "escaped \"bar\"" +msgstr[1] "escaped \"bars\"" diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/escaped-id.po b/public/system/storage/vendor/symfony/translation/Tests/fixtures/escaped-id.po new file mode 100644 index 0000000..308eadd --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/escaped-id.po @@ -0,0 +1,8 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" + +msgid "escaped \"foo\"" +msgstr "escaped \"bar\"" diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/fuzzy-translations.po b/public/system/storage/vendor/symfony/translation/Tests/fixtures/fuzzy-translations.po new file mode 100644 index 0000000..04d4047 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/fuzzy-translations.po @@ -0,0 +1,10 @@ +#, php-format +msgid "foo1" +msgstr "bar1" + +#, fuzzy, php-format +msgid "foo2" +msgstr "fuzzy bar2" + +msgid "foo3" +msgstr "bar3" diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/invalid-xml-resources.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/invalid-xml-resources.xlf new file mode 100644 index 0000000..7bf6c98 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/invalid-xml-resources.xlf @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="en" datatype="plaintext" original="file.ext"> + <body> + <trans-unit id="1"> + <source>foo</source> + <target>bar + </trans-unit> + <trans-unit id="2"> + <source>extra</source> + </trans-unit> + <trans-unit id="3"> + <source>key</source> + <target></target> + </trans-unit> + <trans-unit id="4"> + <source>test</source> + <target>with</target> + <note>note</note> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/malformed.json b/public/system/storage/vendor/symfony/translation/Tests/fixtures/malformed.json new file mode 100644 index 0000000..4563ec6 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/malformed.json @@ -0,0 +1,3 @@ +{ + "foo" "bar" +}
\ No newline at end of file diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/messages.yml b/public/system/storage/vendor/symfony/translation/Tests/fixtures/messages.yml new file mode 100644 index 0000000..d4f82d7 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/messages.yml @@ -0,0 +1,3 @@ +foo: + bar1: value1 + bar2: value2 diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/messages_linear.yml b/public/system/storage/vendor/symfony/translation/Tests/fixtures/messages_linear.yml new file mode 100644 index 0000000..6c1687d --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/messages_linear.yml @@ -0,0 +1,2 @@ +foo.bar1: value1 +foo.bar2: value2 diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/non-valid.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/non-valid.xlf new file mode 100644 index 0000000..734fc97 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/non-valid.xlf @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> + <file source-language="en" datatype="plaintext" original="file.ext"> + <body> + <trans-unit> + <source>foo</source> + <target>bar</target> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/non-valid.yml b/public/system/storage/vendor/symfony/translation/Tests/fixtures/non-valid.yml new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/non-valid.yml @@ -0,0 +1 @@ +foo diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/plurals.mo b/public/system/storage/vendor/symfony/translation/Tests/fixtures/plurals.mo Binary files differnew file mode 100644 index 0000000..6445e77 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/plurals.mo diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/plurals.po b/public/system/storage/vendor/symfony/translation/Tests/fixtures/plurals.po new file mode 100644 index 0000000..439c41a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/plurals.po @@ -0,0 +1,5 @@ +msgid "foo" +msgid_plural "foos" +msgstr[0] "bar" +msgstr[1] "bars" + diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resname.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resname.xlf new file mode 100644 index 0000000..2df16af --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resname.xlf @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="en" datatype="plaintext" original="file.ext"> + <body> + <trans-unit id="1" resname="foo"> + <source></source> + <target>bar</target> + </trans-unit> + <trans-unit id="2" resname="bar"> + <source>bar source</source> + <target>baz</target> + </trans-unit> + <trans-unit id="3"> + <source>baz</source> + <target>foo</target> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/corrupted/resources.dat b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/corrupted/resources.dat new file mode 100644 index 0000000..391250c --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/corrupted/resources.dat @@ -0,0 +1 @@ +XXX
\ No newline at end of file diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.res b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.res Binary files differnew file mode 100644 index 0000000..1fc1436 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.res diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.txt b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.txt new file mode 100644 index 0000000..3d9e9ea --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.txt @@ -0,0 +1,3 @@ +en{ + symfony{"Symfony is great"} +}
\ No newline at end of file diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.res b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.res Binary files differnew file mode 100644 index 0000000..f584160 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.res diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.txt b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.txt new file mode 100644 index 0000000..182d0a0 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.txt @@ -0,0 +1,3 @@ +fr{ + symfony{"Symfony est génial"} +}
\ No newline at end of file diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/packagelist.txt b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/packagelist.txt new file mode 100644 index 0000000..c5783ed --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/packagelist.txt @@ -0,0 +1,2 @@ +en.res +fr.res diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/resources.dat b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/resources.dat Binary files differnew file mode 100644 index 0000000..563b0ea --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/resources.dat diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/res/en.res b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/res/en.res Binary files differnew file mode 100644 index 0000000..ad894a9 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resourcebundle/res/en.res diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-2.0-clean.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-2.0-clean.xlf new file mode 100644 index 0000000..2efa155 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-2.0-clean.xlf @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="fr-FR" trgLang="en-US"> + <file id="messages.en_US"> + <unit id="acbd18db4cc2f85cedef654fccc4a4d8"> + <segment> + <source>foo</source> + <target>bar</target> + </segment> + </unit> + <unit id="3c6e0b8a9c15224a8228b9a98ca1531d"> + <segment> + <source>key</source> + <target order="1"></target> + </segment> + </unit> + <unit id="18e6a493872558d949b4c16ea1fa6ab6"> + <segment> + <source>key.with.cdata</source> + <target><![CDATA[<source> & <target>]]></target> + </segment> + </unit> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-2.0.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-2.0.xlf new file mode 100644 index 0000000..166172a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-2.0.xlf @@ -0,0 +1,25 @@ +<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en-US" trgLang="ja-JP"> + <file id="f1" original="Graphic Example.psd"> + <skeleton href="Graphic Example.psd.skl"/> + <unit id="1"> + <segment> + <source>Quetzal</source> + <target>Quetzal</target> + </segment> + </unit> + <group id="1"> + <unit id="2"> + <segment> + <source>foo</source> + <target>XLIFF 文書を編集、または処理 するアプリケーションです。</target> + </segment> + </unit> + <unit id="3"> + <segment> + <source>bar</source> + <target order="1">XLIFF データ・マネージャ</target> + </segment> + </unit> + </group> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-clean.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-clean.xlf new file mode 100644 index 0000000..436e19e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-clean.xlf @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext"> + <header> + <tool tool-id="symfony" tool-name="Symfony"/> + </header> + <body> + <trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo"> + <source>foo</source> + <target>bar</target> + <note priority="1" from="bar">baz</note> + </trans-unit> + <trans-unit id="3c6e0b8a9c15224a8228b9a98ca1531d" resname="key"> + <source>key</source> + <target></target> + <note>baz</note> + <note>qux</note> + </trans-unit> + <trans-unit id="18e6a493872558d949b4c16ea1fa6ab6" resname="key.with.cdata"> + <source>key.with.cdata</source> + <target><![CDATA[<source> & <target>]]></target> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-target-attributes.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-target-attributes.xlf new file mode 100644 index 0000000..e3afb49 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-target-attributes.xlf @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext"> + <header> + <tool tool-id="symfony" tool-name="Symfony"/> + </header> + <body> + <trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo"> + <source>foo</source> + <target state="needs-translation">bar</target> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-tool-info.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-tool-info.xlf new file mode 100644 index 0000000..1ed06d2 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources-tool-info.xlf @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="en-US" target-language="en-US" datatype="plaintext" original="file.ext"> + <header> + <tool tool-id="foo" tool-name="foo" tool-version="0.0" tool-company="Foo"/> + </header> + <body> + <trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo"> + <source>foo</source> + <target>bar</target> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.csv b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.csv new file mode 100644 index 0000000..374b9eb --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.csv @@ -0,0 +1,4 @@ +"foo"; "bar" +#"bar"; "foo" +"incorrect"; "number"; "columns"; "will"; "be"; "ignored" +"incorrect"
\ No newline at end of file diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.dump.json b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.dump.json new file mode 100644 index 0000000..335965d --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.dump.json @@ -0,0 +1 @@ +{"foo":"\u0022bar\u0022"}
\ No newline at end of file diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.ini b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.ini new file mode 100644 index 0000000..4953062 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.ini @@ -0,0 +1 @@ +foo="bar" diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.json b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.json new file mode 100644 index 0000000..8a79687 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.json @@ -0,0 +1,3 @@ +{ + "foo": "bar" +}
\ No newline at end of file diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.mo b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.mo Binary files differnew file mode 100644 index 0000000..0a96602 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.mo diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.php b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.php new file mode 100644 index 0000000..c291398 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.php @@ -0,0 +1,5 @@ +<?php + +return array ( + 'foo' => 'bar', +); diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.po b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.po new file mode 100644 index 0000000..ccfce6b --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.po @@ -0,0 +1,8 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" + +msgid "foo" +msgstr "bar"
\ No newline at end of file diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.ts b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.ts new file mode 100644 index 0000000..40e1852 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.ts @@ -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> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.xlf new file mode 100644 index 0000000..b0e5988 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.xlf @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="en" datatype="plaintext" original="file.ext"> + <body> + <trans-unit id="1"> + <source>foo</source> + <target>bar</target> + </trans-unit> + <trans-unit id="2"> + <source>extra</source> + </trans-unit> + <trans-unit id="3"> + <source>key</source> + <target></target> + </trans-unit> + <trans-unit id="4"> + <source>test</source> + <target>with</target> + <note>note</note> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.yml b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.yml new file mode 100644 index 0000000..20e9ff3 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/resources.yml @@ -0,0 +1 @@ +foo: bar diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/valid.csv b/public/system/storage/vendor/symfony/translation/Tests/fixtures/valid.csv new file mode 100644 index 0000000..59882e5 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/valid.csv @@ -0,0 +1,4 @@ +foo;bar +bar;"foo +foo" +"foo;foo";bar diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/with-attributes.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/with-attributes.xlf new file mode 100644 index 0000000..7873062 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/with-attributes.xlf @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="en" datatype="plaintext" original="file.ext"> + <body> + <trans-unit id="1"> + <source>foo</source> + <target state="translated">bar</target> + </trans-unit> + <trans-unit id="2"> + <source>extra</source> + <target state="needs-translation">bar</target> + </trans-unit> + <trans-unit id="3"> + <source>key</source> + <target></target> + <note>baz</note> + <note priority="2" from="bar">qux</note> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/withdoctype.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/withdoctype.xlf new file mode 100644 index 0000000..f83e834 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/withdoctype.xlf @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<!DOCTYPE foo> +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> + <file source-language="en" datatype="plaintext" original="file.ext"> + <body> + <trans-unit id="1"> + <source>foo</source> + <target>bar</target> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Tests/fixtures/withnote.xlf b/public/system/storage/vendor/symfony/translation/Tests/fixtures/withnote.xlf new file mode 100644 index 0000000..b1d3f83 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Tests/fixtures/withnote.xlf @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> + <file source-language="en" datatype="plaintext" original="file.ext"> + <body> + <trans-unit id="1"> + <source>foo</source> + <target>bar</target> + <note priority="1">foo</note> + </trans-unit> + <trans-unit id="2"> + <source>extra</source> + <note from="foo">bar</note> + </trans-unit> + <trans-unit id="3"> + <source>key</source> + <target></target> + <note>baz</note> + <note priority="2" from="bar">qux</note> + </trans-unit> + </body> + </file> +</xliff> diff --git a/public/system/storage/vendor/symfony/translation/Translator.php b/public/system/storage/vendor/symfony/translation/Translator.php new file mode 100644 index 0000000..309a2b8 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Translator.php @@ -0,0 +1,441 @@ +<?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; + +use Symfony\Component\Translation\Loader\LoaderInterface; +use Symfony\Component\Translation\Exception\NotFoundResourceException; +use Symfony\Component\Config\ConfigCacheInterface; +use Symfony\Component\Config\ConfigCacheFactoryInterface; +use Symfony\Component\Config\ConfigCacheFactory; + +/** + * Translator. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class Translator implements TranslatorInterface, TranslatorBagInterface +{ + /** + * @var MessageCatalogueInterface[] + */ + protected $catalogues = array(); + + /** + * @var string + */ + private $locale; + + /** + * @var array + */ + private $fallbackLocales = array(); + + /** + * @var LoaderInterface[] + */ + private $loaders = array(); + + /** + * @var array + */ + private $resources = array(); + + /** + * @var MessageSelector + */ + private $selector; + + /** + * @var string + */ + private $cacheDir; + + /** + * @var bool + */ + private $debug; + + /** + * @var ConfigCacheFactoryInterface|null + */ + private $configCacheFactory; + + /** + * Constructor. + * + * @param string $locale The locale + * @param MessageSelector|null $selector The message selector for pluralization + * @param string|null $cacheDir The directory to use for the cache + * @param bool $debug Use cache in debug mode ? + * + * @throws \InvalidArgumentException If a locale contains invalid characters + */ + public function __construct($locale, MessageSelector $selector = null, $cacheDir = null, $debug = false) + { + $this->setLocale($locale); + $this->selector = $selector ?: new MessageSelector(); + $this->cacheDir = $cacheDir; + $this->debug = $debug; + } + + /** + * Sets the ConfigCache factory to use. + * + * @param ConfigCacheFactoryInterface $configCacheFactory + */ + public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory) + { + $this->configCacheFactory = $configCacheFactory; + } + + /** + * Adds a Loader. + * + * @param string $format The name of the loader (@see addResource()) + * @param LoaderInterface $loader A LoaderInterface instance + */ + public function addLoader($format, LoaderInterface $loader) + { + $this->loaders[$format] = $loader; + } + + /** + * Adds a Resource. + * + * @param string $format The name of the loader (@see addLoader()) + * @param mixed $resource The resource name + * @param string $locale The locale + * @param string $domain The domain + * + * @throws \InvalidArgumentException If the locale contains invalid characters + */ + public function addResource($format, $resource, $locale, $domain = null) + { + if (null === $domain) { + $domain = 'messages'; + } + + $this->assertValidLocale($locale); + + $this->resources[$locale][] = array($format, $resource, $domain); + + if (in_array($locale, $this->fallbackLocales)) { + $this->catalogues = array(); + } else { + unset($this->catalogues[$locale]); + } + } + + /** + * {@inheritdoc} + */ + public function setLocale($locale) + { + $this->assertValidLocale($locale); + $this->locale = $locale; + } + + /** + * {@inheritdoc} + */ + public function getLocale() + { + return $this->locale; + } + + /** + * Sets the fallback locales. + * + * @param array $locales The fallback locales + * + * @throws \InvalidArgumentException If a locale contains invalid characters + */ + public function setFallbackLocales(array $locales) + { + // needed as the fallback locales are linked to the already loaded catalogues + $this->catalogues = array(); + + foreach ($locales as $locale) { + $this->assertValidLocale($locale); + } + + $this->fallbackLocales = $locales; + } + + /** + * Gets the fallback locales. + * + * @return array $locales The fallback locales + */ + public function getFallbackLocales() + { + return $this->fallbackLocales; + } + + /** + * {@inheritdoc} + */ + public function trans($id, array $parameters = array(), $domain = null, $locale = null) + { + if (null === $domain) { + $domain = 'messages'; + } + + return strtr($this->getCatalogue($locale)->get((string) $id, $domain), $parameters); + } + + /** + * {@inheritdoc} + */ + public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) + { + if (null === $domain) { + $domain = 'messages'; + } + + $id = (string) $id; + $catalogue = $this->getCatalogue($locale); + $locale = $catalogue->getLocale(); + while (!$catalogue->defines($id, $domain)) { + if ($cat = $catalogue->getFallbackCatalogue()) { + $catalogue = $cat; + $locale = $catalogue->getLocale(); + } else { + break; + } + } + + return strtr($this->selector->choose($catalogue->get($id, $domain), (int) $number, $locale), $parameters); + } + + /** + * {@inheritdoc} + */ + public function getCatalogue($locale = null) + { + if (null === $locale) { + $locale = $this->getLocale(); + } else { + $this->assertValidLocale($locale); + } + + if (!isset($this->catalogues[$locale])) { + $this->loadCatalogue($locale); + } + + return $this->catalogues[$locale]; + } + + /** + * Gets the loaders. + * + * @return array LoaderInterface[] + */ + protected function getLoaders() + { + return $this->loaders; + } + + /** + * @param string $locale + */ + protected function loadCatalogue($locale) + { + if (null === $this->cacheDir) { + $this->initializeCatalogue($locale); + } else { + $this->initializeCacheCatalogue($locale); + } + } + + /** + * @param string $locale + */ + protected function initializeCatalogue($locale) + { + $this->assertValidLocale($locale); + + try { + $this->doLoadCatalogue($locale); + } catch (NotFoundResourceException $e) { + if (!$this->computeFallbackLocales($locale)) { + throw $e; + } + } + $this->loadFallbackCatalogues($locale); + } + + /** + * @param string $locale + */ + private function initializeCacheCatalogue($locale) + { + if (isset($this->catalogues[$locale])) { + /* Catalogue already initialized. */ + return; + } + + $this->assertValidLocale($locale); + $cache = $this->getConfigCacheFactory()->cache($this->getCatalogueCachePath($locale), + function (ConfigCacheInterface $cache) use ($locale) { + $this->dumpCatalogue($locale, $cache); + } + ); + + if (isset($this->catalogues[$locale])) { + /* Catalogue has been initialized as it was written out to cache. */ + return; + } + + /* Read catalogue from cache. */ + $this->catalogues[$locale] = include $cache->getPath(); + } + + private function dumpCatalogue($locale, ConfigCacheInterface $cache) + { + $this->initializeCatalogue($locale); + $fallbackContent = $this->getFallbackContent($this->catalogues[$locale]); + + $content = sprintf(<<<EOF +<?php + +use Symfony\Component\Translation\MessageCatalogue; + +\$catalogue = new MessageCatalogue('%s', %s); + +%s +return \$catalogue; + +EOF + , + $locale, + var_export($this->catalogues[$locale]->all(), true), + $fallbackContent + ); + + $cache->write($content, $this->catalogues[$locale]->getResources()); + } + + private function getFallbackContent(MessageCatalogue $catalogue) + { + $fallbackContent = ''; + $current = ''; + $replacementPattern = '/[^a-z0-9_]/i'; + $fallbackCatalogue = $catalogue->getFallbackCatalogue(); + while ($fallbackCatalogue) { + $fallback = $fallbackCatalogue->getLocale(); + $fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback)); + $currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current)); + + $fallbackContent .= sprintf(<<<EOF +\$catalogue%s = new MessageCatalogue('%s', %s); +\$catalogue%s->addFallbackCatalogue(\$catalogue%s); + +EOF + , + $fallbackSuffix, + $fallback, + var_export($fallbackCatalogue->all(), true), + $currentSuffix, + $fallbackSuffix + ); + $current = $fallbackCatalogue->getLocale(); + $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue(); + } + + return $fallbackContent; + } + + private function getCatalogueCachePath($locale) + { + return $this->cacheDir.'/catalogue.'.$locale.'.'.sha1(serialize($this->fallbackLocales)).'.php'; + } + + private function doLoadCatalogue($locale) + { + $this->catalogues[$locale] = new MessageCatalogue($locale); + + if (isset($this->resources[$locale])) { + foreach ($this->resources[$locale] as $resource) { + if (!isset($this->loaders[$resource[0]])) { + throw new \RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0])); + } + $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2])); + } + } + } + + private function loadFallbackCatalogues($locale) + { + $current = $this->catalogues[$locale]; + + foreach ($this->computeFallbackLocales($locale) as $fallback) { + if (!isset($this->catalogues[$fallback])) { + $this->doLoadCatalogue($fallback); + } + + $fallbackCatalogue = new MessageCatalogue($fallback, $this->catalogues[$fallback]->all()); + foreach ($this->catalogues[$fallback]->getResources() as $resource) { + $fallbackCatalogue->addResource($resource); + } + $current->addFallbackCatalogue($fallbackCatalogue); + $current = $fallbackCatalogue; + } + } + + protected function computeFallbackLocales($locale) + { + $locales = array(); + foreach ($this->fallbackLocales as $fallback) { + if ($fallback === $locale) { + continue; + } + + $locales[] = $fallback; + } + + if (strrchr($locale, '_') !== false) { + array_unshift($locales, substr($locale, 0, -strlen(strrchr($locale, '_')))); + } + + return array_unique($locales); + } + + /** + * Asserts that the locale is valid, throws an Exception if not. + * + * @param string $locale Locale to tests + * + * @throws \InvalidArgumentException If the locale contains invalid characters + */ + protected function assertValidLocale($locale) + { + if (1 !== preg_match('/^[a-z0-9@_\\.\\-]*$/i', $locale)) { + throw new \InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale)); + } + } + + /** + * Provides the ConfigCache factory implementation, falling back to a + * default implementation if necessary. + * + * @return ConfigCacheFactoryInterface $configCacheFactory + */ + private function getConfigCacheFactory() + { + if (!$this->configCacheFactory) { + $this->configCacheFactory = new ConfigCacheFactory($this->debug); + } + + return $this->configCacheFactory; + } +} diff --git a/public/system/storage/vendor/symfony/translation/TranslatorBagInterface.php b/public/system/storage/vendor/symfony/translation/TranslatorBagInterface.php new file mode 100644 index 0000000..14fbb17 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/TranslatorBagInterface.php @@ -0,0 +1,31 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation; + +/** + * TranslatorBagInterface. + * + * @author Abdellatif Ait boudad <a.aitboudad@gmail.com> + */ +interface TranslatorBagInterface +{ + /** + * Gets the catalogue by locale. + * + * @param string|null $locale The locale or null to use the default + * + * @return MessageCatalogueInterface + * + * @throws \InvalidArgumentException If the locale contains invalid characters + */ + public function getCatalogue($locale = null); +} diff --git a/public/system/storage/vendor/symfony/translation/TranslatorInterface.php b/public/system/storage/vendor/symfony/translation/TranslatorInterface.php new file mode 100644 index 0000000..6916c33 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/TranslatorInterface.php @@ -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; + +/** + * TranslatorInterface. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface TranslatorInterface +{ + /** + * Translates the given message. + * + * @param string $id The message id (may also be an object that can be cast to string) + * @param array $parameters An array of parameters for the message + * @param string|null $domain The domain for the message or null to use the default + * @param string|null $locale The locale or null to use the default + * + * @return string The translated string + * + * @throws \InvalidArgumentException If the locale contains invalid characters + */ + public function trans($id, array $parameters = array(), $domain = null, $locale = null); + + /** + * Translates the given choice message by choosing a translation according to a number. + * + * @param string $id The message id (may also be an object that can be cast to string) + * @param int $number The number to use to find the indice of the message + * @param array $parameters An array of parameters for the message + * @param string|null $domain The domain for the message or null to use the default + * @param string|null $locale The locale or null to use the default + * + * @return string The translated string + * + * @throws \InvalidArgumentException If the locale contains invalid characters + */ + public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null); + + /** + * Sets the current locale. + * + * @param string $locale The locale + * + * @throws \InvalidArgumentException If the locale contains invalid characters + */ + public function setLocale($locale); + + /** + * Returns the current locale. + * + * @return string The locale + */ + public function getLocale(); +} diff --git a/public/system/storage/vendor/symfony/translation/Util/ArrayConverter.php b/public/system/storage/vendor/symfony/translation/Util/ArrayConverter.php new file mode 100644 index 0000000..60a55e9 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Util/ArrayConverter.php @@ -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); + } + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/Writer/TranslationWriter.php b/public/system/storage/vendor/symfony/translation/Writer/TranslationWriter.php new file mode 100644 index 0000000..2f5eaa1 --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/Writer/TranslationWriter.php @@ -0,0 +1,89 @@ +<?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\Writer; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Dumper\DumperInterface; + +/** + * TranslationWriter writes translation messages. + * + * @author Michel Salib <michelsalib@hotmail.com> + */ +class TranslationWriter +{ + /** + * Dumpers used for export. + * + * @var array + */ + private $dumpers = array(); + + /** + * Adds a dumper to the writer. + * + * @param string $format The format of the dumper + * @param DumperInterface $dumper The dumper + */ + public function addDumper($format, DumperInterface $dumper) + { + $this->dumpers[$format] = $dumper; + } + + /** + * Disables dumper backup. + */ + public function disableBackup() + { + foreach ($this->dumpers as $dumper) { + if (method_exists($dumper, 'setBackup')) { + $dumper->setBackup(false); + } + } + } + + /** + * Obtains the list of supported formats. + * + * @return array + */ + public function getFormats() + { + return array_keys($this->dumpers); + } + + /** + * Writes translation from the catalogue according to the selected format. + * + * @param MessageCatalogue $catalogue The message catalogue to dump + * @param string $format The format to use to dump the messages + * @param array $options Options that are passed to the dumper + * + * @throws \InvalidArgumentException + */ + public function writeTranslations(MessageCatalogue $catalogue, $format, $options = array()) + { + if (!isset($this->dumpers[$format])) { + throw new \InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format)); + } + + // get the right dumper + $dumper = $this->dumpers[$format]; + + 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 + $dumper->dump($catalogue, $options); + } +} diff --git a/public/system/storage/vendor/symfony/translation/composer.json b/public/system/storage/vendor/symfony/translation/composer.json new file mode 100644 index 0000000..916cd1a --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/composer.json @@ -0,0 +1,48 @@ +{ + "name": "symfony/translation", + "type": "library", + "description": "Symfony Translation Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/config": "~2.8|~3.0", + "symfony/intl": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/config": "<2.8" + }, + "suggest": { + "symfony/config": "", + "symfony/yaml": "", + "psr/log": "To use logging capability in translator" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Translation\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + } +} diff --git a/public/system/storage/vendor/symfony/translation/phpunit.xml.dist b/public/system/storage/vendor/symfony/translation/phpunit.xml.dist new file mode 100644 index 0000000..c25ec5e --- /dev/null +++ b/public/system/storage/vendor/symfony/translation/phpunit.xml.dist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd" + backupGlobals="false" + colors="true" + bootstrap="vendor/autoload.php" +> + <php> + <ini name="error_reporting" value="-1" /> + </php> + + <testsuites> + <testsuite name="Symfony Translation Component Test Suite"> + <directory>./Tests/</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory>./</directory> + <exclude> + <directory>./Tests</directory> + <directory>./vendor</directory> + </exclude> + </whitelist> + </filter> +</phpunit> |