update patch 1

This commit is contained in:
fiqhpratama
2024-12-02 01:18:34 +07:00
parent 453d9bb470
commit 25026b0a85
3380 changed files with 103529 additions and 363623 deletions
+14
View File
@@ -1,6 +1,20 @@
CHANGELOG
=========
7.2
---
* Deprecate `ProviderFactoryTestCase`, extend `AbstractProviderFactoryTestCase` instead
The `testIncompleteDsnException()` test is no longer provided by default. If you make use of it by implementing the `incompleteDsnProvider()` data providers,
you now need to use the `IncompleteDsnTestTrait`.
* Make `ProviderFactoryTestCase` and `ProviderTestCase` compatible with PHPUnit 10+
* Add `lint:translations` command
* Deprecate passing an escape character to `CsvFileLoader::setCsvControl()`
* Make Xliff 2.0 attributes in segment element available as `segment-attributes`
metadata returned by `XliffFileLoader` and make `XliffFileDumper` write them to the file
7.1
---
+8 -10
View File
@@ -30,8 +30,6 @@ abstract class AbstractOperation implements OperationInterface
public const NEW_BATCH = 'new';
public const ALL_BATCH = 'all';
protected MessageCatalogueInterface $source;
protected MessageCatalogueInterface $target;
protected MessageCatalogue $result;
/**
@@ -62,14 +60,14 @@ abstract class AbstractOperation implements OperationInterface
/**
* @throws LogicException
*/
public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
{
public function __construct(
protected MessageCatalogueInterface $source,
protected MessageCatalogueInterface $target,
) {
if ($source->getLocale() !== $target->getLocale()) {
throw new LogicException('Operated catalogues must belong to the same locale.');
}
$this->source = $source;
$this->target = $target;
$this->result = new MessageCatalogue($source->getLocale());
$this->messages = [];
}
@@ -97,7 +95,7 @@ abstract class AbstractOperation implements OperationInterface
public function getMessages(string $domain): array
{
if (!\in_array($domain, $this->getDomains(), true)) {
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
throw new InvalidArgumentException(\sprintf('Invalid domain: "%s".', $domain));
}
if (!isset($this->messages[$domain][self::ALL_BATCH])) {
@@ -110,7 +108,7 @@ abstract class AbstractOperation implements OperationInterface
public function getNewMessages(string $domain): array
{
if (!\in_array($domain, $this->getDomains(), true)) {
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
throw new InvalidArgumentException(\sprintf('Invalid domain: "%s".', $domain));
}
if (!isset($this->messages[$domain][self::NEW_BATCH])) {
@@ -123,7 +121,7 @@ abstract class AbstractOperation implements OperationInterface
public function getObsoleteMessages(string $domain): array
{
if (!\in_array($domain, $this->getDomains(), true)) {
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
throw new InvalidArgumentException(\sprintf('Invalid domain: "%s".', $domain));
}
if (!isset($this->messages[$domain][self::OBSOLETE_BATCH])) {
@@ -160,7 +158,7 @@ abstract class AbstractOperation implements OperationInterface
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)),
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))) {
+10 -18
View File
@@ -34,22 +34,14 @@ final class TranslationPullCommand extends Command
{
use TranslationTrait;
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 = [])
{
$this->providerCollection = $providerCollection;
$this->writer = $writer;
$this->reader = $reader;
$this->defaultLocale = $defaultLocale;
$this->transPaths = $transPaths;
$this->enabledLocales = $enabledLocales;
public function __construct(
private TranslationProviderCollection $providerCollection,
private TranslationWriterInterface $writer,
private TranslationReaderInterface $reader,
private string $defaultLocale,
private array $transPaths = [],
private array $enabledLocales = [],
) {
parent::__construct();
}
@@ -163,7 +155,7 @@ EOF
$this->writer->write($operation->getResult(), $format, $writeOptions);
}
$io->success(sprintf('Local translations has been updated from "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
$io->success(\sprintf('Local translations has been updated from "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
return 0;
}
@@ -177,7 +169,7 @@ EOF
$this->writer->write($catalogue, $format, $writeOptions);
}
$io->success(sprintf('New translations from "%s" has been written locally (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
$io->success(\sprintf('New translations from "%s" has been written locally (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
return 0;
}
+10 -16
View File
@@ -34,18 +34,12 @@ final class TranslationPushCommand extends Command
{
use TranslationTrait;
private TranslationProviderCollection $providers;
private TranslationReaderInterface $reader;
private array $transPaths;
private array $enabledLocales;
public function __construct(TranslationProviderCollection $providers, TranslationReaderInterface $reader, array $transPaths = [], array $enabledLocales = [])
{
$this->providers = $providers;
$this->reader = $reader;
$this->transPaths = $transPaths;
$this->enabledLocales = $enabledLocales;
public function __construct(
private TranslationProviderCollection $providers,
private TranslationReaderInterface $reader,
private array $transPaths = [],
private array $enabledLocales = [],
) {
parent::__construct();
}
@@ -115,7 +109,7 @@ EOF
$provider = $this->providers->get($input->getArgument('provider'));
if (!$this->enabledLocales) {
throw new InvalidArgumentException(sprintf('You must define "framework.enabled_locales" or "framework.translator.providers.%s.locales" config key in order to work with translation providers.', parse_url($provider, \PHP_URL_SCHEME)));
throw new InvalidArgumentException(\sprintf('You must define "framework.enabled_locales" or "framework.translator.providers.%s.locales" config key in order to work with translation providers.', parse_url($provider, \PHP_URL_SCHEME)));
}
$io = new SymfonyStyle($input, $output);
@@ -139,7 +133,7 @@ EOF
if (!$deleteMissing && $force) {
$provider->write($localTranslations);
$io->success(sprintf('All local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
$io->success(\sprintf('All local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
return 0;
}
@@ -149,7 +143,7 @@ EOF
if ($deleteMissing) {
$provider->delete($providerTranslations->diff($localTranslations));
$io->success(sprintf('Missing translations on "%s" has been deleted (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
$io->success(\sprintf('Missing translations on "%s" has been deleted (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
// Read provider translations again, after missing translations deletion,
// to avoid push freshly deleted translations.
@@ -164,7 +158,7 @@ EOF
$provider->write($translationsToWrite);
$io->success(sprintf('%s local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', $force ? 'All' : 'New', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
$io->success(\sprintf('%s local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', $force ? 'All' : 'New', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
return 0;
}
+21 -15
View File
@@ -39,22 +39,24 @@ class XliffLintCommand extends Command
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)
{
public function __construct(
?string $name = null,
?callable $directoryIteratorProvider = null,
?callable $isReadableProvider = null,
private bool $requireStrictFileNames = true,
) {
parent::__construct($name);
$this->directoryIteratorProvider = null === $directoryIteratorProvider ? null : $directoryIteratorProvider(...);
$this->isReadableProvider = null === $isReadableProvider ? null : $isReadableProvider(...);
$this->requireStrictFileNames = $requireStrictFileNames;
}
protected function configure(): void
{
$this
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())))
->addOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())))
->setHelp(<<<EOF
The <info>%command.name%</info> command lints an XLIFF file and outputs to STDOUT
the first encountered syntax error.
@@ -70,6 +72,9 @@ You can also validate the syntax of a file:
Or of a whole directory:
<info>php %command.full_name% dirname</info>
The <info>--format</info> option specifies the format of the command output:
<info>php %command.full_name% dirname --format=json</info>
EOF
@@ -95,7 +100,7 @@ EOF
$filesInfo = [];
foreach ($filenames as $filename) {
if (!$this->isReadable($filename)) {
throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
throw new RuntimeException(\sprintf('File or directory "%s" is not readable.', $filename));
}
foreach ($this->getFiles($filename) as $file) {
@@ -121,18 +126,18 @@ EOF
$document->loadXML($content);
if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) {
$normalizedLocalePattern = sprintf('(%s|%s)', preg_quote($targetLanguage, '/'), preg_quote(str_replace('-', '_', $targetLanguage), '/'));
$normalizedLocalePattern = \sprintf('(%s|%s)', preg_quote($targetLanguage, '/'), preg_quote(str_replace('-', '_', $targetLanguage), '/'));
// strict file names require translation files to be named '____.locale.xlf'
// otherwise, both '____.locale.xlf' and 'locale.____.xlf' are allowed
// also, the regexp matching must be case-insensitive, as defined for 'target-language' values
// http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#target-language
$expectedFilenamePattern = $this->requireStrictFileNames ? sprintf('/^.*\.(?i:%s)\.(?:xlf|xliff)/', $normalizedLocalePattern) : sprintf('/^(?:.*\.(?i:%s)|(?i:%s)\..*)\.(?:xlf|xliff)/', $normalizedLocalePattern, $normalizedLocalePattern);
$expectedFilenamePattern = $this->requireStrictFileNames ? \sprintf('/^.*\.(?i:%s)\.(?:xlf|xliff)/', $normalizedLocalePattern) : \sprintf('/^(?:.*\.(?i:%s)|(?i:%s)\..*)\.(?:xlf|xliff)/', $normalizedLocalePattern, $normalizedLocalePattern);
if (0 === preg_match($expectedFilenamePattern, basename($file))) {
$errors[] = [
'line' => -1,
'column' => -1,
'message' => sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage),
'message' => \sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage),
];
}
}
@@ -157,7 +162,7 @@ EOF
'txt' => $this->displayTxt($io, $files),
'json' => $this->displayJson($io, $files),
'github' => $this->displayTxt($io, $files, true),
default => throw new InvalidArgumentException(sprintf('Supported formats are "%s".', implode('", "', $this->getAvailableFormatOptions()))),
default => throw new InvalidArgumentException(\sprintf('Supported formats are "%s".', implode('", "', $this->getAvailableFormatOptions()))),
};
}
@@ -169,25 +174,25 @@ EOF
foreach ($filesInfo as $info) {
if ($info['valid'] && $this->displayCorrectFiles) {
$io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
$io->comment('<info>OK</info>'.($info['file'] ? \sprintf(' in %s', $info['file']) : ''));
} elseif (!$info['valid']) {
++$erroredFiles;
$io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
$io->text('<error> ERROR </error>'.($info['file'] ? \sprintf(' in %s', $info['file']) : ''));
$io->listing(array_map(function ($error) use ($info, $githubReporter) {
// general document errors have a '-1' line number
$line = -1 === $error['line'] ? null : $error['line'];
$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']);
return null === $line ? $error['message'] : \sprintf('Line %d, Column %d: %s', $line, $error['column'], $error['message']);
}, $info['messages']));
}
}
if (0 === $erroredFiles) {
$io->success(sprintf('All %d XLIFF files contain valid syntax.', $countFiles));
$io->success(\sprintf('All %d XLIFF files contain valid syntax.', $countFiles));
} else {
$io->warning(sprintf('%d XLIFF files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
$io->warning(\sprintf('%d XLIFF files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
}
return min($erroredFiles, 1);
@@ -275,6 +280,7 @@ EOF
}
}
/** @return string[] */
private function getAvailableFormatOptions(): array
{
return ['txt', 'json', 'github'];
@@ -25,11 +25,9 @@ use Symfony\Component\VarDumper\Cloner\Data;
*/
class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface
{
private DataCollectorTranslator $translator;
public function __construct(DataCollectorTranslator $translator)
{
$this->translator = $translator;
public function __construct(
private DataCollectorTranslator $translator,
) {
}
public function lateCollect(): void
+4 -13
View File
@@ -12,7 +12,6 @@
namespace Symfony\Component\Translation;
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Contracts\Translation\LocaleAwareInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -27,19 +26,11 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
public const MESSAGE_MISSING = 1;
public const MESSAGE_EQUALS_FALLBACK = 2;
private TranslatorInterface $translator;
private array $messages = [];
/**
* @param TranslatorInterface&TranslatorBagInterface&LocaleAwareInterface $translator
*/
public function __construct(TranslatorInterface $translator)
{
if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', get_debug_type($translator)));
}
$this->translator = $translator;
public function __construct(
private TranslatorInterface&TranslatorBagInterface&LocaleAwareInterface $translator,
) {
}
public function trans(?string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string
@@ -73,7 +64,7 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
public function warmUp(string $cacheDir, ?string $buildDir = null): array
{
if ($this->translator instanceof WarmableInterface) {
return (array) $this->translator->warmUp($cacheDir, $buildDir);
return $this->translator->warmUp($cacheDir, $buildDir);
}
return [];
@@ -37,7 +37,7 @@ class LoggingTranslatorPass implements CompilerPassInterface
$class = $container->getParameterBag()->resolveValue($definition->getClass());
if (!$r = $container->getReflectionClass($class)) {
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $translatorAlias));
throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $translatorAlias));
}
if (!$r->isSubclassOf(TranslatorInterface::class) || !$r->isSubclassOf(TranslatorBagInterface::class)) {
@@ -31,7 +31,7 @@ class TranslationExtractorPass implements CompilerPassInterface
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));
throw new RuntimeException(\sprintf('The alias for the tag "translation.extractor" of service "%s" must be set.', $id));
}
$definition->addMethodCall('addExtractor', [$attributes[0]['alias'], new Reference($id)]);
+1 -1
View File
@@ -50,7 +50,7 @@ abstract class FileDumper implements DumperInterface
if (!file_exists($fullpath)) {
$directory = \dirname($fullpath);
if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory));
throw new RuntimeException(\sprintf('Unable to create directory "%s".', $directory));
}
}
+2 -5
View File
@@ -54,14 +54,11 @@ class MoFileDumper extends FileDumper
.$this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
}
$output = implode('', array_map($this->writeLong(...), $header))
return implode('', array_map($this->writeLong(...), $header))
.$sourceOffsets
.$targetOffsets
.$sources
.$targets
;
return $output;
.$targets;
}
protected function getExtension(): string
+9 -9
View File
@@ -51,14 +51,14 @@ class PoFileDumper extends FileDumper
$sourceRules = $this->getStandardRules($source);
$targetRules = $this->getStandardRules($target);
if (2 == \count($sourceRules) && [] !== $targetRules) {
$output .= sprintf('msgid "%s"'."\n", $this->escape($sourceRules[0]));
$output .= sprintf('msgid_plural "%s"'."\n", $this->escape($sourceRules[1]));
$output .= \sprintf('msgid "%s"'."\n", $this->escape($sourceRules[0]));
$output .= \sprintf('msgid_plural "%s"'."\n", $this->escape($sourceRules[1]));
foreach ($targetRules as $i => $targetRule) {
$output .= sprintf('msgstr[%d] "%s"'."\n", $i, $this->escape($targetRule));
$output .= \sprintf('msgstr[%d] "%s"'."\n", $i, $this->escape($targetRule));
}
} else {
$output .= sprintf('msgid "%s"'."\n", $this->escape($source));
$output .= sprintf('msgstr "%s"'."\n", $this->escape($target));
$output .= \sprintf('msgid "%s"'."\n", $this->escape($source));
$output .= \sprintf('msgstr "%s"'."\n", $this->escape($target));
}
}
@@ -100,9 +100,9 @@ EOF;
if (preg_match($intervalRegexp, $part)) {
// Explicit rule is not a standard rule.
return [];
} else {
$standardRules[] = $part;
}
}
$standardRules[] = $part;
}
return $standardRules;
@@ -123,7 +123,7 @@ EOF;
$output = null;
foreach ((array) $comments as $comment) {
$output .= sprintf('#%s %s'."\n", $prefix, $comment);
$output .= \sprintf('#%s %s'."\n", $prefix, $comment);
}
return $output;
+7 -1
View File
@@ -46,7 +46,7 @@ class XliffFileDumper extends FileDumper
return $this->dumpXliff2($defaultLocale, $messages, $domain);
}
throw new InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
throw new InvalidArgumentException(\sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
}
protected function getExtension(): string
@@ -193,6 +193,12 @@ class XliffFileDumper extends FileDumper
$segment = $translation->appendChild($dom->createElement('segment'));
if ($this->hasMetadataArrayInfo('segment-attributes', $metadata)) {
foreach ($metadata['segment-attributes'] as $name => $value) {
$segment->setAttribute($name, $value);
}
}
$s = $segment->appendChild($dom->createElement('source'));
$s->appendChild($dom->createTextNode($source));
+3 -5
View File
@@ -23,11 +23,9 @@ use Symfony\Component\Yaml\Yaml;
*/
class YamlFileDumper extends FileDumper
{
private string $extension;
public function __construct(string $extension = 'yml')
{
$this->extension = $extension;
public function __construct(
private string $extension = 'yml',
) {
}
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
@@ -16,7 +16,7 @@ class IncompleteDsnException extends InvalidArgumentException
public function __construct(string $message, ?string $dsn = null, ?\Throwable $previous = null)
{
if ($dsn) {
$message = sprintf('Invalid "%s" provider DSN: ', $dsn).$message;
$message = \sprintf('Invalid "%s" provider DSN: ', $dsn).$message;
}
parent::__construct($message, 0, $previous);
@@ -18,7 +18,7 @@ class MissingRequiredOptionException extends IncompleteDsnException
{
public function __construct(string $option, ?string $dsn = null, ?\Throwable $previous = null)
{
$message = sprintf('The option "%s" is required but missing.', $option);
$message = \sprintf('The option "%s" is required but missing.', $option);
parent::__construct($message, $dsn, $previous);
}
+6 -4
View File
@@ -18,12 +18,14 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
*/
class ProviderException extends RuntimeException implements ProviderExceptionInterface
{
private ResponseInterface $response;
private string $debug;
public function __construct(string $message, ResponseInterface $response, int $code = 0, ?\Exception $previous = null)
{
$this->response = $response;
public function __construct(
string $message,
private ResponseInterface $response,
int $code = 0,
?\Exception $previous = null,
) {
$this->debug = $response->getInfo('debug') ?? '';
parent::__construct($message, $code, $previous);
@@ -43,14 +43,14 @@ class UnsupportedSchemeException extends LogicException
}
$package = self::SCHEME_TO_PACKAGE_MAP[$provider] ?? null;
if ($package && !class_exists($package['class'])) {
parent::__construct(sprintf('Unable to synchronize translations via "%s" as the provider is not installed. Try running "composer require %s".', $provider, $package['package']));
parent::__construct(\sprintf('Unable to synchronize translations via "%s" as the provider is not installed. Try running "composer require %s".', $provider, $package['package']));
return;
}
$message = sprintf('The "%s" scheme is not supported', $dsn->getScheme());
$message = \sprintf('The "%s" scheme is not supported', $dsn->getScheme());
if ($name && $supported) {
$message .= sprintf('; supported schemes for translation provider "%s" are: "%s"', $name, implode('", "', $supported));
$message .= \sprintf('; supported schemes for translation provider "%s" are: "%s"', $name, implode('", "', $supported));
}
parent::__construct($message.'.');
@@ -49,7 +49,7 @@ abstract class AbstractFileExtractor
protected function isFile(string $file): bool
{
if (!is_file($file)) {
throw new InvalidArgumentException(sprintf('The "%s" file does not exist.', $file));
throw new InvalidArgumentException(\sprintf('The "%s" file does not exist.', $file));
}
return true;
+2 -2
View File
@@ -36,7 +36,7 @@ final class PhpAstExtractor extends AbstractFileExtractor implements ExtractorIn
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));
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())->createForHostVersion();
@@ -77,7 +77,7 @@ final class PhpAstExtractor extends AbstractFileExtractor implements ExtractorIn
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));
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);
+2 -2
View File
@@ -37,7 +37,7 @@ class IntlFormatter implements IntlFormatterInterface
try {
$this->cache[$locale][$message] = $formatter = new \MessageFormatter($locale, $message);
} catch (\IntlException $e) {
throw new InvalidArgumentException(sprintf('Invalid message format (error #%d): ', intl_get_error_code()).intl_get_error_message(), 0, $e);
throw new InvalidArgumentException(\sprintf('Invalid message format (error #%d): ', intl_get_error_code()).intl_get_error_message(), 0, $e);
}
}
@@ -49,7 +49,7 @@ class IntlFormatter implements IntlFormatterInterface
}
if (false === $message = $formatter->format($parameters)) {
throw new InvalidArgumentException(sprintf('Unable to format message (error #%s): ', $formatter->getErrorCode()).$formatter->getErrorMessage());
throw new InvalidArgumentException(\sprintf('Unable to format message (error #%s): ', $formatter->getErrorCode()).$formatter->getErrorMessage());
}
return $message;
+8 -1
View File
@@ -22,6 +22,9 @@ class CsvFileLoader extends FileLoader
{
private string $delimiter = ';';
private string $enclosure = '"';
/**
* @deprecated since Symfony 7.2, to be removed in 8.0
*/
private string $escape = '';
protected function loadResource(string $resource): array
@@ -31,7 +34,7 @@ class CsvFileLoader extends FileLoader
try {
$file = new \SplFileObject($resource, 'rb');
} catch (\RuntimeException $e) {
throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e);
throw new NotFoundResourceException(\sprintf('Error opening file "%s".', $resource), 0, $e);
}
$file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
@@ -57,6 +60,10 @@ class CsvFileLoader extends FileLoader
{
$this->delimiter = $delimiter;
$this->enclosure = $enclosure;
if ('' !== $escape) {
trigger_deprecation('symfony/translation', '7.2', 'The "escape" parameter of the "%s" method is deprecated. It will be removed in 8.0.', __METHOD__);
}
$this->escape = $escape;
}
}
+3 -3
View File
@@ -24,11 +24,11 @@ abstract class FileLoader extends ArrayLoader
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));
throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
}
if (!file_exists($resource)) {
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource));
}
$messages = $this->loadResource($resource);
@@ -38,7 +38,7 @@ abstract class FileLoader extends ArrayLoader
// not an array
if (!\is_array($messages)) {
throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
throw new InvalidResourceException(\sprintf('Unable to load file "%s".', $resource));
}
$catalogue = parent::load($messages, $locale, $domain);
+3 -3
View File
@@ -26,11 +26,11 @@ class IcuDatFileLoader extends IcuResFileLoader
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));
throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
}
if (!file_exists($resource.'.dat')) {
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource));
}
try {
@@ -40,7 +40,7 @@ class IcuDatFileLoader extends IcuResFileLoader
}
if (!$rb) {
throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource));
throw new InvalidResourceException(\sprintf('Cannot load resource "%s".', $resource));
} elseif (intl_is_failure($rb->getErrorCode())) {
throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
}
+3 -3
View File
@@ -26,11 +26,11 @@ class IcuResFileLoader implements LoaderInterface
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));
throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
}
if (!is_dir($resource)) {
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource));
}
try {
@@ -40,7 +40,7 @@ class IcuResFileLoader implements LoaderInterface
}
if (!$rb) {
throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource));
throw new InvalidResourceException(\sprintf('Cannot load resource "%s".', $resource));
} elseif (intl_is_failure($rb->getErrorCode())) {
throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
}
+3 -3
View File
@@ -32,17 +32,17 @@ class QtFileLoader implements LoaderInterface
}
if (!stream_is_local($resource)) {
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
}
if (!file_exists($resource)) {
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource));
}
try {
$dom = XmlUtils::loadFile($resource);
} catch (\InvalidArgumentException $e) {
throw new InvalidResourceException(sprintf('Unable to load "%s".', $resource), $e->getCode(), $e);
throw new InvalidResourceException(\sprintf('Unable to load "%s".', $resource), $e->getCode(), $e);
}
$internalErrors = libxml_use_internal_errors(true);
+12 -5
View File
@@ -36,15 +36,15 @@ class XliffFileLoader implements LoaderInterface
if (!$this->isXmlString($resource)) {
if (!stream_is_local($resource)) {
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
}
if (!file_exists($resource)) {
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource));
}
if (!is_file($resource)) {
throw new InvalidResourceException(sprintf('This is neither a file nor an XLIFF string "%s".', $resource));
throw new InvalidResourceException(\sprintf('This is neither a file nor an XLIFF string "%s".', $resource));
}
}
@@ -55,11 +55,11 @@ class XliffFileLoader implements LoaderInterface
$dom = XmlUtils::loadFile($resource);
}
} catch (\InvalidArgumentException|XmlParsingException|InvalidXmlException $e) {
throw new InvalidResourceException(sprintf('Unable to load "%s": ', $resource).$e->getMessage(), $e->getCode(), $e);
throw new InvalidResourceException(\sprintf('Unable to load "%s": ', $resource).$e->getMessage(), $e->getCode(), $e);
}
if ($errors = XliffUtils::validateSchema($dom)) {
throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: ', $resource).XliffUtils::getErrorsAsString($errors));
throw new InvalidResourceException(\sprintf('Invalid resource provided: "%s"; Errors: ', $resource).XliffUtils::getErrorsAsString($errors));
}
$catalogue = new MessageCatalogue($locale);
@@ -172,6 +172,13 @@ class XliffFileLoader implements LoaderInterface
$catalogue->set((string) $source, $target, $domain);
$metadata = [];
if ($segment->attributes()) {
$metadata['segment-attributes'] = [];
foreach ($segment->attributes() as $key => $value) {
$metadata['segment-attributes'][$key] = (string) $value;
}
}
if (isset($segment->target) && $segment->target->attributes()) {
$metadata['target-attributes'] = [];
foreach ($segment->target->attributes() as $key => $value) {
+2 -2
View File
@@ -39,11 +39,11 @@ class YamlFileLoader extends FileLoader
try {
$messages = $this->yamlParser->parseFile($resource, Yaml::PARSE_CONSTANT);
} catch (ParseException $e) {
throw new InvalidResourceException(sprintf('The file "%s" does not contain valid YAML: ', $resource).$e->getMessage(), 0, $e);
throw new InvalidResourceException(\sprintf('The file "%s" does not contain valid YAML: ', $resource).$e->getMessage(), 0, $e);
}
if (null !== $messages && !\is_array($messages)) {
throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
throw new InvalidResourceException(\sprintf('Unable to load file "%s".', $resource));
}
return $messages ?: [];
+5 -16
View File
@@ -12,7 +12,6 @@
namespace Symfony\Component\Translation;
use Psr\Log\LoggerInterface;
use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Contracts\Translation\LocaleAwareInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -21,20 +20,10 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface
{
private TranslatorInterface $translator;
private LoggerInterface $logger;
/**
* @param TranslatorInterface&TranslatorBagInterface&LocaleAwareInterface $translator The translator must implement TranslatorBagInterface
*/
public function __construct(TranslatorInterface $translator, LoggerInterface $logger)
{
if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', get_debug_type($translator)));
}
$this->translator = $translator;
$this->logger = $logger;
public function __construct(
private TranslatorInterface&TranslatorBagInterface&LocaleAwareInterface $translator,
private LoggerInterface $logger,
) {
}
public function trans(?string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string
@@ -53,7 +42,7 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface,
return;
}
$this->logger->debug(sprintf('The locale of the translator has changed from "%s" to "%s".', $prev, $locale));
$this->logger->debug(\sprintf('The locale of the translator has changed from "%s" to "%s".', $prev, $locale));
}
public function getLocale(): string
+7 -9
View File
@@ -19,21 +19,19 @@ use Symfony\Component\Translation\Exception\LogicException;
*/
class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface, CatalogueMetadataAwareInterface
{
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
*/
public function __construct(string $locale, array $messages = [])
{
$this->locale = $locale;
$this->messages = $messages;
public function __construct(
private string $locale,
private array $messages = [],
) {
}
public function getLocale(): string
@@ -143,7 +141,7 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
public function addCatalogue(MessageCatalogueInterface $catalogue): void
{
if ($catalogue->getLocale() !== $this->locale) {
throw new LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s".', $catalogue->getLocale(), $this->locale));
throw new LogicException(\sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s".', $catalogue->getLocale(), $this->locale));
}
foreach ($catalogue->all() as $domain => $messages) {
@@ -175,14 +173,14 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
$c = $catalogue;
while ($c = $c->getFallbackCatalogue()) {
if ($c->getLocale() === $this->getLocale()) {
throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
throw new LogicException(\sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
}
}
$c = $this;
do {
if ($c->getLocale() === $catalogue->getLocale()) {
throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
throw new LogicException(\sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
}
foreach ($catalogue->getResources() as $resource) {
+5 -9
View File
@@ -21,15 +21,11 @@ use Symfony\Component\Translation\TranslatorBagInterface;
*/
class FilteringProvider implements ProviderInterface
{
private ProviderInterface $provider;
private array $locales;
private array $domains;
public function __construct(ProviderInterface $provider, array $locales, array $domains = [])
{
$this->provider = $provider;
$this->locales = $locales;
$this->domains = $domains;
public function __construct(
private ProviderInterface $provider,
private array $locales,
private array $domains = [],
) {
}
public function __toString(): string
@@ -44,7 +44,7 @@ final class TranslationProviderCollection
public function get(string $name): ProviderInterface
{
if (!$this->has($name)) {
throw new InvalidArgumentException(sprintf('Provider "%s" not found. Available: "%s".', $name, (string) $this));
throw new InvalidArgumentException(\sprintf('Provider "%s" not found. Available: "%s".', $name, (string) $this));
}
return $this->providers[$name];
@@ -18,16 +18,13 @@ use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
*/
class TranslationProviderCollectionFactory
{
private iterable $factories;
private array $enabledLocales;
/**
* @param iterable<mixed, ProviderFactoryInterface> $factories
*/
public function __construct(iterable $factories, array $enabledLocales)
{
$this->factories = $factories;
$this->enabledLocales = $enabledLocales;
public function __construct(
private iterable $factories,
private array $enabledLocales,
) {
}
public function fromConfig(array $config): TranslationProviderCollection
@@ -20,7 +20,6 @@ final class PseudoLocalizationTranslator implements TranslatorInterface
{
private const EXPANSION_CHARACTER = '~';
private TranslatorInterface $translator;
private bool $accents;
private float $expansionFactor;
private bool $brackets;
@@ -64,8 +63,10 @@ final class PseudoLocalizationTranslator implements TranslatorInterface
* description: the list of HTML attributes whose values can be altered - it is only useful when the "parse_html" option is set to true
* example: if ["title"], and with the "accents" option set to true, "<a href="#" title="Go to your profile">Profile</a>" => "<a href="#" title="Ĝö ţö ýöûŕ þŕöƒîļé">Þŕöƒîļé</a>" - if "title" was not in the "localizable_html_attributes" list, the title attribute data would be left unchanged.
*/
public function __construct(TranslatorInterface $translator, array $options = [])
{
public function __construct(
private TranslatorInterface $translator,
array $options = [],
) {
$this->translator = $translator;
$this->accents = $options['accents'] ?? true;
+7 -75
View File
@@ -12,15 +12,10 @@
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\Exception\IncompleteDsnException;
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;
@@ -28,9 +23,13 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
* A test case to ease testing a translation provider factory.
*
* @author Mathieu Santostefano <msantostefano@protonmail.com>
*
* @deprecated since Symfony 7.2, use AbstractProviderFactoryTestCase instead
*/
abstract class ProviderFactoryTestCase extends TestCase
abstract class ProviderFactoryTestCase extends AbstractProviderFactoryTestCase
{
use IncompleteDsnTestTrait;
protected HttpClientInterface $client;
protected LoggerInterface|MockObject $logger;
protected string $defaultLocale;
@@ -38,20 +37,8 @@ abstract class ProviderFactoryTestCase extends TestCase
protected XliffFileDumper|MockObject $xliffFileDumper;
protected TranslatorBagInterface|MockObject $translatorBag;
abstract public function createFactory(): ProviderFactoryInterface;
/**
* @return iterable<array{0: bool, 1: string}>
*/
abstract public static function supportsProvider(): iterable;
/**
* @return iterable<array{0: string, 1: string}>
*/
abstract public static function createProvider(): iterable;
/**
* @return iterable<array{0: string, 1: string|null}>
* @return iterable<array{0: string, 1?: string|null}>
*/
public static function unsupportedSchemeProvider(): iterable
{
@@ -59,68 +46,13 @@ abstract class ProviderFactoryTestCase extends TestCase
}
/**
* @return iterable<array{0: string, 1: string|null}>
* @return iterable<array{0: string, 1?: string|null}>
*/
public static function incompleteDsnProvider(): iterable
{
return [];
}
/**
* @dataProvider supportsProvider
*/
public function testSupports(bool $expected, string $dsn)
{
$factory = $this->createFactory();
$this->assertSame($expected, $factory->supports(new Dsn($dsn)));
}
/**
* @dataProvider createProvider
*/
public function testCreate(string $expected, string $dsn)
{
$factory = $this->createFactory();
$provider = $factory->create(new Dsn($dsn));
$this->assertSame($expected, (string) $provider);
}
/**
* @dataProvider unsupportedSchemeProvider
*/
public function testUnsupportedSchemeException(string $dsn, ?string $message = null)
{
$factory = $this->createFactory();
$dsn = new Dsn($dsn);
$this->expectException(UnsupportedSchemeException::class);
if (null !== $message) {
$this->expectExceptionMessage($message);
}
$factory->create($dsn);
}
/**
* @dataProvider incompleteDsnProvider
*/
public function testIncompleteDsnException(string $dsn, ?string $message = null)
{
$factory = $this->createFactory();
$dsn = new Dsn($dsn);
$this->expectException(IncompleteDsnException::class);
if (null !== $message) {
$this->expectExceptionMessage($message);
}
$factory->create($dsn);
}
protected function getClient(): HttpClientInterface
{
return $this->client ??= new MockHttpClient();
+2
View File
@@ -11,6 +11,7 @@
namespace Symfony\Component\Translation\Test;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
@@ -45,6 +46,7 @@ abstract class ProviderTestCase extends TestCase
/**
* @dataProvider toStringProvider
*/
#[DataProvider('toStringProvider')]
public function testToString(ProviderInterface $provider, string $expected)
{
$this->assertSame($expected, (string) $provider);
+5 -9
View File
@@ -19,15 +19,11 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
class TranslatableMessage implements TranslatableInterface
{
private string $message;
private array $parameters;
private ?string $domain;
public function __construct(string $message, array $parameters = [], ?string $domain = null)
{
$this->message = $message;
$this->parameters = $parameters;
$this->domain = $domain;
public function __construct(
private string $message,
private array $parameters = [],
private ?string $domain = null,
) {
}
public function __toString(): string
+12 -16
View File
@@ -54,12 +54,6 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
private MessageFormatterInterface $formatter;
private ?string $cacheDir;
private bool $debug;
private array $cacheVary;
private ?ConfigCacheFactoryInterface $configCacheFactory;
private array $parentLocales;
@@ -69,14 +63,16 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
/**
* @throws InvalidArgumentException If a locale contains invalid characters
*/
public function __construct(string $locale, ?MessageFormatterInterface $formatter = null, ?string $cacheDir = null, bool $debug = false, array $cacheVary = [])
{
public function __construct(
string $locale,
?MessageFormatterInterface $formatter = null,
private ?string $cacheDir = null,
private bool $debug = false,
private array $cacheVary = [],
) {
$this->setLocale($locale);
$this->formatter = $formatter ??= new MessageFormatter();
$this->cacheDir = $cacheDir;
$this->debug = $debug;
$this->cacheVary = $cacheVary;
$this->hasIntlFormatter = $formatter instanceof IntlFormatterInterface;
}
@@ -272,7 +268,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
$this->initializeCatalogue($locale);
$fallbackContent = $this->getFallbackContent($this->catalogues[$locale]);
$content = sprintf(<<<EOF
$content = \sprintf(<<<EOF
<?php
use Symfony\Component\Translation\MessageCatalogue;
@@ -303,7 +299,7 @@ EOF
$fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback));
$currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current));
$fallbackContent .= sprintf(<<<'EOF'
$fallbackContent .= \sprintf(<<<'EOF'
$catalogue%s = new MessageCatalogue('%s', %s);
$catalogue%s->addFallbackCatalogue($catalogue%s);
@@ -338,10 +334,10 @@ EOF
foreach ($this->resources[$locale] as $resource) {
if (!isset($this->loaders[$resource[0]])) {
if (\is_string($resource[1])) {
throw new RuntimeException(sprintf('No loader is registered for the "%s" format when loading the "%s" resource.', $resource[0], $resource[1]));
throw new RuntimeException(\sprintf('No loader is registered for the "%s" format when loading the "%s" resource.', $resource[0], $resource[1]));
}
throw new RuntimeException(sprintf('No loader is registered for the "%s" format.', $resource[0]));
throw new RuntimeException(\sprintf('No loader is registered for the "%s" format.', $resource[0]));
}
$this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
}
@@ -415,7 +411,7 @@ EOF
protected function assertValidLocale(string $locale): void
{
if (!preg_match('/^[a-z0-9@_\\.\\-]*$/i', $locale)) {
throw new InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
throw new InvalidArgumentException(\sprintf('Invalid "%s" locale.', $locale));
}
}
+3 -3
View File
@@ -41,7 +41,7 @@ class XliffUtils
$namespace = $xliff->attributes->getNamedItem('xmlns');
if ($namespace) {
if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) {
throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s".', $namespace));
throw new InvalidArgumentException(\sprintf('Not a valid XLIFF namespace "%s".', $namespace));
}
return substr($namespace, 34);
@@ -113,7 +113,7 @@ class XliffUtils
$errorsAsString = '';
foreach ($xmlErrors as $error) {
$errorsAsString .= sprintf("[%s %s] %s (in %s - line %d, column %d)\n",
$errorsAsString .= \sprintf("[%s %s] %s (in %s - line %d, column %d)\n",
\LIBXML_ERR_WARNING === $error['level'] ? 'WARNING' : 'ERROR',
$error['code'],
$error['message'],
@@ -135,7 +135,7 @@ class XliffUtils
$schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-2.0.xsd');
$xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd';
} else {
throw new InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion));
throw new InvalidArgumentException(\sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion));
}
return self::fixXmlLocation($schemaSource, $xmlUri);
+2 -2
View File
@@ -55,14 +55,14 @@ class TranslationWriter implements TranslationWriterInterface
public function write(MessageCatalogue $catalogue, string $format, array $options = []): void
{
if (!isset($this->dumpers[$format])) {
throw new InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format));
throw new InvalidArgumentException(\sprintf('There is no dumper associated with format "%s".', $format));
}
// get the right dumper
$dumper = $this->dumpers[$format];
if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0777, true) && !is_dir($options['path'])) {
throw new RuntimeException(sprintf('Translation Writer was not able to create directory "%s".', $options['path']));
throw new RuntimeException(\sprintf('Translation Writer was not able to create directory "%s".', $options['path']));
}
// save
+2 -1
View File
@@ -18,7 +18,8 @@
"require": {
"php": ">=8.2",
"symfony/polyfill-mbstring": "~1.0",
"symfony/translation-contracts": "^2.5|^3.0"
"symfony/translation-contracts": "^2.5|^3.0",
"symfony/deprecation-contracts": "^2.5|^3"
},
"require-dev": {
"nikic/php-parser": "^4.18|^5.0",