package and depencies
This commit is contained in:
13
vendor/symfony/translation/CHANGELOG.md
vendored
13
vendor/symfony/translation/CHANGELOG.md
vendored
@@ -1,6 +1,19 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
6.2
|
||||
---
|
||||
|
||||
* Deprecate `PhpStringTokenParser`
|
||||
* Deprecate `PhpExtractor` in favor of `PhpAstExtractor`
|
||||
* Add `PhpAstExtractor` (requires [nikic/php-parser](https://github.com/nikic/php-parser) to be installed)
|
||||
|
||||
6.1
|
||||
---
|
||||
|
||||
* Parameters implementing `TranslatableInterface` are processed
|
||||
* Add the file extension to the `XliffFileDumper` constructor
|
||||
|
||||
5.4
|
||||
---
|
||||
|
||||
|
@@ -77,10 +77,7 @@ abstract class AbstractOperation implements OperationInterface
|
||||
$this->messages = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDomains()
|
||||
public function getDomains(): array
|
||||
{
|
||||
if (null === $this->domains) {
|
||||
$domains = [];
|
||||
@@ -100,10 +97,7 @@ abstract class AbstractOperation implements OperationInterface
|
||||
return $this->domains;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMessages(string $domain)
|
||||
public function getMessages(string $domain): array
|
||||
{
|
||||
if (!\in_array($domain, $this->getDomains())) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
|
||||
@@ -116,10 +110,7 @@ abstract class AbstractOperation implements OperationInterface
|
||||
return $this->messages[$domain][self::ALL_BATCH];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNewMessages(string $domain)
|
||||
public function getNewMessages(string $domain): array
|
||||
{
|
||||
if (!\in_array($domain, $this->getDomains())) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
|
||||
@@ -132,10 +123,7 @@ abstract class AbstractOperation implements OperationInterface
|
||||
return $this->messages[$domain][self::NEW_BATCH];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getObsoleteMessages(string $domain)
|
||||
public function getObsoleteMessages(string $domain): array
|
||||
{
|
||||
if (!\in_array($domain, $this->getDomains())) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
|
||||
@@ -148,10 +136,7 @@ abstract class AbstractOperation implements OperationInterface
|
||||
return $this->messages[$domain][self::OBSOLETE_BATCH];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResult()
|
||||
public function getResult(): MessageCatalogueInterface
|
||||
{
|
||||
foreach ($this->getDomains() as $domain) {
|
||||
if (!isset($this->messages[$domain])) {
|
||||
@@ -174,12 +159,12 @@ abstract class AbstractOperation implements OperationInterface
|
||||
|
||||
foreach ($this->getDomains() as $domain) {
|
||||
$intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
|
||||
switch ($batch) {
|
||||
case self::OBSOLETE_BATCH: $messages = $this->getObsoleteMessages($domain); break;
|
||||
case self::NEW_BATCH: $messages = $this->getNewMessages($domain); break;
|
||||
case self::ALL_BATCH: $messages = $this->getMessages($domain); break;
|
||||
default: throw new \InvalidArgumentException(sprintf('$batch argument must be one of ["%s", "%s", "%s"].', self::ALL_BATCH, self::NEW_BATCH, self::OBSOLETE_BATCH));
|
||||
}
|
||||
$messages = match ($batch) {
|
||||
self::OBSOLETE_BATCH => $this->getObsoleteMessages($domain),
|
||||
self::NEW_BATCH => $this->getNewMessages($domain),
|
||||
self::ALL_BATCH => $this->getMessages($domain),
|
||||
default => throw new \InvalidArgumentException(sprintf('$batch argument must be one of ["%s", "%s", "%s"].', self::ALL_BATCH, self::NEW_BATCH, self::OBSOLETE_BATCH)),
|
||||
};
|
||||
|
||||
if (!$messages || (!$this->source->all($intlDomain) && $this->source->all($domain))) {
|
||||
continue;
|
||||
|
@@ -24,9 +24,6 @@ use Symfony\Component\Translation\MessageCatalogueInterface;
|
||||
*/
|
||||
class MergeOperation extends AbstractOperation
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processDomain(string $domain)
|
||||
{
|
||||
$this->messages[$domain] = [
|
||||
@@ -36,6 +33,18 @@ class MergeOperation extends AbstractOperation
|
||||
];
|
||||
$intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
|
||||
|
||||
foreach ($this->target->getCatalogueMetadata('', $domain) ?? [] as $key => $value) {
|
||||
if (null === $this->result->getCatalogueMetadata($key, $domain)) {
|
||||
$this->result->setCatalogueMetadata($key, $value, $domain);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->target->getCatalogueMetadata('', $intlDomain) ?? [] as $key => $value) {
|
||||
if (null === $this->result->getCatalogueMetadata($key, $intlDomain)) {
|
||||
$this->result->setCatalogueMetadata($key, $value, $intlDomain);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->source->all($domain) as $id => $message) {
|
||||
$this->messages[$domain]['all'][$id] = $message;
|
||||
$d = $this->source->defines($id, $intlDomain) ? $intlDomain : $domain;
|
||||
|
@@ -36,36 +36,26 @@ interface OperationInterface
|
||||
{
|
||||
/**
|
||||
* Returns domains affected by operation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDomains();
|
||||
public function getDomains(): array;
|
||||
|
||||
/**
|
||||
* Returns all valid messages ('all') after operation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages(string $domain);
|
||||
public function getMessages(string $domain): array;
|
||||
|
||||
/**
|
||||
* Returns new messages ('new') after operation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNewMessages(string $domain);
|
||||
public function getNewMessages(string $domain): array;
|
||||
|
||||
/**
|
||||
* Returns obsolete messages ('obsolete') after operation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getObsoleteMessages(string $domain);
|
||||
public function getObsoleteMessages(string $domain): array;
|
||||
|
||||
/**
|
||||
* Returns resulting catalogue ('result').
|
||||
*
|
||||
* @return MessageCatalogueInterface
|
||||
*/
|
||||
public function getResult();
|
||||
public function getResult(): MessageCatalogueInterface;
|
||||
}
|
||||
|
@@ -25,9 +25,6 @@ use Symfony\Component\Translation\MessageCatalogueInterface;
|
||||
*/
|
||||
class TargetOperation extends AbstractOperation
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processDomain(string $domain)
|
||||
{
|
||||
$this->messages[$domain] = [
|
||||
@@ -37,6 +34,18 @@ class TargetOperation extends AbstractOperation
|
||||
];
|
||||
$intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
|
||||
|
||||
foreach ($this->target->getCatalogueMetadata('', $domain) ?? [] as $key => $value) {
|
||||
if (null === $this->result->getCatalogueMetadata($key, $domain)) {
|
||||
$this->result->setCatalogueMetadata($key, $value, $domain);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->target->getCatalogueMetadata('', $intlDomain) ?? [] as $key => $value) {
|
||||
if (null === $this->result->getCatalogueMetadata($key, $intlDomain)) {
|
||||
$this->result->setCatalogueMetadata($key, $value, $intlDomain);
|
||||
}
|
||||
}
|
||||
|
||||
// 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}
|
||||
//
|
||||
|
44
vendor/symfony/translation/CatalogueMetadataAwareInterface.php
vendored
Normal file
44
vendor/symfony/translation/CatalogueMetadataAwareInterface.php
vendored
Normal file
@@ -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;
|
||||
|
||||
/**
|
||||
* This interface is used to get, set, and delete metadata about the Catalogue.
|
||||
*
|
||||
* @author Hugo Alliaume <hugo@alliau.me>
|
||||
*/
|
||||
interface CatalogueMetadataAwareInterface
|
||||
{
|
||||
/**
|
||||
* Gets catalogue metadata for the given domain and key.
|
||||
*
|
||||
* Passing an empty domain will return an array with all catalogue metadata indexed by
|
||||
* domain and then by key. Passing an empty key will return an array with all
|
||||
* catalogue metadata for the given domain.
|
||||
*
|
||||
* @return mixed The value that was set or an array with the domains/keys or null
|
||||
*/
|
||||
public function getCatalogueMetadata(string $key = '', string $domain = 'messages'): mixed;
|
||||
|
||||
/**
|
||||
* Adds catalogue metadata to a message domain.
|
||||
*/
|
||||
public function setCatalogueMetadata(string $key, mixed $value, string $domain = 'messages');
|
||||
|
||||
/**
|
||||
* Deletes catalogue metadata for the given key and domain.
|
||||
*
|
||||
* Passing an empty domain will delete all catalogue metadata. Passing an empty key will
|
||||
* delete all metadata for the given domain.
|
||||
*/
|
||||
public function deleteCatalogueMetadata(string $key = '', string $domain = 'messages');
|
||||
}
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Translation\Command;
|
||||
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
@@ -28,19 +29,17 @@ use Symfony\Component\Translation\Writer\TranslationWriterInterface;
|
||||
/**
|
||||
* @author Mathieu Santostefano <msantostefano@protonmail.com>
|
||||
*/
|
||||
#[AsCommand(name: 'translation:pull', description: 'Pull translations from a given provider.')]
|
||||
final class TranslationPullCommand extends Command
|
||||
{
|
||||
use TranslationTrait;
|
||||
|
||||
protected static $defaultName = 'translation:pull';
|
||||
protected static $defaultDescription = 'Pull translations from a given provider.';
|
||||
|
||||
private $providerCollection;
|
||||
private $writer;
|
||||
private $reader;
|
||||
private $defaultLocale;
|
||||
private $transPaths;
|
||||
private $enabledLocales;
|
||||
private TranslationProviderCollection $providerCollection;
|
||||
private TranslationWriterInterface $writer;
|
||||
private TranslationReaderInterface $reader;
|
||||
private string $defaultLocale;
|
||||
private array $transPaths;
|
||||
private array $enabledLocales;
|
||||
|
||||
public function __construct(TranslationProviderCollection $providerCollection, TranslationWriterInterface $writer, TranslationReaderInterface $reader, string $defaultLocale, array $transPaths = [], array $enabledLocales = [])
|
||||
{
|
||||
@@ -65,9 +64,8 @@ final class TranslationPullCommand extends Command
|
||||
if ($input->mustSuggestOptionValuesFor('domains')) {
|
||||
$provider = $this->providerCollection->get($input->getArgument('provider'));
|
||||
|
||||
if ($provider && method_exists($provider, 'getDomains')) {
|
||||
$domains = $provider->getDomains();
|
||||
$suggestions->suggestValues($domains);
|
||||
if (method_exists($provider, 'getDomains')) {
|
||||
$suggestions->suggestValues($provider->getDomains());
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -84,9 +82,6 @@ final class TranslationPullCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$keys = $this->providerCollection->keys();
|
||||
@@ -121,9 +116,6 @@ EOF
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Translation\Command;
|
||||
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
@@ -28,17 +29,15 @@ use Symfony\Component\Translation\TranslatorBag;
|
||||
/**
|
||||
* @author Mathieu Santostefano <msantostefano@protonmail.com>
|
||||
*/
|
||||
#[AsCommand(name: 'translation:push', description: 'Push translations to a given provider.')]
|
||||
final class TranslationPushCommand extends Command
|
||||
{
|
||||
use TranslationTrait;
|
||||
|
||||
protected static $defaultName = 'translation:push';
|
||||
protected static $defaultDescription = 'Push translations to a given provider.';
|
||||
|
||||
private $providers;
|
||||
private $reader;
|
||||
private $transPaths;
|
||||
private $enabledLocales;
|
||||
private TranslationProviderCollection $providers;
|
||||
private TranslationReaderInterface $reader;
|
||||
private array $transPaths;
|
||||
private array $enabledLocales;
|
||||
|
||||
public function __construct(TranslationProviderCollection $providers, TranslationReaderInterface $reader, array $transPaths = [], array $enabledLocales = [])
|
||||
{
|
||||
@@ -74,9 +73,6 @@ final class TranslationPushCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$keys = $this->providers->keys();
|
||||
@@ -114,9 +110,6 @@ EOF
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$provider = $this->providers->get($input->getArgument('provider'));
|
||||
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Translation\Command;
|
||||
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\CI\GithubActionReporter;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
@@ -31,33 +32,27 @@ use Symfony\Component\Translation\Util\XliffUtils;
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
#[AsCommand(name: 'lint:xliff', description: 'Lint an XLIFF file and outputs encountered errors')]
|
||||
class XliffLintCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'lint:xliff';
|
||||
protected static $defaultDescription = 'Lint an XLIFF file and outputs encountered errors';
|
||||
|
||||
private $format;
|
||||
private $displayCorrectFiles;
|
||||
private $directoryIteratorProvider;
|
||||
private $isReadableProvider;
|
||||
private $requireStrictFileNames;
|
||||
private string $format;
|
||||
private bool $displayCorrectFiles;
|
||||
private ?\Closure $directoryIteratorProvider;
|
||||
private ?\Closure $isReadableProvider;
|
||||
private bool $requireStrictFileNames;
|
||||
|
||||
public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true)
|
||||
{
|
||||
parent::__construct($name);
|
||||
|
||||
$this->directoryIteratorProvider = $directoryIteratorProvider;
|
||||
$this->isReadableProvider = $isReadableProvider;
|
||||
$this->directoryIteratorProvider = null === $directoryIteratorProvider ? null : $directoryIteratorProvider(...);
|
||||
$this->isReadableProvider = null === $isReadableProvider ? null : $isReadableProvider(...);
|
||||
$this->requireStrictFileNames = $requireStrictFileNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setDescription(self::$defaultDescription)
|
||||
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
|
||||
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format')
|
||||
->setHelp(<<<EOF
|
||||
@@ -82,7 +77,7 @@ EOF
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$filenames = (array) $input->getArgument('filename');
|
||||
@@ -158,16 +153,12 @@ EOF
|
||||
|
||||
private function display(SymfonyStyle $io, array $files)
|
||||
{
|
||||
switch ($this->format) {
|
||||
case 'txt':
|
||||
return $this->displayTxt($io, $files);
|
||||
case 'json':
|
||||
return $this->displayJson($io, $files);
|
||||
case 'github':
|
||||
return $this->displayTxt($io, $files, true);
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
|
||||
}
|
||||
return match ($this->format) {
|
||||
'txt' => $this->displayTxt($io, $files),
|
||||
'json' => $this->displayJson($io, $files),
|
||||
'github' => $this->displayTxt($io, $files, true),
|
||||
default => throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)),
|
||||
};
|
||||
}
|
||||
|
||||
private function displayTxt(SymfonyStyle $io, array $filesInfo, bool $errorAsGithubAnnotations = false)
|
||||
@@ -186,9 +177,7 @@ EOF
|
||||
// general document errors have a '-1' line number
|
||||
$line = -1 === $error['line'] ? null : $error['line'];
|
||||
|
||||
if ($githubReporter) {
|
||||
$githubReporter->error($error['message'], $info['file'], $line, null !== $line ? $error['column'] : null);
|
||||
}
|
||||
$githubReporter?->error($error['message'], $info['file'], $line, null !== $line ? $error['column'] : null);
|
||||
|
||||
return null === $line ? $error['message'] : sprintf('Line %d, Column %d: %s', $line, $error['column'], $error['message']);
|
||||
}, $info['messages']));
|
||||
|
@@ -25,16 +25,13 @@ use Symfony\Component\VarDumper\Cloner\Data;
|
||||
*/
|
||||
class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface
|
||||
{
|
||||
private $translator;
|
||||
private DataCollectorTranslator $translator;
|
||||
|
||||
public function __construct(DataCollectorTranslator $translator)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function lateCollect()
|
||||
{
|
||||
$messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages());
|
||||
@@ -45,27 +42,18 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto
|
||||
$this->data = $this->cloneVar($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
{
|
||||
$this->data['locale'] = $this->translator->getLocale();
|
||||
$this->data['fallback_locales'] = $this->translator->getFallbackLocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|Data
|
||||
*/
|
||||
public function getMessages()
|
||||
public function getMessages(): array|Data
|
||||
{
|
||||
return $this->data['messages'] ?? [];
|
||||
}
|
||||
@@ -98,9 +86,6 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto
|
||||
return (isset($this->data['fallback_locales']) && \count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'translation';
|
||||
|
@@ -25,8 +25,8 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
||||
public const MESSAGE_MISSING = 1;
|
||||
public const MESSAGE_EQUALS_FALLBACK = 2;
|
||||
|
||||
private $translator;
|
||||
private $messages = [];
|
||||
private TranslatorInterface $translator;
|
||||
private array $messages = [];
|
||||
|
||||
/**
|
||||
* @param TranslatorInterface&TranslatorBagInterface&LocaleAwareInterface $translator
|
||||
@@ -40,10 +40,7 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
|
||||
public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string
|
||||
{
|
||||
$trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
|
||||
$this->collectMessage($locale, $domain, $id, $trans, $parameters);
|
||||
@@ -51,44 +48,30 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
||||
return $trans;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setLocale(string $locale)
|
||||
{
|
||||
$this->translator->setLocale($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLocale()
|
||||
public function getLocale(): string
|
||||
{
|
||||
return $this->translator->getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCatalogue(string $locale = null)
|
||||
public function getCatalogue(string $locale = null): MessageCatalogueInterface
|
||||
{
|
||||
return $this->translator->getCatalogue($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCatalogues(): array
|
||||
{
|
||||
return $this->translator->getCatalogues();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function warmUp(string $cacheDir)
|
||||
public function warmUp(string $cacheDir): array
|
||||
{
|
||||
if ($this->translator instanceof WarmableInterface) {
|
||||
return (array) $this->translator->warmUp($cacheDir);
|
||||
@@ -99,10 +82,8 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
||||
|
||||
/**
|
||||
* Gets the fallback locales.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFallbackLocales()
|
||||
public function getFallbackLocales(): array
|
||||
{
|
||||
if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
|
||||
return $this->translator->getFallbackLocales();
|
||||
@@ -119,19 +100,14 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
|
||||
return $this->translator->{$method}(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCollectedMessages()
|
||||
public function getCollectedMessages(): array
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
private function collectMessage(?string $locale, ?string $domain, string $id, string $translation, ?array $parameters = [])
|
||||
{
|
||||
if (null === $domain) {
|
||||
$domain = 'messages';
|
||||
}
|
||||
$domain ??= 'messages';
|
||||
|
||||
$catalogue = $this->translator->getCatalogue($locale);
|
||||
$locale = $catalogue->getLocale();
|
||||
|
@@ -20,28 +20,15 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*/
|
||||
class TranslationDumperPass implements CompilerPassInterface
|
||||
{
|
||||
private $writerServiceId;
|
||||
private $dumperTag;
|
||||
|
||||
public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper')
|
||||
{
|
||||
if (1 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->writerServiceId = $writerServiceId;
|
||||
$this->dumperTag = $dumperTag;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->writerServiceId)) {
|
||||
if (!$container->hasDefinition('translation.writer')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition($this->writerServiceId);
|
||||
$definition = $container->getDefinition('translation.writer');
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->dumperTag, true) as $id => $attributes) {
|
||||
foreach ($container->findTaggedServiceIds('translation.dumper', true) as $id => $attributes) {
|
||||
$definition->addMethodCall('addDumper', [$attributes[0]['alias'], new Reference($id)]);
|
||||
}
|
||||
}
|
||||
|
@@ -21,28 +21,15 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*/
|
||||
class TranslationExtractorPass implements CompilerPassInterface
|
||||
{
|
||||
private $extractorServiceId;
|
||||
private $extractorTag;
|
||||
|
||||
public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->extractorServiceId = $extractorServiceId;
|
||||
$this->extractorTag = $extractorTag;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->extractorServiceId)) {
|
||||
if (!$container->hasDefinition('translation.extractor')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition($this->extractorServiceId);
|
||||
$definition = $container->getDefinition('translation.extractor');
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->extractorTag, true) as $id => $attributes) {
|
||||
foreach ($container->findTaggedServiceIds('translation.extractor', true) as $id => $attributes) {
|
||||
if (!isset($attributes[0]['alias'])) {
|
||||
throw new RuntimeException(sprintf('The alias for the tag "translation.extractor" of service "%s" must be set.', $id));
|
||||
}
|
||||
|
@@ -18,34 +18,15 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
class TranslatorPass implements CompilerPassInterface
|
||||
{
|
||||
private $translatorServiceId;
|
||||
private $readerServiceId;
|
||||
private $loaderTag;
|
||||
private $debugCommandServiceId;
|
||||
private $updateCommandServiceId;
|
||||
|
||||
public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_extract')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->translatorServiceId = $translatorServiceId;
|
||||
$this->readerServiceId = $readerServiceId;
|
||||
$this->loaderTag = $loaderTag;
|
||||
$this->debugCommandServiceId = $debugCommandServiceId;
|
||||
$this->updateCommandServiceId = $updateCommandServiceId;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->translatorServiceId)) {
|
||||
if (!$container->hasDefinition('translator.default')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$loaders = [];
|
||||
$loaderRefs = [];
|
||||
foreach ($container->findTaggedServiceIds($this->loaderTag, true) as $id => $attributes) {
|
||||
foreach ($container->findTaggedServiceIds('translation.loader', true) as $id => $attributes) {
|
||||
$loaderRefs[$id] = new Reference($id);
|
||||
$loaders[$id][] = $attributes[0]['alias'];
|
||||
if (isset($attributes[0]['legacy-alias'])) {
|
||||
@@ -53,8 +34,8 @@ class TranslatorPass implements CompilerPassInterface
|
||||
}
|
||||
}
|
||||
|
||||
if ($container->hasDefinition($this->readerServiceId)) {
|
||||
$definition = $container->getDefinition($this->readerServiceId);
|
||||
if ($container->hasDefinition('translation.reader')) {
|
||||
$definition = $container->getDefinition('translation.reader');
|
||||
foreach ($loaders as $id => $formats) {
|
||||
foreach ($formats as $format) {
|
||||
$definition->addMethodCall('addLoader', [$format, $loaderRefs[$id]]);
|
||||
@@ -63,26 +44,39 @@ class TranslatorPass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
$container
|
||||
->findDefinition($this->translatorServiceId)
|
||||
->findDefinition('translator.default')
|
||||
->replaceArgument(0, ServiceLocatorTagPass::register($container, $loaderRefs))
|
||||
->replaceArgument(3, $loaders)
|
||||
;
|
||||
|
||||
if ($container->hasDefinition('validator') && $container->hasDefinition('translation.extractor.visitor.constraint')) {
|
||||
$constraintVisitorDefinition = $container->getDefinition('translation.extractor.visitor.constraint');
|
||||
$constraintClassNames = [];
|
||||
|
||||
foreach ($container->findTaggedServiceIds('validator.constraint_validator', true) as $id => $attributes) {
|
||||
$serviceDefinition = $container->getDefinition($id);
|
||||
// Extraction of the constraint class name from the Constraint Validator FQCN
|
||||
$constraintClassNames[] = str_replace('Validator', '', substr(strrchr($serviceDefinition->getClass(), '\\'), 1));
|
||||
}
|
||||
|
||||
$constraintVisitorDefinition->setArgument(0, $constraintClassNames);
|
||||
}
|
||||
|
||||
if (!$container->hasParameter('twig.default_path')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$paths = array_keys($container->getDefinition('twig.template_iterator')->getArgument(1));
|
||||
if ($container->hasDefinition($this->debugCommandServiceId)) {
|
||||
$definition = $container->getDefinition($this->debugCommandServiceId);
|
||||
if ($container->hasDefinition('console.command.translation_debug')) {
|
||||
$definition = $container->getDefinition('console.command.translation_debug');
|
||||
$definition->replaceArgument(4, $container->getParameter('twig.default_path'));
|
||||
|
||||
if (\count($definition->getArguments()) > 6) {
|
||||
$definition->replaceArgument(6, $paths);
|
||||
}
|
||||
}
|
||||
if ($container->hasDefinition($this->updateCommandServiceId)) {
|
||||
$definition = $container->getDefinition($this->updateCommandServiceId);
|
||||
if ($container->hasDefinition('console.command.translation_extract')) {
|
||||
$definition = $container->getDefinition('console.command.translation_extract');
|
||||
$definition->replaceArgument(5, $container->getParameter('twig.default_path'));
|
||||
|
||||
if (\count($definition->getArguments()) > 7) {
|
||||
|
@@ -22,42 +22,26 @@ use Symfony\Component\DependencyInjection\ServiceLocator;
|
||||
*/
|
||||
class TranslatorPathsPass extends AbstractRecursivePass
|
||||
{
|
||||
private $translatorServiceId;
|
||||
private $debugCommandServiceId;
|
||||
private $updateCommandServiceId;
|
||||
private $resolverServiceId;
|
||||
private $level = 0;
|
||||
private int $level = 0;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $paths = [];
|
||||
private array $paths = [];
|
||||
|
||||
/**
|
||||
* @var array<int, Definition>
|
||||
*/
|
||||
private $definitions = [];
|
||||
private array $definitions = [];
|
||||
|
||||
/**
|
||||
* @var array<string, array<string, bool>>
|
||||
*/
|
||||
private $controllers = [];
|
||||
|
||||
public function __construct(string $translatorServiceId = 'translator', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_extract', string $resolverServiceId = 'argument_resolver.service')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->translatorServiceId = $translatorServiceId;
|
||||
$this->debugCommandServiceId = $debugCommandServiceId;
|
||||
$this->updateCommandServiceId = $updateCommandServiceId;
|
||||
$this->resolverServiceId = $resolverServiceId;
|
||||
}
|
||||
private array $controllers = [];
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->translatorServiceId)) {
|
||||
if (!$container->hasDefinition('translator')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -82,12 +66,12 @@ class TranslatorPathsPass extends AbstractRecursivePass
|
||||
}
|
||||
}
|
||||
if ($paths) {
|
||||
if ($container->hasDefinition($this->debugCommandServiceId)) {
|
||||
$definition = $container->getDefinition($this->debugCommandServiceId);
|
||||
if ($container->hasDefinition('console.command.translation_debug')) {
|
||||
$definition = $container->getDefinition('console.command.translation_debug');
|
||||
$definition->replaceArgument(6, array_merge($definition->getArgument(6), $paths));
|
||||
}
|
||||
if ($container->hasDefinition($this->updateCommandServiceId)) {
|
||||
$definition = $container->getDefinition($this->updateCommandServiceId);
|
||||
if ($container->hasDefinition('console.command.translation_extract')) {
|
||||
$definition = $container->getDefinition('console.command.translation_extract');
|
||||
$definition->replaceArgument(7, array_merge($definition->getArgument(7), $paths));
|
||||
}
|
||||
}
|
||||
@@ -98,10 +82,10 @@ class TranslatorPathsPass extends AbstractRecursivePass
|
||||
}
|
||||
}
|
||||
|
||||
protected function processValue($value, bool $isRoot = false)
|
||||
protected function processValue(mixed $value, bool $isRoot = false): mixed
|
||||
{
|
||||
if ($value instanceof Reference) {
|
||||
if ((string) $value === $this->translatorServiceId) {
|
||||
if ('translator' === (string) $value) {
|
||||
for ($i = $this->level - 1; $i >= 0; --$i) {
|
||||
$class = $this->definitions[$i]->getClass();
|
||||
|
||||
@@ -136,8 +120,8 @@ class TranslatorPathsPass extends AbstractRecursivePass
|
||||
|
||||
private function findControllerArguments(ContainerBuilder $container): array
|
||||
{
|
||||
if ($container->hasDefinition($this->resolverServiceId)) {
|
||||
$argument = $container->getDefinition($this->resolverServiceId)->getArgument(0);
|
||||
if ($container->hasDefinition('argument_resolver.service')) {
|
||||
$argument = $container->getDefinition('argument_resolver.service')->getArgument(0);
|
||||
if ($argument instanceof Reference) {
|
||||
$argument = $container->getDefinition($argument);
|
||||
}
|
||||
@@ -145,8 +129,8 @@ class TranslatorPathsPass extends AbstractRecursivePass
|
||||
return $argument->getArgument(0);
|
||||
}
|
||||
|
||||
if ($container->hasDefinition('debug.'.$this->resolverServiceId)) {
|
||||
$argument = $container->getDefinition('debug.'.$this->resolverServiceId)->getArgument(0);
|
||||
if ($container->hasDefinition('debug.'.'argument_resolver.service')) {
|
||||
$argument = $container->getDefinition('debug.'.'argument_resolver.service')->getArgument(0);
|
||||
if ($argument instanceof Reference) {
|
||||
$argument = $container->getDefinition($argument);
|
||||
}
|
||||
|
@@ -20,13 +20,10 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class CsvFileDumper extends FileDumper
|
||||
{
|
||||
private $delimiter = ';';
|
||||
private $enclosure = '"';
|
||||
private string $delimiter = ';';
|
||||
private string $enclosure = '"';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
$handle = fopen('php://memory', 'r+');
|
||||
|
||||
@@ -50,10 +47,7 @@ class CsvFileDumper extends FileDumper
|
||||
$this->enclosure = $enclosure;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'csv';
|
||||
}
|
||||
|
11
vendor/symfony/translation/Dumper/FileDumper.php
vendored
11
vendor/symfony/translation/Dumper/FileDumper.php
vendored
@@ -42,9 +42,6 @@ abstract class FileDumper implements DumperInterface
|
||||
$this->relativePathTemplate = $relativePathTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dump(MessageCatalogue $messages, array $options = [])
|
||||
{
|
||||
if (!\array_key_exists('path', $options)) {
|
||||
@@ -86,17 +83,13 @@ abstract class FileDumper implements DumperInterface
|
||||
|
||||
/**
|
||||
* Transforms a domain of a message catalogue to its string representation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []);
|
||||
abstract public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string;
|
||||
|
||||
/**
|
||||
* Gets the file extension of the dumper.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getExtension();
|
||||
abstract protected function getExtension(): string;
|
||||
|
||||
/**
|
||||
* Gets the relative file path using the template.
|
||||
|
@@ -20,15 +20,9 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class IcuResFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $relativePathTemplate = '%domain%/%locale%.%extension%';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
$data = $indexes = $resources = '';
|
||||
|
||||
@@ -94,10 +88,7 @@ class IcuResFileDumper extends FileDumper
|
||||
return (\strlen($data) + 28) / 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'res';
|
||||
}
|
||||
|
@@ -20,10 +20,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class IniFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
$output = '';
|
||||
|
||||
@@ -35,10 +32,7 @@ class IniFileDumper extends FileDumper
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'ini';
|
||||
}
|
||||
|
@@ -20,20 +20,14 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class JsonFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
$flags = $options['json_encoding'] ?? \JSON_PRETTY_PRINT;
|
||||
|
||||
return json_encode($messages->all($domain), $flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'json';
|
||||
}
|
||||
|
@@ -21,10 +21,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class MoFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
$sources = $targets = $sourceOffsets = $targetOffsets = '';
|
||||
$offsets = [];
|
||||
@@ -57,7 +54,7 @@ class MoFileDumper extends FileDumper
|
||||
.$this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
|
||||
}
|
||||
|
||||
$output = implode('', array_map([$this, 'writeLong'], $header))
|
||||
$output = implode('', array_map($this->writeLong(...), $header))
|
||||
.$sourceOffsets
|
||||
.$targetOffsets
|
||||
.$sources
|
||||
@@ -67,15 +64,12 @@ class MoFileDumper extends FileDumper
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'mo';
|
||||
}
|
||||
|
||||
private function writeLong($str): string
|
||||
private function writeLong(mixed $str): string
|
||||
{
|
||||
return pack('V*', $str);
|
||||
}
|
||||
|
@@ -20,18 +20,12 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class PhpFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
return "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'php';
|
||||
}
|
||||
|
@@ -20,10 +20,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class PoFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
$output = 'msgid ""'."\n";
|
||||
$output .= 'msgstr ""'."\n";
|
||||
@@ -111,10 +108,7 @@ EOF;
|
||||
return $standardRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'po';
|
||||
}
|
||||
@@ -124,7 +118,7 @@ EOF;
|
||||
return addcslashes($str, "\0..\37\42\134");
|
||||
}
|
||||
|
||||
private function formatComments($comments, string $prefix = ''): ?string
|
||||
private function formatComments(string|array $comments, string $prefix = ''): ?string
|
||||
{
|
||||
$output = null;
|
||||
|
||||
|
@@ -20,10 +20,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class QtFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->formatOutput = true;
|
||||
@@ -51,10 +48,7 @@ class QtFileDumper extends FileDumper
|
||||
return $dom->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'ts';
|
||||
}
|
||||
|
@@ -21,10 +21,12 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class XliffFileDumper extends FileDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function __construct(
|
||||
private string $extension = 'xlf',
|
||||
) {
|
||||
}
|
||||
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
$xliffVersion = '1.2';
|
||||
if (\array_key_exists('xliff_version', $options)) {
|
||||
@@ -47,12 +49,9 @@ class XliffFileDumper extends FileDumper
|
||||
throw new InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return 'xlf';
|
||||
return $this->extension;
|
||||
}
|
||||
|
||||
private function dumpXliff1(string $defaultLocale, MessageCatalogue $messages, ?string $domain, array $options = [])
|
||||
@@ -81,6 +80,15 @@ class XliffFileDumper extends FileDumper
|
||||
$xliffTool->setAttribute($id, $value);
|
||||
}
|
||||
|
||||
if ($catalogueMetadata = $messages->getCatalogueMetadata('', $domain) ?? []) {
|
||||
$xliffPropGroup = $xliffHead->appendChild($dom->createElement('prop-group'));
|
||||
foreach ($catalogueMetadata as $key => $value) {
|
||||
$xliffProp = $xliffPropGroup->appendChild($dom->createElement('prop'));
|
||||
$xliffProp->setAttribute('prop-type', $key);
|
||||
$xliffProp->appendChild($dom->createTextNode($value));
|
||||
}
|
||||
}
|
||||
|
||||
$xliffBody = $xliffFile->appendChild($dom->createElement('body'));
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$translation = $dom->createElement('trans-unit');
|
||||
@@ -147,6 +155,16 @@ class XliffFileDumper extends FileDumper
|
||||
$xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
|
||||
}
|
||||
|
||||
if ($catalogueMetadata = $messages->getCatalogueMetadata('', $domain) ?? []) {
|
||||
$xliff->setAttribute('xmlns:m', 'urn:oasis:names:tc:xliff:metadata:2.0');
|
||||
$xliffMetadata = $xliffFile->appendChild($dom->createElement('m:metadata'));
|
||||
foreach ($catalogueMetadata as $key => $value) {
|
||||
$xliffMeta = $xliffMetadata->appendChild($dom->createElement('prop'));
|
||||
$xliffMeta->setAttribute('type', $key);
|
||||
$xliffMeta->appendChild($dom->createTextNode($value));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$translation = $dom->createElement('unit');
|
||||
$translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
|
||||
|
@@ -23,17 +23,14 @@ use Symfony\Component\Yaml\Yaml;
|
||||
*/
|
||||
class YamlFileDumper extends FileDumper
|
||||
{
|
||||
private $extension;
|
||||
private string $extension;
|
||||
|
||||
public function __construct(string $extension = 'yml')
|
||||
{
|
||||
$this->extension = $extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
|
||||
{
|
||||
if (!class_exists(Yaml::class)) {
|
||||
throw new LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.');
|
||||
@@ -52,10 +49,7 @@ class YamlFileDumper extends FileDumper
|
||||
return Yaml::dump($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExtension()
|
||||
protected function getExtension(): string
|
||||
{
|
||||
return $this->extension;
|
||||
}
|
||||
|
@@ -18,8 +18,8 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
*/
|
||||
class ProviderException extends RuntimeException implements ProviderExceptionInterface
|
||||
{
|
||||
private $response;
|
||||
private $debug;
|
||||
private ResponseInterface $response;
|
||||
private string $debug;
|
||||
|
||||
public function __construct(string $message, ResponseInterface $response, int $code = 0, \Exception $previous = null)
|
||||
{
|
||||
|
@@ -20,12 +20,7 @@ use Symfony\Component\Translation\Exception\InvalidArgumentException;
|
||||
*/
|
||||
abstract class AbstractFileExtractor
|
||||
{
|
||||
/**
|
||||
* @param string|iterable $resource Files, a file or a directory
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
protected function extractFiles($resource)
|
||||
protected function extractFiles(string|iterable $resource): iterable
|
||||
{
|
||||
if (is_iterable($resource)) {
|
||||
$files = [];
|
||||
@@ -49,11 +44,9 @@ abstract class AbstractFileExtractor
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function isFile(string $file)
|
||||
protected function isFile(string $file): bool
|
||||
{
|
||||
if (!is_file($file)) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" file does not exist.', $file));
|
||||
@@ -68,9 +61,7 @@ abstract class AbstractFileExtractor
|
||||
abstract protected function canBeExtracted(string $file);
|
||||
|
||||
/**
|
||||
* @param string|array $resource Files, a file or a directory
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
abstract protected function extractFromDirectory($resource);
|
||||
abstract protected function extractFromDirectory(string|array $resource);
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ class ChainExtractor implements ExtractorInterface
|
||||
*
|
||||
* @var ExtractorInterface[]
|
||||
*/
|
||||
private $extractors = [];
|
||||
private array $extractors = [];
|
||||
|
||||
/**
|
||||
* Adds a loader to the translation extractor.
|
||||
@@ -35,9 +35,6 @@ class ChainExtractor implements ExtractorInterface
|
||||
$this->extractors[$format] = $extractor;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPrefix(string $prefix)
|
||||
{
|
||||
foreach ($this->extractors as $extractor) {
|
||||
@@ -45,10 +42,7 @@ class ChainExtractor implements ExtractorInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function extract($directory, MessageCatalogue $catalogue)
|
||||
public function extract(string|iterable $directory, MessageCatalogue $catalogue)
|
||||
{
|
||||
foreach ($this->extractors as $extractor) {
|
||||
$extractor->extract($directory, $catalogue);
|
||||
|
@@ -26,7 +26,7 @@ interface ExtractorInterface
|
||||
*
|
||||
* @param string|iterable<string> $resource Files, a file or a directory
|
||||
*/
|
||||
public function extract($resource, MessageCatalogue $catalogue);
|
||||
public function extract(string|iterable $resource, MessageCatalogue $catalogue);
|
||||
|
||||
/**
|
||||
* Sets the prefix that should be used for new found messages.
|
||||
|
78
vendor/symfony/translation/Extractor/PhpAstExtractor.php
vendored
Normal file
78
vendor/symfony/translation/Extractor/PhpAstExtractor.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?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 PhpParser\NodeTraverser;
|
||||
use PhpParser\NodeVisitor;
|
||||
use PhpParser\Parser;
|
||||
use PhpParser\ParserFactory;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Translation\Extractor\Visitor\AbstractVisitor;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
|
||||
/**
|
||||
* PhpAstExtractor extracts translation messages from a PHP AST.
|
||||
*
|
||||
* @author Mathieu Santostefano <msantostefano@protonmail.com>
|
||||
*/
|
||||
final class PhpAstExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
{
|
||||
private Parser $parser;
|
||||
|
||||
public function __construct(
|
||||
/**
|
||||
* @param iterable<AbstractVisitor&NodeVisitor> $visitors
|
||||
*/
|
||||
private readonly iterable $visitors,
|
||||
private string $prefix = '',
|
||||
) {
|
||||
if (!class_exists(ParserFactory::class)) {
|
||||
throw new \LogicException(sprintf('You cannot use "%s" as the "nikic/php-parser" package is not installed. Try running "composer require nikic/php-parser".', static::class));
|
||||
}
|
||||
|
||||
$this->parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
|
||||
}
|
||||
|
||||
public function extract(iterable|string $resource, MessageCatalogue $catalogue): void
|
||||
{
|
||||
foreach ($this->extractFiles($resource) as $file) {
|
||||
$traverser = new NodeTraverser();
|
||||
/** @var AbstractVisitor&NodeVisitor $visitor */
|
||||
foreach ($this->visitors as $visitor) {
|
||||
$visitor->initialize($catalogue, $file, $this->prefix);
|
||||
$traverser->addVisitor($visitor);
|
||||
}
|
||||
|
||||
$nodes = $this->parser->parse(file_get_contents($file));
|
||||
$traverser->traverse($nodes);
|
||||
}
|
||||
}
|
||||
|
||||
public function setPrefix(string $prefix): void
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
protected function canBeExtracted(string $file): bool
|
||||
{
|
||||
return 'php' === pathinfo($file, \PATHINFO_EXTENSION) && $this->isFile($file);
|
||||
}
|
||||
|
||||
protected function extractFromDirectory(array|string $resource): iterable|Finder
|
||||
{
|
||||
if (!class_exists(Finder::class)) {
|
||||
throw new \LogicException(sprintf('You cannot use "%s" as the "symfony/finder" package is not installed. Try running "composer require symfony/finder".', static::class));
|
||||
}
|
||||
|
||||
return (new Finder())->files()->name('*.php')->in($resource);
|
||||
}
|
||||
}
|
@@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\Translation\Extractor;
|
||||
|
||||
trigger_deprecation('symfony/translation', '6.2', '"%s" is deprecated, use "%s" instead.', PhpExtractor::class, PhpAstExtractor::class);
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
|
||||
@@ -18,6 +20,8 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
* PhpExtractor extracts translation messages from a PHP template.
|
||||
*
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
*
|
||||
* @deprecated since Symfony 6.2, use the PhpAstExtractor instead
|
||||
*/
|
||||
class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
{
|
||||
@@ -28,7 +32,7 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
/**
|
||||
* Prefix for new found message.
|
||||
*/
|
||||
private $prefix = '';
|
||||
private string $prefix = '';
|
||||
|
||||
/**
|
||||
* The sequence that captures translation messages.
|
||||
@@ -128,10 +132,7 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function extract($resource, MessageCatalogue $catalog)
|
||||
public function extract(string|iterable $resource, MessageCatalogue $catalog)
|
||||
{
|
||||
$files = $this->extractFiles($resource);
|
||||
foreach ($files as $file) {
|
||||
@@ -141,9 +142,6 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPrefix(string $prefix)
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
@@ -151,12 +149,8 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
|
||||
/**
|
||||
* Normalizes a token.
|
||||
*
|
||||
* @param mixed $token
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function normalizeToken($token)
|
||||
protected function normalizeToken(mixed $token): ?string
|
||||
{
|
||||
if (isset($token[1]) && 'b"' !== $token) {
|
||||
return $token[1];
|
||||
@@ -311,19 +305,14 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function canBeExtracted(string $file)
|
||||
protected function canBeExtracted(string $file): bool
|
||||
{
|
||||
return $this->isFile($file) && 'php' === pathinfo($file, \PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function extractFromDirectory($directory)
|
||||
protected function extractFromDirectory(string|array $directory): iterable
|
||||
{
|
||||
if (!class_exists(Finder::class)) {
|
||||
throw new \LogicException(sprintf('You cannot use "%s" as the "symfony/finder" package is not installed. Try running "composer require symfony/finder".', static::class));
|
||||
|
@@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\Translation\Extractor;
|
||||
|
||||
trigger_deprecation('symfony/translation', '6.2', '"%s" is deprecated.', PhpStringTokenParser::class);
|
||||
|
||||
/*
|
||||
* The following is derived from code at http://github.com/nikic/PHP-Parser
|
||||
*
|
||||
@@ -47,6 +49,9 @@ namespace Symfony\Component\Translation\Extractor;
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 6.2
|
||||
*/
|
||||
class PhpStringTokenParser
|
||||
{
|
||||
protected static $replacements = [
|
||||
@@ -64,10 +69,8 @@ class PhpStringTokenParser
|
||||
* Parses a string token.
|
||||
*
|
||||
* @param string $str String token content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function parse(string $str)
|
||||
public static function parse(string $str): string
|
||||
{
|
||||
$bLength = 0;
|
||||
if ('b' === $str[0]) {
|
||||
@@ -90,10 +93,8 @@ class PhpStringTokenParser
|
||||
*
|
||||
* @param string $str String without quotes
|
||||
* @param string|null $quote Quote type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function parseEscapeSequences(string $str, string $quote = null)
|
||||
public static function parseEscapeSequences(string $str, string $quote = null): string
|
||||
{
|
||||
if (null !== $quote) {
|
||||
$str = str_replace('\\'.$quote, $quote, $str);
|
||||
@@ -124,10 +125,8 @@ class PhpStringTokenParser
|
||||
*
|
||||
* @param string $startToken Doc string start token content (<<<SMTHG)
|
||||
* @param string $str String token content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function parseDocString(string $startToken, string $str)
|
||||
public static function parseDocString(string $startToken, string $str): string
|
||||
{
|
||||
// strip last newline (thanks tokenizer for sticking it into the string!)
|
||||
$str = preg_replace('~(\r\n|\n|\r)$~', '', $str);
|
||||
|
111
vendor/symfony/translation/Extractor/Visitor/AbstractVisitor.php
vendored
Normal file
111
vendor/symfony/translation/Extractor/Visitor/AbstractVisitor.php
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
<?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\Visitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
|
||||
/**
|
||||
* @author Mathieu Santostefano <msantostefano@protonmail.com>
|
||||
*/
|
||||
abstract class AbstractVisitor
|
||||
{
|
||||
private MessageCatalogue $catalogue;
|
||||
private \SplFileInfo $file;
|
||||
private string $messagePrefix;
|
||||
|
||||
public function initialize(MessageCatalogue $catalogue, \SplFileInfo $file, string $messagePrefix): void
|
||||
{
|
||||
$this->catalogue = $catalogue;
|
||||
$this->file = $file;
|
||||
$this->messagePrefix = $messagePrefix;
|
||||
}
|
||||
|
||||
protected function addMessageToCatalogue(string $message, ?string $domain, int $line): void
|
||||
{
|
||||
$domain ??= 'messages';
|
||||
$this->catalogue->set($message, $this->messagePrefix.$message, $domain);
|
||||
$metadata = $this->catalogue->getMetadata($message, $domain) ?? [];
|
||||
$normalizedFilename = preg_replace('{[\\\\/]+}', '/', $this->file);
|
||||
$metadata['sources'][] = $normalizedFilename.':'.$line;
|
||||
$this->catalogue->setMetadata($message, $metadata, $domain);
|
||||
}
|
||||
|
||||
protected function getStringArguments(Node\Expr\CallLike|Node\Attribute|Node\Expr\New_ $node, int|string $index, bool $indexIsRegex = false): array
|
||||
{
|
||||
if (\is_string($index)) {
|
||||
return $this->getStringNamedArguments($node, $index, $indexIsRegex);
|
||||
}
|
||||
|
||||
$args = $node instanceof Node\Expr\CallLike ? $node->getRawArgs() : $node->args;
|
||||
|
||||
if (!($arg = $args[$index] ?? null) instanceof Node\Arg) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return (array) $this->getStringValue($arg->value);
|
||||
}
|
||||
|
||||
protected function hasNodeNamedArguments(Node\Expr\CallLike|Node\Attribute|Node\Expr\New_ $node): bool
|
||||
{
|
||||
$args = $node instanceof Node\Expr\CallLike ? $node->getRawArgs() : $node->args;
|
||||
|
||||
foreach ($args as $arg) {
|
||||
if ($arg instanceof Node\Arg && null !== $arg->name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getStringNamedArguments(Node\Expr\CallLike|Node\Attribute $node, string $argumentName = null, bool $isArgumentNamePattern = false): array
|
||||
{
|
||||
$args = $node instanceof Node\Expr\CallLike ? $node->getArgs() : $node->args;
|
||||
$argumentValues = [];
|
||||
|
||||
foreach ($args as $arg) {
|
||||
if (!$isArgumentNamePattern && $arg->name?->toString() === $argumentName) {
|
||||
$argumentValues[] = $this->getStringValue($arg->value);
|
||||
} elseif ($isArgumentNamePattern && preg_match($argumentName, $arg->name?->toString() ?? '') > 0) {
|
||||
$argumentValues[] = $this->getStringValue($arg->value);
|
||||
}
|
||||
}
|
||||
|
||||
return array_filter($argumentValues);
|
||||
}
|
||||
|
||||
private function getStringValue(Node $node): ?string
|
||||
{
|
||||
if ($node instanceof Node\Scalar\String_) {
|
||||
return $node->value;
|
||||
}
|
||||
|
||||
if ($node instanceof Node\Expr\BinaryOp\Concat) {
|
||||
if (null === $left = $this->getStringValue($node->left)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (null === $right = $this->getStringValue($node->right)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $left.$right;
|
||||
}
|
||||
|
||||
if ($node instanceof Node\Expr\Assign && $node->expr instanceof Node\Scalar\String_) {
|
||||
return $node->expr->value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
114
vendor/symfony/translation/Extractor/Visitor/ConstraintVisitor.php
vendored
Normal file
114
vendor/symfony/translation/Extractor/Visitor/ConstraintVisitor.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?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\Visitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeVisitor;
|
||||
|
||||
/**
|
||||
* @author Mathieu Santostefano <msantostefano@protonmail.com>
|
||||
*
|
||||
* Code mostly comes from https://github.com/php-translation/extractor/blob/master/src/Visitor/Php/Symfony/Constraint.php
|
||||
*/
|
||||
final class ConstraintVisitor extends AbstractVisitor implements NodeVisitor
|
||||
{
|
||||
private const CONSTRAINT_VALIDATION_MESSAGE_PATTERN = '/[a-zA-Z]*message/i';
|
||||
|
||||
public function __construct(
|
||||
private readonly array $constraintClassNames = []
|
||||
) {
|
||||
}
|
||||
|
||||
public function beforeTraverse(array $nodes): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function enterNode(Node $node): ?Node
|
||||
{
|
||||
if (!$node instanceof Node\Expr\New_ && !$node instanceof Node\Attribute) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$className = $node instanceof Node\Attribute ? $node->name : $node->class;
|
||||
if (!$className instanceof Node\Name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parts = $className->parts;
|
||||
$isConstraintClass = false;
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if (\in_array($part, $this->constraintClassNames, true)) {
|
||||
$isConstraintClass = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isConstraintClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$arg = $node->args[0] ?? null;
|
||||
if (!$arg instanceof Node\Arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->hasNodeNamedArguments($node)) {
|
||||
$messages = $this->getStringArguments($node, self::CONSTRAINT_VALIDATION_MESSAGE_PATTERN, true);
|
||||
} else {
|
||||
if (!$arg->value instanceof Node\Expr\Array_) {
|
||||
// There is no way to guess which argument is a message to be translated.
|
||||
return null;
|
||||
}
|
||||
|
||||
$messages = [];
|
||||
$options = $arg->value;
|
||||
|
||||
/** @var Node\Expr\ArrayItem $item */
|
||||
foreach ($options->items as $item) {
|
||||
if (!$item->key instanceof Node\Scalar\String_) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!preg_match(self::CONSTRAINT_VALIDATION_MESSAGE_PATTERN, $item->key->value ?? '')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$item->value instanceof Node\Scalar\String_) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$messages[] = $item->value->value;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$this->addMessageToCatalogue($message, 'validators', $node->getStartLine());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function leaveNode(Node $node): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function afterTraverse(array $nodes): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
64
vendor/symfony/translation/Extractor/Visitor/TransMethodVisitor.php
vendored
Normal file
64
vendor/symfony/translation/Extractor/Visitor/TransMethodVisitor.php
vendored
Normal file
@@ -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\Extractor\Visitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeVisitor;
|
||||
|
||||
/**
|
||||
* @author Mathieu Santostefano <msantostefano@protonmail.com>
|
||||
*/
|
||||
final class TransMethodVisitor extends AbstractVisitor implements NodeVisitor
|
||||
{
|
||||
public function beforeTraverse(array $nodes): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function enterNode(Node $node): ?Node
|
||||
{
|
||||
if (!$node instanceof Node\Expr\MethodCall && !$node instanceof Node\Expr\FuncCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!\is_string($node->name) && !$node->name instanceof Node\Identifier && !$node->name instanceof Node\Name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$name = (string) $node->name;
|
||||
|
||||
if ('trans' === $name || 't' === $name) {
|
||||
$nodeHasNamedArguments = $this->hasNodeNamedArguments($node);
|
||||
if (!$messages = $this->getStringArguments($node, $nodeHasNamedArguments ? 'message' : 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$domain = $this->getStringArguments($node, $nodeHasNamedArguments ? 'domain' : 2)[0] ?? null;
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$this->addMessageToCatalogue($message, $domain, $node->getStartLine());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function leaveNode(Node $node): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function afterTraverse(array $nodes): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
65
vendor/symfony/translation/Extractor/Visitor/TranslatableMessageVisitor.php
vendored
Normal file
65
vendor/symfony/translation/Extractor/Visitor/TranslatableMessageVisitor.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Translation\Extractor\Visitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeVisitor;
|
||||
|
||||
/**
|
||||
* @author Mathieu Santostefano <msantostefano@protonmail.com>
|
||||
*/
|
||||
final class TranslatableMessageVisitor extends AbstractVisitor implements NodeVisitor
|
||||
{
|
||||
public function beforeTraverse(array $nodes): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function enterNode(Node $node): ?Node
|
||||
{
|
||||
if (!$node instanceof Node\Expr\New_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!($className = $node->class) instanceof Node\Name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!\in_array('TranslatableMessage', $className->parts, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$nodeHasNamedArguments = $this->hasNodeNamedArguments($node);
|
||||
|
||||
if (!$messages = $this->getStringArguments($node, $nodeHasNamedArguments ? 'message' : 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$domain = $this->getStringArguments($node, $nodeHasNamedArguments ? 'domain' : 2)[0] ?? null;
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$this->addMessageToCatalogue($message, $domain, $node->getStartLine());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function leaveNode(Node $node): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function afterTraverse(array $nodes): ?Node
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -23,9 +23,6 @@ class IntlFormatter implements IntlFormatterInterface
|
||||
private $hasMessageFormatter;
|
||||
private $cache = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatIntl(string $message, string $locale, array $parameters = []): string
|
||||
{
|
||||
// MessageFormatter constructor throws an exception if the message is empty
|
||||
@@ -34,7 +31,7 @@ class IntlFormatter implements IntlFormatterInterface
|
||||
}
|
||||
|
||||
if (!$formatter = $this->cache[$locale][$message] ?? null) {
|
||||
if (!($this->hasMessageFormatter ?? $this->hasMessageFormatter = class_exists(\MessageFormatter::class))) {
|
||||
if (!$this->hasMessageFormatter ??= class_exists(\MessageFormatter::class)) {
|
||||
throw new LogicException('Cannot parse message translation: please install the "intl" PHP extension or the "symfony/polyfill-intl-messageformatter" package.');
|
||||
}
|
||||
try {
|
||||
|
@@ -22,8 +22,8 @@ class_exists(IntlFormatter::class);
|
||||
*/
|
||||
class MessageFormatter implements MessageFormatterInterface, IntlFormatterInterface
|
||||
{
|
||||
private $translator;
|
||||
private $intlFormatter;
|
||||
private TranslatorInterface $translator;
|
||||
private IntlFormatterInterface $intlFormatter;
|
||||
|
||||
/**
|
||||
* @param TranslatorInterface|null $translator An identity translator to use as selector for pluralization
|
||||
@@ -34,10 +34,7 @@ class MessageFormatter implements MessageFormatterInterface, IntlFormatterInterf
|
||||
$this->intlFormatter = $intlFormatter ?? new IntlFormatter();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(string $message, string $locale, array $parameters = [])
|
||||
public function format(string $message, string $locale, array $parameters = []): string
|
||||
{
|
||||
if ($this->translator instanceof TranslatorInterface) {
|
||||
return $this->translator->trans($message, $parameters, null, $locale);
|
||||
@@ -46,9 +43,6 @@ class MessageFormatter implements MessageFormatterInterface, IntlFormatterInterf
|
||||
return strtr($message, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatIntl(string $message, string $locale, array $parameters = []): string
|
||||
{
|
||||
return $this->intlFormatter->formatIntl($message, $locale, $parameters);
|
||||
|
@@ -23,8 +23,6 @@ interface MessageFormatterInterface
|
||||
* @param string $message The message (may also be an object that can be cast to string)
|
||||
* @param string $locale The message locale
|
||||
* @param array $parameters An array of parameters for the message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(string $message, string $locale, array $parameters = []);
|
||||
public function format(string $message, string $locale, array $parameters = []): string;
|
||||
}
|
||||
|
@@ -20,10 +20,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class ArrayLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, string $locale, string $domain = 'messages')
|
||||
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
|
||||
{
|
||||
$resource = $this->flatten($resource);
|
||||
$catalogue = new MessageCatalogue($locale);
|
||||
|
@@ -20,14 +20,11 @@ use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
*/
|
||||
class CsvFileLoader extends FileLoader
|
||||
{
|
||||
private $delimiter = ';';
|
||||
private $enclosure = '"';
|
||||
private $escape = '\\';
|
||||
private string $delimiter = ';';
|
||||
private string $enclosure = '"';
|
||||
private string $escape = '\\';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadResource(string $resource)
|
||||
protected function loadResource(string $resource): array
|
||||
{
|
||||
$messages = [];
|
||||
|
||||
@@ -45,7 +42,7 @@ class CsvFileLoader extends FileLoader
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('#' !== substr($data[0], 0, 1) && isset($data[1]) && 2 === \count($data)) {
|
||||
if (!str_starts_with($data[0], '#') && isset($data[1]) && 2 === \count($data)) {
|
||||
$messages[$data[0]] = $data[1];
|
||||
}
|
||||
}
|
||||
|
14
vendor/symfony/translation/Loader/FileLoader.php
vendored
14
vendor/symfony/translation/Loader/FileLoader.php
vendored
@@ -14,16 +14,14 @@ namespace Symfony\Component\Translation\Loader;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
|
||||
/**
|
||||
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
|
||||
*/
|
||||
abstract class FileLoader extends ArrayLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, string $locale, string $domain = 'messages')
|
||||
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
@@ -36,9 +34,7 @@ abstract class FileLoader extends ArrayLoader
|
||||
$messages = $this->loadResource($resource);
|
||||
|
||||
// empty resource
|
||||
if (null === $messages) {
|
||||
$messages = [];
|
||||
}
|
||||
$messages ??= [];
|
||||
|
||||
// not an array
|
||||
if (!\is_array($messages)) {
|
||||
@@ -55,9 +51,7 @@ abstract class FileLoader extends ArrayLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws InvalidResourceException if stream content has an invalid format
|
||||
*/
|
||||
abstract protected function loadResource(string $resource);
|
||||
abstract protected function loadResource(string $resource): array;
|
||||
}
|
||||
|
@@ -23,10 +23,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class IcuDatFileLoader extends IcuResFileLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, string $locale, string $domain = 'messages')
|
||||
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
|
||||
{
|
||||
if (!stream_is_local($resource.'.dat')) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
@@ -38,7 +35,7 @@ class IcuDatFileLoader extends IcuResFileLoader
|
||||
|
||||
try {
|
||||
$rb = new \ResourceBundle($locale, $resource);
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Exception) {
|
||||
$rb = null;
|
||||
}
|
||||
|
||||
|
@@ -23,10 +23,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class IcuResFileLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, string $locale, string $domain = 'messages')
|
||||
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
|
||||
{
|
||||
if (!stream_is_local($resource)) {
|
||||
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
|
||||
@@ -38,7 +35,7 @@ class IcuResFileLoader implements LoaderInterface
|
||||
|
||||
try {
|
||||
$rb = new \ResourceBundle($locale, $resource);
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Exception) {
|
||||
$rb = null;
|
||||
}
|
||||
|
||||
@@ -72,10 +69,8 @@ class IcuResFileLoader implements LoaderInterface
|
||||
* @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
|
||||
*/
|
||||
protected function flatten(\ResourceBundle $rb, array &$messages = [], string $path = null)
|
||||
protected function flatten(\ResourceBundle $rb, array &$messages = [], string $path = null): array
|
||||
{
|
||||
foreach ($rb as $key => $value) {
|
||||
$nodePath = $path ? $path.'.'.$key : $key;
|
||||
|
@@ -18,10 +18,7 @@ namespace Symfony\Component\Translation\Loader;
|
||||
*/
|
||||
class IniFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadResource(string $resource)
|
||||
protected function loadResource(string $resource): array
|
||||
{
|
||||
return parse_ini_file($resource, true);
|
||||
}
|
||||
|
@@ -20,10 +20,7 @@ use Symfony\Component\Translation\Exception\InvalidResourceException;
|
||||
*/
|
||||
class JsonFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadResource(string $resource)
|
||||
protected function loadResource(string $resource): array
|
||||
{
|
||||
$messages = [];
|
||||
if ($data = file_get_contents($resource)) {
|
||||
@@ -42,19 +39,13 @@ class JsonFileLoader extends FileLoader
|
||||
*/
|
||||
private function getJSONErrorMessage(int $errorCode): string
|
||||
{
|
||||
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';
|
||||
}
|
||||
return match ($errorCode) {
|
||||
\JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
|
||||
\JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch',
|
||||
\JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
|
||||
\JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
|
||||
\JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded',
|
||||
default => 'Unknown error',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -25,14 +25,8 @@ interface LoaderInterface
|
||||
/**
|
||||
* Loads a locale.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $locale A locale
|
||||
* @param string $domain The domain
|
||||
*
|
||||
* @return MessageCatalogue
|
||||
*
|
||||
* @throws NotFoundResourceException when the resource cannot be found
|
||||
* @throws InvalidResourceException when the resource cannot be loaded
|
||||
*/
|
||||
public function load($resource, string $locale, string $domain = 'messages');
|
||||
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue;
|
||||
}
|
||||
|
@@ -38,10 +38,8 @@ class MoFileLoader extends FileLoader
|
||||
/**
|
||||
* 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(string $resource)
|
||||
protected function loadResource(string $resource): array
|
||||
{
|
||||
$stream = fopen($resource, 'r');
|
||||
|
||||
|
@@ -18,14 +18,11 @@ namespace Symfony\Component\Translation\Loader;
|
||||
*/
|
||||
class PhpFileLoader extends FileLoader
|
||||
{
|
||||
private static $cache = [];
|
||||
private static ?array $cache = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadResource(string $resource)
|
||||
protected function loadResource(string $resource): array
|
||||
{
|
||||
if ([] === self::$cache && \function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(\ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) {
|
||||
if ([] === self::$cache && \function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOL) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(\ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOL))) {
|
||||
self::$cache = null;
|
||||
}
|
||||
|
||||
@@ -33,10 +30,6 @@ class PhpFileLoader extends FileLoader
|
||||
return require $resource;
|
||||
}
|
||||
|
||||
if (isset(self::$cache[$resource])) {
|
||||
return self::$cache[$resource];
|
||||
}
|
||||
|
||||
return self::$cache[$resource] = require $resource;
|
||||
return self::$cache[$resource] ??= require $resource;
|
||||
}
|
||||
}
|
||||
|
@@ -57,10 +57,8 @@ class PoFileLoader extends FileLoader
|
||||
* - Message IDs are allowed to have other encodings as just US-ASCII.
|
||||
*
|
||||
* Items with an empty id are ignored.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadResource(string $resource)
|
||||
protected function loadResource(string $resource): array
|
||||
{
|
||||
$stream = fopen($resource, 'r');
|
||||
|
||||
@@ -83,15 +81,15 @@ class PoFileLoader extends FileLoader
|
||||
}
|
||||
$item = $defaults;
|
||||
$flags = [];
|
||||
} elseif ('#,' === substr($line, 0, 2)) {
|
||||
} elseif (str_starts_with($line, '#,')) {
|
||||
$flags = array_map('trim', explode(',', substr($line, 2)));
|
||||
} elseif ('msgid "' === substr($line, 0, 7)) {
|
||||
} elseif (str_starts_with($line, '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 ('msgstr "' === substr($line, 0, 8)) {
|
||||
} elseif (str_starts_with($line, 'msgstr "')) {
|
||||
$item['translated'] = substr($line, 8, -1);
|
||||
} elseif ('"' === $line[0]) {
|
||||
$continues = isset($item['translated']) ? 'translated' : 'ids';
|
||||
@@ -102,9 +100,9 @@ class PoFileLoader extends FileLoader
|
||||
} else {
|
||||
$item[$continues] .= substr($line, 1, -1);
|
||||
}
|
||||
} elseif ('msgid_plural "' === substr($line, 0, 14)) {
|
||||
} elseif (str_starts_with($line, 'msgid_plural "')) {
|
||||
$item['ids']['plural'] = substr($line, 14, -1);
|
||||
} elseif ('msgstr[' === substr($line, 0, 7)) {
|
||||
} elseif (str_starts_with($line, 'msgstr[')) {
|
||||
$size = strpos($line, ']');
|
||||
$item['translated'][(int) substr($line, 7, 1)] = substr($line, $size + 3, -1);
|
||||
}
|
||||
|
@@ -25,10 +25,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
*/
|
||||
class QtFileLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, string $locale, string $domain = 'messages')
|
||||
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
|
||||
{
|
||||
if (!class_exists(XmlUtils::class)) {
|
||||
throw new RuntimeException('Loading translations from the QT format requires the Symfony Config component.');
|
||||
|
@@ -28,10 +28,7 @@ use Symfony\Component\Translation\Util\XliffUtils;
|
||||
*/
|
||||
class XliffFileLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, string $locale, string $domain = 'messages')
|
||||
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
|
||||
{
|
||||
if (!class_exists(XmlUtils::class)) {
|
||||
throw new RuntimeException('Loading translations from the Xliff format requires the Symfony Config component.');
|
||||
@@ -104,6 +101,10 @@ class XliffFileLoader implements LoaderInterface
|
||||
|
||||
$file->registerXPathNamespace('xliff', $namespace);
|
||||
|
||||
foreach ($file->xpath('.//xliff:prop') as $prop) {
|
||||
$catalogue->setCatalogueMetadata($prop->attributes()['prop-type'], (string) $prop, $domain);
|
||||
}
|
||||
|
||||
foreach ($file->xpath('.//xliff:trans-unit') as $translation) {
|
||||
$attributes = $translation->attributes();
|
||||
|
||||
@@ -227,6 +228,6 @@ class XliffFileLoader implements LoaderInterface
|
||||
|
||||
private function isXmlString(string $resource): bool
|
||||
{
|
||||
return 0 === strpos($resource, '<?xml');
|
||||
return str_starts_with($resource, '<?xml');
|
||||
}
|
||||
}
|
||||
|
@@ -26,10 +26,7 @@ class YamlFileLoader extends FileLoader
|
||||
{
|
||||
private $yamlParser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadResource(string $resource)
|
||||
protected function loadResource(string $resource): array
|
||||
{
|
||||
if (null === $this->yamlParser) {
|
||||
if (!class_exists(\Symfony\Component\Yaml\Parser::class)) {
|
||||
|
75
vendor/symfony/translation/LocaleSwitcher.php
vendored
Normal file
75
vendor/symfony/translation/LocaleSwitcher.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?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\Routing\RequestContext;
|
||||
use Symfony\Contracts\Translation\LocaleAwareInterface;
|
||||
|
||||
/**
|
||||
* @author Kevin Bond <kevinbond@gmail.com>
|
||||
*/
|
||||
class LocaleSwitcher implements LocaleAwareInterface
|
||||
{
|
||||
private string $defaultLocale;
|
||||
|
||||
/**
|
||||
* @param LocaleAwareInterface[] $localeAwareServices
|
||||
*/
|
||||
public function __construct(
|
||||
private string $locale,
|
||||
private iterable $localeAwareServices,
|
||||
private ?RequestContext $requestContext = null,
|
||||
) {
|
||||
$this->defaultLocale = $locale;
|
||||
}
|
||||
|
||||
public function setLocale(string $locale): void
|
||||
{
|
||||
\Locale::setDefault($this->locale = $locale);
|
||||
$this->requestContext?->setParameter('_locale', $locale);
|
||||
|
||||
foreach ($this->localeAwareServices as $service) {
|
||||
$service->setLocale($locale);
|
||||
}
|
||||
}
|
||||
|
||||
public function getLocale(): string
|
||||
{
|
||||
return $this->locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to a new locale, execute a callback, then switch back to the original.
|
||||
*
|
||||
* @template T
|
||||
*
|
||||
* @param callable():T $callback
|
||||
*
|
||||
* @return T
|
||||
*/
|
||||
public function runWithLocale(string $locale, callable $callback): mixed
|
||||
{
|
||||
$original = $this->getLocale();
|
||||
$this->setLocale($locale);
|
||||
|
||||
try {
|
||||
return $callback();
|
||||
} finally {
|
||||
$this->setLocale($original);
|
||||
}
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->setLocale($this->defaultLocale);
|
||||
}
|
||||
}
|
33
vendor/symfony/translation/LoggingTranslator.php
vendored
33
vendor/symfony/translation/LoggingTranslator.php
vendored
@@ -21,8 +21,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
*/
|
||||
class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface
|
||||
{
|
||||
private $translator;
|
||||
private $logger;
|
||||
private TranslatorInterface $translator;
|
||||
private LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @param TranslatorInterface&TranslatorBagInterface&LocaleAwareInterface $translator The translator must implement TranslatorBagInterface
|
||||
@@ -37,10 +37,7 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface,
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
|
||||
public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string
|
||||
{
|
||||
$trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
|
||||
$this->log($id, $domain, $locale);
|
||||
@@ -48,9 +45,6 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface,
|
||||
return $trans;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setLocale(string $locale)
|
||||
{
|
||||
$prev = $this->translator->getLocale();
|
||||
@@ -62,25 +56,16 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface,
|
||||
$this->logger->debug(sprintf('The locale of the translator has changed from "%s" to "%s".', $prev, $locale));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLocale()
|
||||
public function getLocale(): string
|
||||
{
|
||||
return $this->translator->getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCatalogue(string $locale = null)
|
||||
public function getCatalogue(string $locale = null): MessageCatalogueInterface
|
||||
{
|
||||
return $this->translator->getCatalogue($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCatalogues(): array
|
||||
{
|
||||
return $this->translator->getCatalogues();
|
||||
@@ -88,10 +73,8 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface,
|
||||
|
||||
/**
|
||||
* Gets the fallback locales.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFallbackLocales()
|
||||
public function getFallbackLocales(): array
|
||||
{
|
||||
if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
|
||||
return $this->translator->getFallbackLocales();
|
||||
@@ -113,9 +96,7 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface,
|
||||
*/
|
||||
private function log(string $id, ?string $domain, ?string $locale)
|
||||
{
|
||||
if (null === $domain) {
|
||||
$domain = 'messages';
|
||||
}
|
||||
$domain ??= 'messages';
|
||||
|
||||
$catalogue = $this->translator->getCatalogue($locale);
|
||||
if ($catalogue->defines($id, $domain)) {
|
||||
|
135
vendor/symfony/translation/MessageCatalogue.php
vendored
135
vendor/symfony/translation/MessageCatalogue.php
vendored
@@ -17,14 +17,15 @@ use Symfony\Component\Translation\Exception\LogicException;
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface
|
||||
class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface, CatalogueMetadataAwareInterface
|
||||
{
|
||||
private $messages = [];
|
||||
private $metadata = [];
|
||||
private $resources = [];
|
||||
private $locale;
|
||||
private $fallbackCatalogue;
|
||||
private $parent;
|
||||
private array $messages = [];
|
||||
private array $metadata = [];
|
||||
private array $catalogueMetadata = [];
|
||||
private array $resources = [];
|
||||
private string $locale;
|
||||
private ?MessageCatalogueInterface $fallbackCatalogue = null;
|
||||
private ?self $parent = null;
|
||||
|
||||
/**
|
||||
* @param array $messages An array of messages classified by domain
|
||||
@@ -35,18 +36,12 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
$this->messages = $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLocale()
|
||||
public function getLocale(): string
|
||||
{
|
||||
return $this->locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDomains()
|
||||
public function getDomains(): array
|
||||
{
|
||||
$domains = [];
|
||||
|
||||
@@ -60,10 +55,7 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
return array_values($domains);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function all(string $domain = null)
|
||||
public function all(string $domain = null): array
|
||||
{
|
||||
if (null !== $domain) {
|
||||
// skip messages merge if intl-icu requested explicitly
|
||||
@@ -88,18 +80,12 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
return $allMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set(string $id, string $translation, string $domain = 'messages')
|
||||
{
|
||||
$this->add([$id => $translation], $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has(string $id, string $domain = 'messages')
|
||||
public function has(string $id, string $domain = 'messages'): bool
|
||||
{
|
||||
if (isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
|
||||
return true;
|
||||
@@ -112,18 +98,12 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defines(string $id, string $domain = 'messages')
|
||||
public function defines(string $id, string $domain = 'messages'): bool
|
||||
{
|
||||
return isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $id, string $domain = 'messages')
|
||||
public function get(string $id, string $domain = 'messages'): string
|
||||
{
|
||||
if (isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
|
||||
return $this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id];
|
||||
@@ -140,9 +120,6 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function replace(array $messages, string $domain = 'messages')
|
||||
{
|
||||
unset($this->messages[$domain], $this->messages[$domain.self::INTL_DOMAIN_SUFFIX]);
|
||||
@@ -150,9 +127,6 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
$this->add($messages, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(array $messages, string $domain = 'messages')
|
||||
{
|
||||
$altDomain = str_ends_with($domain, self::INTL_DOMAIN_SUFFIX) ? substr($domain, 0, -\strlen(self::INTL_DOMAIN_SUFFIX)) : $domain.self::INTL_DOMAIN_SUFFIX;
|
||||
@@ -166,9 +140,6 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addCatalogue(MessageCatalogueInterface $catalogue)
|
||||
{
|
||||
if ($catalogue->getLocale() !== $this->locale) {
|
||||
@@ -191,11 +162,13 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
$metadata = $catalogue->getMetadata('', '');
|
||||
$this->addMetadata($metadata);
|
||||
}
|
||||
|
||||
if ($catalogue instanceof CatalogueMetadataAwareInterface) {
|
||||
$catalogueMetadata = $catalogue->getCatalogueMetadata('', '');
|
||||
$this->addCatalogueMetadata($catalogueMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
|
||||
{
|
||||
// detect circular references
|
||||
@@ -225,34 +198,22 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFallbackCatalogue()
|
||||
public function getFallbackCatalogue(): ?MessageCatalogueInterface
|
||||
{
|
||||
return $this->fallbackCatalogue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResources()
|
||||
public function getResources(): array
|
||||
{
|
||||
return array_values($this->resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addResource(ResourceInterface $resource)
|
||||
{
|
||||
$this->resources[$resource->__toString()] = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadata(string $key = '', string $domain = 'messages')
|
||||
public function getMetadata(string $key = '', string $domain = 'messages'): mixed
|
||||
{
|
||||
if ('' == $domain) {
|
||||
return $this->metadata;
|
||||
@@ -271,17 +232,11 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMetadata(string $key, $value, string $domain = 'messages')
|
||||
public function setMetadata(string $key, mixed $value, string $domain = 'messages')
|
||||
{
|
||||
$this->metadata[$domain][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMetadata(string $key = '', string $domain = 'messages')
|
||||
{
|
||||
if ('' == $domain) {
|
||||
@@ -293,6 +248,41 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
}
|
||||
}
|
||||
|
||||
public function getCatalogueMetadata(string $key = '', string $domain = 'messages'): mixed
|
||||
{
|
||||
if (!$domain) {
|
||||
return $this->catalogueMetadata;
|
||||
}
|
||||
|
||||
if (isset($this->catalogueMetadata[$domain])) {
|
||||
if (!$key) {
|
||||
return $this->catalogueMetadata[$domain];
|
||||
}
|
||||
|
||||
if (isset($this->catalogueMetadata[$domain][$key])) {
|
||||
return $this->catalogueMetadata[$domain][$key];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setCatalogueMetadata(string $key, mixed $value, string $domain = 'messages')
|
||||
{
|
||||
$this->catalogueMetadata[$domain][$key] = $value;
|
||||
}
|
||||
|
||||
public function deleteCatalogueMetadata(string $key = '', string $domain = 'messages')
|
||||
{
|
||||
if (!$domain) {
|
||||
$this->catalogueMetadata = [];
|
||||
} elseif (!$key) {
|
||||
unset($this->catalogueMetadata[$domain]);
|
||||
} else {
|
||||
unset($this->catalogueMetadata[$domain][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds current values with the new values.
|
||||
*
|
||||
@@ -306,4 +296,13 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addCatalogueMetadata(array $values)
|
||||
{
|
||||
foreach ($values as $domain => $keys) {
|
||||
foreach ($keys as $key => $value) {
|
||||
$this->setCatalogueMetadata($key, $value, $domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,17 +24,13 @@ interface MessageCatalogueInterface
|
||||
|
||||
/**
|
||||
* Gets the catalogue locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale();
|
||||
public function getLocale(): string;
|
||||
|
||||
/**
|
||||
* Gets the domains.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDomains();
|
||||
public function getDomains(): array;
|
||||
|
||||
/**
|
||||
* Gets the messages within a given domain.
|
||||
@@ -42,10 +38,8 @@ interface MessageCatalogueInterface
|
||||
* If $domain is null, it returns all messages.
|
||||
*
|
||||
* @param string $domain The domain name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(string $domain = null);
|
||||
public function all(string $domain = null): array;
|
||||
|
||||
/**
|
||||
* Sets a message translation.
|
||||
@@ -61,30 +55,24 @@ interface MessageCatalogueInterface
|
||||
*
|
||||
* @param string $id The message id
|
||||
* @param string $domain The domain name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $id, string $domain = 'messages');
|
||||
public function has(string $id, string $domain = 'messages'): bool;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function defines(string $id, string $domain = 'messages');
|
||||
public function defines(string $id, string $domain = 'messages'): bool;
|
||||
|
||||
/**
|
||||
* Gets a message translation.
|
||||
*
|
||||
* @param string $id The message id
|
||||
* @param string $domain The domain name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get(string $id, string $domain = 'messages');
|
||||
public function get(string $id, string $domain = 'messages'): string;
|
||||
|
||||
/**
|
||||
* Sets translations for a given domain.
|
||||
@@ -119,17 +107,15 @@ interface MessageCatalogueInterface
|
||||
|
||||
/**
|
||||
* Gets the fallback catalogue.
|
||||
*
|
||||
* @return self|null
|
||||
*/
|
||||
public function getFallbackCatalogue();
|
||||
public function getFallbackCatalogue(): ?self;
|
||||
|
||||
/**
|
||||
* Returns an array of resources loaded to build this collection.
|
||||
*
|
||||
* @return ResourceInterface[]
|
||||
*/
|
||||
public function getResources();
|
||||
public function getResources(): array;
|
||||
|
||||
/**
|
||||
* Adds a resource for this collection.
|
||||
|
@@ -12,7 +12,7 @@
|
||||
namespace Symfony\Component\Translation;
|
||||
|
||||
/**
|
||||
* MetadataAwareInterface.
|
||||
* This interface is used to get, set, and delete metadata about the translation messages.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
@@ -27,14 +27,12 @@ interface MetadataAwareInterface
|
||||
*
|
||||
* @return mixed The value that was set or an array with the domains/keys or null
|
||||
*/
|
||||
public function getMetadata(string $key = '', string $domain = 'messages');
|
||||
public function getMetadata(string $key = '', string $domain = 'messages'): mixed;
|
||||
|
||||
/**
|
||||
* Adds metadata to a message domain.
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setMetadata(string $key, $value, string $domain = 'messages');
|
||||
public function setMetadata(string $key, mixed $value, string $domain = 'messages');
|
||||
|
||||
/**
|
||||
* Deletes metadata for the given key and domain.
|
||||
|
18
vendor/symfony/translation/Provider/Dsn.php
vendored
18
vendor/symfony/translation/Provider/Dsn.php
vendored
@@ -20,14 +20,14 @@ use Symfony\Component\Translation\Exception\MissingRequiredOptionException;
|
||||
*/
|
||||
final class Dsn
|
||||
{
|
||||
private $scheme;
|
||||
private $host;
|
||||
private $user;
|
||||
private $password;
|
||||
private $port;
|
||||
private $path;
|
||||
private $options;
|
||||
private $originalDsn;
|
||||
private ?string $scheme;
|
||||
private ?string $host;
|
||||
private ?string $user;
|
||||
private ?string $password;
|
||||
private ?int $port;
|
||||
private ?string $path;
|
||||
private array $options = [];
|
||||
private string $originalDsn;
|
||||
|
||||
public function __construct(string $dsn)
|
||||
{
|
||||
@@ -79,7 +79,7 @@ final class Dsn
|
||||
return $this->port ?? $default;
|
||||
}
|
||||
|
||||
public function getOption(string $key, $default = null)
|
||||
public function getOption(string $key, mixed $default = null)
|
||||
{
|
||||
return $this->options[$key] ?? $default;
|
||||
}
|
||||
|
@@ -21,9 +21,9 @@ use Symfony\Component\Translation\TranslatorBagInterface;
|
||||
*/
|
||||
class FilteringProvider implements ProviderInterface
|
||||
{
|
||||
private $provider;
|
||||
private $locales;
|
||||
private $domains;
|
||||
private ProviderInterface $provider;
|
||||
private array $locales;
|
||||
private array $domains;
|
||||
|
||||
public function __construct(ProviderInterface $provider, array $locales, array $domains = [])
|
||||
{
|
||||
@@ -37,9 +37,6 @@ class FilteringProvider implements ProviderInterface
|
||||
return (string) $this->provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(TranslatorBagInterface $translatorBag): void
|
||||
{
|
||||
$this->provider->write($translatorBag);
|
||||
|
@@ -18,8 +18,8 @@ use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
|
||||
*/
|
||||
class TranslationProviderCollectionFactory
|
||||
{
|
||||
private $factories;
|
||||
private $enabledLocales;
|
||||
private iterable $factories;
|
||||
private array $enabledLocales;
|
||||
|
||||
/**
|
||||
* @param iterable<mixed, ProviderFactoryInterface> $factories
|
||||
|
@@ -20,16 +20,16 @@ final class PseudoLocalizationTranslator implements TranslatorInterface
|
||||
{
|
||||
private const EXPANSION_CHARACTER = '~';
|
||||
|
||||
private $translator;
|
||||
private $accents;
|
||||
private $expansionFactor;
|
||||
private $brackets;
|
||||
private $parseHTML;
|
||||
private TranslatorInterface $translator;
|
||||
private bool $accents;
|
||||
private float $expansionFactor;
|
||||
private bool $brackets;
|
||||
private bool $parseHTML;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $localizableHTMLAttributes;
|
||||
private array $localizableHTMLAttributes;
|
||||
|
||||
/**
|
||||
* Available options:
|
||||
@@ -83,9 +83,6 @@ final class PseudoLocalizationTranslator implements TranslatorInterface
|
||||
$this->localizableHTMLAttributes = $options['localizable_html_attributes'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null): string
|
||||
{
|
||||
$trans = '';
|
||||
|
8
vendor/symfony/translation/README.md
vendored
8
vendor/symfony/translation/README.md
vendored
@@ -26,12 +26,11 @@ echo $translator->trans('Hello World!'); // outputs « Bonjour ! »
|
||||
Sponsor
|
||||
-------
|
||||
|
||||
The Translation component for Symfony 5.4/6.0 is [backed][1] by:
|
||||
The Translation component for Symfony 6.1 is [backed][1] by:
|
||||
|
||||
* [Crowdin][2], a cloud-based localization management software helping teams to go global and stay agile.
|
||||
* [Lokalise][3], a continuous localization and translation management platform that integrates into your development workflow so you can ship localized products, faster.
|
||||
|
||||
Help Symfony by [sponsoring][4] its development!
|
||||
Help Symfony by [sponsoring][3] its development!
|
||||
|
||||
Resources
|
||||
---------
|
||||
@@ -44,5 +43,4 @@ Resources
|
||||
|
||||
[1]: https://symfony.com/backers
|
||||
[2]: https://crowdin.com
|
||||
[3]: https://lokalise.com
|
||||
[4]: https://symfony.com/sponsor
|
||||
[3]: https://symfony.com/sponsor
|
||||
|
@@ -27,7 +27,7 @@ class TranslationReader implements TranslationReaderInterface
|
||||
*
|
||||
* @var array<string, LoaderInterface>
|
||||
*/
|
||||
private $loaders = [];
|
||||
private array $loaders = [];
|
||||
|
||||
/**
|
||||
* Adds a loader to the translation extractor.
|
||||
@@ -39,9 +39,6 @@ class TranslationReader implements TranslationReaderInterface
|
||||
$this->loaders[$format] = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read(string $directory, MessageCatalogue $catalogue)
|
||||
{
|
||||
if (!is_dir($directory)) {
|
||||
|
@@ -66,7 +66,7 @@ foreach (array_slice($argv, 1) as $argumentOrOption) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 === strpos($argumentOrOption, '-')) {
|
||||
if (str_starts_with($argumentOrOption, '-')) {
|
||||
$config['verbose_output'] = true;
|
||||
} else {
|
||||
$config['locale_to_analyze'] = $argumentOrOption;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
May-19-2004:
|
||||
@@ -1646,20 +1645,21 @@ Jan-10-2006
|
||||
</xsd:group>
|
||||
<xsd:attributeGroup name="AttrGroup_TextContent">
|
||||
<xsd:attribute name="id" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="ts" type="xsd:string" use="optional"/>
|
||||
<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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</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:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="skip"/>
|
||||
<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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="file">
|
||||
@@ -1672,14 +1672,16 @@ Jan-10-2006
|
||||
<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 default="manual" name="tool" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
|
||||
<xsd:attribute ref="xml:space" use="optional"/>
|
||||
<xsd:attribute name="ts" type="xsd:string" 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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
<xsd:unique name="U_group_id">
|
||||
<xsd:selector xpath=".//xlf:group"/>
|
||||
@@ -1739,10 +1741,11 @@ Jan-10-2006
|
||||
<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:prop-group"/>
|
||||
<xsd:element ref="xlf:note"/>
|
||||
<xsd:element ref="xlf:tool"/>
|
||||
</xsd:choice>
|
||||
<xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
|
||||
<xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="skip"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
@@ -1791,6 +1794,7 @@ Jan-10-2006
|
||||
<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="tool" 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"/>
|
||||
@@ -1838,16 +1842,34 @@ Jan-10-2006
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="prop-group">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence maxOccurs="unbounded">
|
||||
<xsd:element ref="xlf:prop"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="prop">
|
||||
<xsd:complexType>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="prop-type" type="xsd:string" use="required"/>
|
||||
<xsd:attribute ref="xml:lang" 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:any namespace="##any" processContents="skip" 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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="body">
|
||||
@@ -1865,8 +1887,9 @@ Jan-10-2006
|
||||
<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:prop-group"/>
|
||||
<xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
|
||||
<xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
|
||||
<xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="skip"/>
|
||||
</xsd:sequence>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
|
||||
@@ -1877,6 +1900,7 @@ Jan-10-2006
|
||||
<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="ts" 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"/>
|
||||
@@ -1901,7 +1925,7 @@ Jan-10-2006
|
||||
<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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="trans-unit">
|
||||
@@ -1913,10 +1937,11 @@ Jan-10-2006
|
||||
<xsd:choice maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:element ref="xlf:context-group"/>
|
||||
<xsd:element ref="xlf:count-group"/>
|
||||
<xsd:element ref="xlf:prop-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:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="skip"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
|
||||
@@ -1924,6 +1949,7 @@ Jan-10-2006
|
||||
<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="ts" type="xsd:string" 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"/>
|
||||
@@ -1947,7 +1973,7 @@ Jan-10-2006
|
||||
<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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
<xsd:unique name="U_tu_segsrc_mid">
|
||||
<xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
|
||||
@@ -1962,7 +1988,8 @@ Jan-10-2006
|
||||
<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:attribute name="ts" type="xsd:string" use="optional"/>
|
||||
<xsd:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
<xsd:unique name="U_source_bpt_rid">
|
||||
<xsd:selector xpath=".//xlf:bpt"/>
|
||||
@@ -1985,7 +2012,8 @@ Jan-10-2006
|
||||
<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:attribute name="ts" type="xsd:string" use="optional"/>
|
||||
<xsd:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
<xsd:unique name="U_segsrc_bpt_rid">
|
||||
<xsd:selector xpath=".//xlf:bpt"/>
|
||||
@@ -2011,6 +2039,8 @@ Jan-10-2006
|
||||
<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="ts" 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="coord" type="xlf:AttrType_Coordinates" use="optional"/>
|
||||
<xsd:attribute name="font" type="xsd:string" use="optional"/>
|
||||
@@ -2018,7 +2048,7 @@ Jan-10-2006
|
||||
<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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
<xsd:unique name="U_target_bpt_rid">
|
||||
<xsd:selector xpath=".//xlf:bpt"/>
|
||||
@@ -2042,18 +2072,21 @@ Jan-10-2006
|
||||
<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" ref="xlf:target"/>
|
||||
<xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
|
||||
<xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:prop-group"/>
|
||||
<xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
|
||||
<xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
|
||||
<xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="skip"/>
|
||||
</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="tool" 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="ts" 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"/>
|
||||
@@ -2070,7 +2103,7 @@ Jan-10-2006
|
||||
<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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
<xsd:unique name="U_at_segsrc_mid">
|
||||
<xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
|
||||
@@ -2089,20 +2122,22 @@ Jan-10-2006
|
||||
<xsd:choice maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:element ref="xlf:context-group"/>
|
||||
<xsd:element ref="xlf:count-group"/>
|
||||
<xsd:element ref="xlf:prop-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:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="skip"/>
|
||||
</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="ts" 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="phase-name" type="xsd:string" use="optional"/>
|
||||
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
||||
<xsd:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="bin-source">
|
||||
@@ -2111,7 +2146,8 @@ Jan-10-2006
|
||||
<xsd:element ref="xlf:internal-file"/>
|
||||
<xsd:element ref="xlf:external-file"/>
|
||||
</xsd:choice>
|
||||
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
||||
<xsd:attribute name="ts" type="xsd:string" use="optional"/>
|
||||
<xsd:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="bin-target">
|
||||
@@ -2121,12 +2157,13 @@ Jan-10-2006
|
||||
<xsd:element ref="xlf:external-file"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
|
||||
<xsd:attribute name="ts" type="xsd:string" 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:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<!-- Element for inline codes -->
|
||||
@@ -2217,7 +2254,8 @@ Jan-10-2006
|
||||
<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:attribute name="ts" type="xsd:string" use="optional"/>
|
||||
<xsd:anyAttribute namespace="##any" processContents="skip"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Translation\Test;
|
||||
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpClient\MockHttpClient;
|
||||
@@ -20,6 +21,7 @@ use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
|
||||
use Symfony\Component\Translation\Loader\LoaderInterface;
|
||||
use Symfony\Component\Translation\Provider\Dsn;
|
||||
use Symfony\Component\Translation\Provider\ProviderFactoryInterface;
|
||||
use Symfony\Component\Translation\TranslatorBagInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
/**
|
||||
@@ -31,11 +33,12 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
*/
|
||||
abstract class ProviderFactoryTestCase extends TestCase
|
||||
{
|
||||
protected $client;
|
||||
protected $logger;
|
||||
protected $defaultLocale;
|
||||
protected $loader;
|
||||
protected $xliffFileDumper;
|
||||
protected HttpClientInterface $client;
|
||||
protected LoggerInterface|MockObject $logger;
|
||||
protected string $defaultLocale;
|
||||
protected LoaderInterface|MockObject $loader;
|
||||
protected XliffFileDumper|MockObject $xliffFileDumper;
|
||||
protected TranslatorBagInterface|MockObject $translatorBag;
|
||||
|
||||
abstract public function createFactory(): ProviderFactoryInterface;
|
||||
|
||||
@@ -122,26 +125,31 @@ abstract class ProviderFactoryTestCase extends TestCase
|
||||
|
||||
protected function getClient(): HttpClientInterface
|
||||
{
|
||||
return $this->client ?? $this->client = new MockHttpClient();
|
||||
return $this->client ??= new MockHttpClient();
|
||||
}
|
||||
|
||||
protected function getLogger(): LoggerInterface
|
||||
{
|
||||
return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class);
|
||||
return $this->logger ??= $this->createMock(LoggerInterface::class);
|
||||
}
|
||||
|
||||
protected function getDefaultLocale(): string
|
||||
{
|
||||
return $this->defaultLocale ?? $this->defaultLocale = 'en';
|
||||
return $this->defaultLocale ??= 'en';
|
||||
}
|
||||
|
||||
protected function getLoader(): LoaderInterface
|
||||
{
|
||||
return $this->loader ?? $this->loader = $this->createMock(LoaderInterface::class);
|
||||
return $this->loader ??= $this->createMock(LoaderInterface::class);
|
||||
}
|
||||
|
||||
protected function getXliffFileDumper(): XliffFileDumper
|
||||
{
|
||||
return $this->xliffFileDumper ?? $this->xliffFileDumper = $this->createMock(XliffFileDumper::class);
|
||||
return $this->xliffFileDumper ??= $this->createMock(XliffFileDumper::class);
|
||||
}
|
||||
|
||||
protected function getTranslatorBag(): TranslatorBagInterface
|
||||
{
|
||||
return $this->translatorBag ??= $this->createMock(TranslatorBagInterface::class);
|
||||
}
|
||||
}
|
||||
|
@@ -11,12 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\Translation\Test;
|
||||
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpClient\MockHttpClient;
|
||||
use Symfony\Component\Translation\Dumper\XliffFileDumper;
|
||||
use Symfony\Component\Translation\Loader\LoaderInterface;
|
||||
use Symfony\Component\Translation\Provider\ProviderInterface;
|
||||
use Symfony\Component\Translation\TranslatorBagInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
/**
|
||||
@@ -28,11 +30,12 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
*/
|
||||
abstract class ProviderTestCase extends TestCase
|
||||
{
|
||||
protected $client;
|
||||
protected $logger;
|
||||
protected $defaultLocale;
|
||||
protected $loader;
|
||||
protected $xliffFileDumper;
|
||||
protected HttpClientInterface $client;
|
||||
protected LoggerInterface|MockObject $logger;
|
||||
protected string $defaultLocale;
|
||||
protected LoaderInterface|MockObject $loader;
|
||||
protected XliffFileDumper|MockObject $xliffFileDumper;
|
||||
protected TranslatorBagInterface|MockObject $translatorBag;
|
||||
|
||||
abstract public function createProvider(HttpClientInterface $client, LoaderInterface $loader, LoggerInterface $logger, string $defaultLocale, string $endpoint): ProviderInterface;
|
||||
|
||||
@@ -51,26 +54,31 @@ abstract class ProviderTestCase extends TestCase
|
||||
|
||||
protected function getClient(): MockHttpClient
|
||||
{
|
||||
return $this->client ?? $this->client = new MockHttpClient();
|
||||
return $this->client ??= new MockHttpClient();
|
||||
}
|
||||
|
||||
protected function getLoader(): LoaderInterface
|
||||
{
|
||||
return $this->loader ?? $this->loader = $this->createMock(LoaderInterface::class);
|
||||
return $this->loader ??= $this->createMock(LoaderInterface::class);
|
||||
}
|
||||
|
||||
protected function getLogger(): LoggerInterface
|
||||
{
|
||||
return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class);
|
||||
return $this->logger ??= $this->createMock(LoggerInterface::class);
|
||||
}
|
||||
|
||||
protected function getDefaultLocale(): string
|
||||
{
|
||||
return $this->defaultLocale ?? $this->defaultLocale = 'en';
|
||||
return $this->defaultLocale ??= 'en';
|
||||
}
|
||||
|
||||
protected function getXliffFileDumper(): XliffFileDumper
|
||||
{
|
||||
return $this->xliffFileDumper ?? $this->xliffFileDumper = $this->createMock(XliffFileDumper::class);
|
||||
return $this->xliffFileDumper ??= $this->createMock(XliffFileDumper::class);
|
||||
}
|
||||
|
||||
protected function getTranslatorBag(): TranslatorBagInterface
|
||||
{
|
||||
return $this->translatorBag ??= $this->createMock(TranslatorBagInterface::class);
|
||||
}
|
||||
}
|
||||
|
@@ -19,9 +19,9 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
*/
|
||||
class TranslatableMessage implements TranslatableInterface
|
||||
{
|
||||
private $message;
|
||||
private $parameters;
|
||||
private $domain;
|
||||
private string $message;
|
||||
private array $parameters;
|
||||
private ?string $domain;
|
||||
|
||||
public function __construct(string $message, array $parameters = [], string $domain = null)
|
||||
{
|
||||
|
95
vendor/symfony/translation/Translator.php
vendored
95
vendor/symfony/translation/Translator.php
vendored
@@ -22,6 +22,7 @@ use Symfony\Component\Translation\Formatter\MessageFormatter;
|
||||
use Symfony\Component\Translation\Formatter\MessageFormatterInterface;
|
||||
use Symfony\Component\Translation\Loader\LoaderInterface;
|
||||
use Symfony\Contracts\Translation\LocaleAwareInterface;
|
||||
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
// Help opcache.preload discover always-needed symbols
|
||||
@@ -37,54 +38,33 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
*/
|
||||
protected $catalogues = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $locale;
|
||||
private string $locale;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $fallbackLocales = [];
|
||||
private array $fallbackLocales = [];
|
||||
|
||||
/**
|
||||
* @var LoaderInterface[]
|
||||
*/
|
||||
private $loaders = [];
|
||||
private array $loaders = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $resources = [];
|
||||
private array $resources = [];
|
||||
|
||||
/**
|
||||
* @var MessageFormatterInterface
|
||||
*/
|
||||
private $formatter;
|
||||
private MessageFormatterInterface $formatter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheDir;
|
||||
private ?string $cacheDir;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debug;
|
||||
private bool $debug;
|
||||
|
||||
private $cacheVary;
|
||||
private array $cacheVary;
|
||||
|
||||
/**
|
||||
* @var ConfigCacheFactoryInterface|null
|
||||
*/
|
||||
private $configCacheFactory;
|
||||
private ?ConfigCacheFactoryInterface $configCacheFactory;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
private $parentLocales;
|
||||
private array $parentLocales;
|
||||
|
||||
private $hasIntlFormatter;
|
||||
private bool $hasIntlFormatter;
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException If a locale contains invalid characters
|
||||
@@ -93,11 +73,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
{
|
||||
$this->setLocale($locale);
|
||||
|
||||
if (null === $formatter) {
|
||||
$formatter = new MessageFormatter();
|
||||
}
|
||||
|
||||
$this->formatter = $formatter;
|
||||
$this->formatter = $formatter ??= new MessageFormatter();
|
||||
$this->cacheDir = $cacheDir;
|
||||
$this->debug = $debug;
|
||||
$this->cacheVary = $cacheVary;
|
||||
@@ -127,11 +103,9 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
*
|
||||
* @throws InvalidArgumentException If the locale contains invalid characters
|
||||
*/
|
||||
public function addResource(string $format, $resource, string $locale, string $domain = null)
|
||||
public function addResource(string $format, mixed $resource, string $locale, string $domain = null)
|
||||
{
|
||||
if (null === $domain) {
|
||||
$domain = 'messages';
|
||||
}
|
||||
$domain ??= 'messages';
|
||||
|
||||
$this->assertValidLocale($locale);
|
||||
$locale ?: $locale = class_exists(\Locale::class) ? \Locale::getDefault() : 'en';
|
||||
@@ -145,19 +119,13 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setLocale(string $locale)
|
||||
{
|
||||
$this->assertValidLocale($locale);
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLocale()
|
||||
public function getLocale(): string
|
||||
{
|
||||
return $this->locale ?: (class_exists(\Locale::class) ? \Locale::getDefault() : 'en');
|
||||
}
|
||||
@@ -191,18 +159,13 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
return $this->fallbackLocales;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
|
||||
public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string
|
||||
{
|
||||
if (null === $id || '' === $id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (null === $domain) {
|
||||
$domain = 'messages';
|
||||
}
|
||||
$domain ??= 'messages';
|
||||
|
||||
$catalogue = $this->getCatalogue($locale);
|
||||
$locale = $catalogue->getLocale();
|
||||
@@ -215,6 +178,10 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
}
|
||||
}
|
||||
|
||||
$parameters = array_map(function ($parameter) use ($locale) {
|
||||
return $parameter instanceof TranslatableInterface ? $parameter->trans($this, $locale) : $parameter;
|
||||
}, $parameters);
|
||||
|
||||
$len = \strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX);
|
||||
if ($this->hasIntlFormatter
|
||||
&& ($catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)
|
||||
@@ -226,10 +193,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
return $this->formatter->format($catalogue->get($id, $domain), $locale, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCatalogue(string $locale = null)
|
||||
public function getCatalogue(string $locale = null): MessageCatalogueInterface
|
||||
{
|
||||
if (!$locale) {
|
||||
$locale = $this->getLocale();
|
||||
@@ -244,9 +208,6 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
return $this->catalogues[$locale];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCatalogues(): array
|
||||
{
|
||||
return array_values($this->catalogues);
|
||||
@@ -257,7 +218,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
|
||||
*
|
||||
* @return LoaderInterface[]
|
||||
*/
|
||||
protected function getLoaders()
|
||||
protected function getLoaders(): array
|
||||
{
|
||||
return $this->loaders;
|
||||
}
|
||||
@@ -409,9 +370,7 @@ EOF
|
||||
|
||||
protected function computeFallbackLocales(string $locale)
|
||||
{
|
||||
if (null === $this->parentLocales) {
|
||||
$this->parentLocales = json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);
|
||||
}
|
||||
$this->parentLocales ??= json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);
|
||||
|
||||
$originLocale = $locale;
|
||||
$locales = [];
|
||||
@@ -468,9 +427,7 @@ EOF
|
||||
*/
|
||||
private function getConfigCacheFactory(): ConfigCacheFactoryInterface
|
||||
{
|
||||
if (!$this->configCacheFactory) {
|
||||
$this->configCacheFactory = new ConfigCacheFactory($this->debug);
|
||||
}
|
||||
$this->configCacheFactory ??= new ConfigCacheFactory($this->debug);
|
||||
|
||||
return $this->configCacheFactory;
|
||||
}
|
||||
|
8
vendor/symfony/translation/TranslatorBag.php
vendored
8
vendor/symfony/translation/TranslatorBag.php
vendored
@@ -17,7 +17,7 @@ use Symfony\Component\Translation\Catalogue\TargetOperation;
|
||||
final class TranslatorBag implements TranslatorBagInterface
|
||||
{
|
||||
/** @var MessageCatalogue[] */
|
||||
private $catalogues = [];
|
||||
private array $catalogues = [];
|
||||
|
||||
public function addCatalogue(MessageCatalogue $catalogue): void
|
||||
{
|
||||
@@ -35,9 +35,6 @@ final class TranslatorBag implements TranslatorBagInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCatalogue(string $locale = null): MessageCatalogueInterface
|
||||
{
|
||||
if (null === $locale || !isset($this->catalogues[$locale])) {
|
||||
@@ -47,9 +44,6 @@ final class TranslatorBag implements TranslatorBagInterface
|
||||
return $this->catalogues[$locale];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCatalogues(): array
|
||||
{
|
||||
return array_values($this->catalogues);
|
||||
|
@@ -14,10 +14,6 @@ namespace Symfony\Component\Translation;
|
||||
use Symfony\Component\Translation\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* TranslatorBagInterface.
|
||||
*
|
||||
* @method MessageCatalogueInterface[] getCatalogues() Returns all catalogues of the instance
|
||||
*
|
||||
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
|
||||
*/
|
||||
interface TranslatorBagInterface
|
||||
@@ -27,9 +23,14 @@ interface TranslatorBagInterface
|
||||
*
|
||||
* @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(string $locale = null);
|
||||
public function getCatalogue(string $locale = null): MessageCatalogueInterface;
|
||||
|
||||
/**
|
||||
* Returns all catalogues of the instance.
|
||||
*
|
||||
* @return MessageCatalogueInterface[]
|
||||
*/
|
||||
public function getCatalogues(): array;
|
||||
}
|
||||
|
@@ -30,10 +30,8 @@ class ArrayConverter
|
||||
* For example this array('foo.bar' => 'value') will be converted to ['foo' => ['bar' => 'value']].
|
||||
*
|
||||
* @param array $messages Linear messages array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function expandToTree(array $messages)
|
||||
public static function expandToTree(array $messages): array
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
|
@@ -85,11 +85,6 @@ class XliffUtils
|
||||
|
||||
private static function shouldEnableEntityLoader(): bool
|
||||
{
|
||||
// Version prior to 8.0 can be enabled without deprecation
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static $dom, $schema;
|
||||
if (null === $dom) {
|
||||
$dom = new \DOMDocument();
|
||||
@@ -134,7 +129,7 @@ class XliffUtils
|
||||
private static function getSchema(string $xliffVersion): string
|
||||
{
|
||||
if ('1.2' === $xliffVersion) {
|
||||
$schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-1.2-strict.xsd');
|
||||
$schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-1.2-transitional.xsd');
|
||||
$xmlUri = 'http://www.w3.org/2001/xml.xsd';
|
||||
} elseif ('2.0' === $xliffVersion) {
|
||||
$schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-2.0.xsd');
|
||||
|
@@ -26,7 +26,7 @@ class TranslationWriter implements TranslationWriterInterface
|
||||
/**
|
||||
* @var array<string, DumperInterface>
|
||||
*/
|
||||
private $dumpers = [];
|
||||
private array $dumpers = [];
|
||||
|
||||
/**
|
||||
* Adds a dumper to the writer.
|
||||
@@ -38,10 +38,8 @@ class TranslationWriter implements TranslationWriterInterface
|
||||
|
||||
/**
|
||||
* Obtains the list of supported formats.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFormats()
|
||||
public function getFormats(): array
|
||||
{
|
||||
return array_keys($this->dumpers);
|
||||
}
|
||||
|
35
vendor/symfony/translation/composer.json
vendored
35
vendor/symfony/translation/composer.json
vendored
@@ -16,37 +16,38 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/deprecation-contracts": "^2.1|^3",
|
||||
"php": ">=8.1",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/translation-contracts": "^2.3"
|
||||
"symfony/translation-contracts": "^2.3|^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/config": "^4.4|^5.0|^6.0",
|
||||
"nikic/php-parser": "^4.13",
|
||||
"symfony/config": "^5.4|^6.0",
|
||||
"symfony/console": "^5.4|^6.0",
|
||||
"symfony/dependency-injection": "^5.0|^6.0",
|
||||
"symfony/dependency-injection": "^5.4|^6.0",
|
||||
"symfony/http-client-contracts": "^1.1|^2.0|^3.0",
|
||||
"symfony/http-kernel": "^5.0|^6.0",
|
||||
"symfony/intl": "^4.4|^5.0|^6.0",
|
||||
"symfony/http-kernel": "^5.4|^6.0",
|
||||
"symfony/intl": "^5.4|^6.0",
|
||||
"symfony/polyfill-intl-icu": "^1.21",
|
||||
"symfony/routing": "^5.4|^6.0",
|
||||
"symfony/service-contracts": "^1.1.2|^2|^3",
|
||||
"symfony/yaml": "^4.4|^5.0|^6.0",
|
||||
"symfony/finder": "^4.4|^5.0|^6.0",
|
||||
"symfony/yaml": "^5.4|^6.0",
|
||||
"symfony/finder": "^5.4|^6.0",
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/config": "<4.4",
|
||||
"symfony/dependency-injection": "<5.0",
|
||||
"symfony/http-kernel": "<5.0",
|
||||
"symfony/twig-bundle": "<5.0",
|
||||
"symfony/yaml": "<4.4",
|
||||
"symfony/console": "<5.3"
|
||||
"symfony/config": "<5.4",
|
||||
"symfony/dependency-injection": "<5.4",
|
||||
"symfony/http-kernel": "<5.4",
|
||||
"symfony/twig-bundle": "<5.4",
|
||||
"symfony/yaml": "<5.4",
|
||||
"symfony/console": "<5.4"
|
||||
},
|
||||
"provide": {
|
||||
"symfony/translation-implementation": "2.3"
|
||||
"symfony/translation-implementation": "2.3|3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"nikic/php-parser": "To use PhpAstExtractor",
|
||||
"symfony/config": "",
|
||||
"symfony/yaml": "",
|
||||
"psr/log-implementation": "To use logging capability in translator"
|
||||
|
Reference in New Issue
Block a user