Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6e55fa8

Browse filesBrowse files
welcoMatticOlivier Dolbeau
and
Olivier Dolbeau
committed
Added Translation Providers
Co-authored-by: Olivier Dolbeau <github@a.bbnt.me>
1 parent be384cf commit 6e55fa8
Copy full SHA for 6e55fa8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner

58 files changed

+3616
-51
lines changed

‎UPGRADE-5.3.md

Copy file name to clipboardExpand all lines: UPGRADE-5.3.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ FrameworkBundle
4444
* Deprecate the `KernelTestCase::$container` property, use `KernelTestCase::getContainer()` instead
4545
* Rename the container parameter `profiler_listener.only_master_requests` to `profiler_listener.only_main_requests`
4646
* Deprecate registering workflow services as public
47+
* Deprecate option `--xliff-version` of the `translation:update` command, use e.g. `--format=xlf20` instead
48+
* Deprecate option `--output-format` of the `translation:update` command, use e.g. `--format=xlf20` instead
4749

4850
HttpFoundation
4951
--------------

‎UPGRADE-6.0.md

Copy file name to clipboardExpand all lines: UPGRADE-6.0.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ FrameworkBundle
8686
* Removed the `lock.RESOURCE_NAME` and `lock.RESOURCE_NAME.store` services and the `lock`, `LockInterface`, `lock.store` and `PersistingStoreInterface` aliases, use `lock.RESOURCE_NAME.factory`, `lock.factory` or `LockFactory` instead.
8787
* Remove the `KernelTestCase::$container` property, use `KernelTestCase::getContainer()` instead
8888
* Registered workflow services are now private
89+
* Remove option `--xliff-version` of the `translation:update` command, use e.g. `--output-format=xlf20` instead
90+
* Remove option `--output-format` of the `translation:update` command, use e.g. `--output-format=xlf20` instead
8991

9092
HttpFoundation
9193
--------------

‎link

Copy file name to clipboardExpand all lines: link
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ if (!is_dir("$pathToProject/vendor/symfony")) {
4141
$sfPackages = array('symfony/symfony' => __DIR__);
4242

4343
$filesystem = new Filesystem();
44-
$braces = array('Bundle', 'Bridge', 'Component', 'Component/Security', 'Component/Mailer/Bridge', 'Component/Messenger/Bridge', 'Component/Notifier/Bridge', 'Contracts');
44+
$braces = array('Bundle', 'Bridge', 'Component', 'Component/Security', 'Component/Mailer/Bridge', 'Component/Messenger/Bridge', 'Component/Notifier/Bridge', 'Contracts', 'Component/Translation/Bridge');
4545
$directories = array_merge(...array_values(array_map(function ($part) {
4646
return glob(__DIR__.'/src/Symfony/'.$part.'/*', GLOB_ONLYDIR | GLOB_NOSORT);
4747
}, $braces)));

‎src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ CHANGELOG
2020
* Rename the container parameter `profiler_listener.only_master_requests` to `profiler_listener.only_main_requests`
2121
* Add service `fragment.uri_generator` to generate the URI of a fragment
2222
* Deprecate registering workflow services as public
23+
* Deprecate option `--xliff-version` of the `translation:update` command, use e.g. `--format=xlf20` instead
24+
* Deprecate option `--output-format` of the `translation:update` command, use e.g. `--format=xlf20` instead
2325

2426
5.2.0
2527
-----

‎src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
+31-26Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ protected function configure()
7777
new InputArgument('locale', InputArgument::REQUIRED, 'The locale'),
7878
new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'),
7979
new InputOption('prefix', null, InputOption::VALUE_OPTIONAL, 'Override the default prefix', '__'),
80-
new InputOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf'),
80+
new InputOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format (deprecated)'),
81+
new InputOption('format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf12'),
8182
new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'),
8283
new InputOption('force', null, InputOption::VALUE_NONE, 'Should the update be done'),
8384
new InputOption('clean', null, InputOption::VALUE_NONE, 'Should clean not found messages'),
8485
new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'Specify the domain to update'),
85-
new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version', '1.2'),
86+
new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version (deprecated)'),
8687
new InputOption('sort', null, InputOption::VALUE_OPTIONAL, 'Return list of messages sorted alphabetically', 'asc'),
8788
new InputOption('as-tree', null, InputOption::VALUE_OPTIONAL, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'),
8889
])
@@ -112,8 +113,8 @@ protected function configure()
112113
113114
You can dump a tree-like structure using the yaml format with <comment>--as-tree</> flag:
114115
115-
<info>php %command.full_name% --force --output-format=yaml --as-tree=3 en AcmeBundle</info>
116-
<info>php %command.full_name% --force --output-format=yaml --sort=asc --as-tree=3 fr</info>
116+
<info>php %command.full_name% --force --format=yaml --as-tree=3 en AcmeBundle</info>
117+
<info>php %command.full_name% --force --format=yaml --sort=asc --as-tree=3 fr</info>
117118

118119
EOF
119120
)
@@ -135,13 +136,31 @@ protected function execute(InputInterface $input, OutputInterface $output): int
135136
return 1;
136137
}
137138

139+
$format = $input->getOption('output-format') ?: $input->getOption('format');
140+
$xliffVersion = $input->getOption('xliff-version') ?? '1.2';
141+
142+
if ($input->getOption('xliff-version')) {
143+
trigger_deprecation('symfony/framework-bundle', '5.3', 'The "--xliff-version" option is deprecated, use "--format=xlf%d" instead.', 10 * $xliffVersion);
144+
}
145+
146+
if ($input->getOption('output-format')) {
147+
trigger_deprecation('symfony/framework-bundle', '5.3', 'The "--output-format" option is deprecated, use "--format=xlf%d" instead.', 10 * $xliffVersion);
148+
}
149+
150+
switch ($format) {
151+
case 'xlf20': $xliffVersion = '2.0';
152+
// no break
153+
case 'xlf12': $format = 'xlf';
154+
}
155+
138156
// check format
139157
$supportedFormats = $this->writer->getFormats();
140-
if (!\in_array($input->getOption('output-format'), $supportedFormats, true)) {
141-
$errorIo->error(['Wrong output format', 'Supported formats are: '.implode(', ', $supportedFormats).'.']);
158+
if (!\in_array($format, $supportedFormats, true)) {
159+
$errorIo->error(['Wrong output format', 'Supported formats are: '.implode(', ', $supportedFormats).', xlf12 and xlf20.']);
142160

143161
return 1;
144162
}
163+
145164
/** @var KernelInterface $kernel */
146165
$kernel = $this->getApplication()->getKernel();
147166

@@ -225,23 +244,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
225244

226245
$resultMessage = 'Translation files were successfully updated';
227246

228-
// move new messages to intl domain when possible
229-
if (class_exists(\MessageFormatter::class)) {
230-
foreach ($operation->getDomains() as $domain) {
231-
$intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
232-
$newMessages = $operation->getNewMessages($domain);
233-
234-
if ([] === $newMessages || ([] === $currentCatalogue->all($intlDomain) && [] !== $currentCatalogue->all($domain))) {
235-
continue;
236-
}
237-
238-
$result = $operation->getResult();
239-
$allIntlMessages = $result->all($intlDomain);
240-
$currentMessages = array_diff_key($newMessages, $result->all($domain));
241-
$result->replace($currentMessages, $domain);
242-
$result->replace($allIntlMessages + $newMessages, $intlDomain);
243-
}
244-
}
247+
$operation->moveMessagesToIntlDomainsIfPossible('new');
245248

246249
// show compiled list of messages
247250
if (true === $input->getOption('dump-messages')) {
@@ -284,8 +287,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
284287
$extractedMessagesCount += $domainMessagesCount;
285288
}
286289

287-
if ('xlf' === $input->getOption('output-format')) {
288-
$io->comment(sprintf('Xliff output version is <info>%s</info>', $input->getOption('xliff-version')));
290+
if ('xlf' === $format) {
291+
$io->comment(sprintf('Xliff output version is <info>%s</info>', $xliffVersion));
289292
}
290293

291294
$resultMessage = sprintf('%d message%s successfully extracted', $extractedMessagesCount, $extractedMessagesCount > 1 ? 's were' : ' was');
@@ -306,7 +309,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
306309
$bundleTransPath = end($transPaths);
307310
}
308311

309-
$this->writer->write($operation->getResult(), $input->getOption('output-format'), ['path' => $bundleTransPath, 'default_locale' => $this->defaultLocale, 'xliff_version' => $input->getOption('xliff-version'), 'as_tree' => $input->getOption('as-tree'), 'inline' => $input->getOption('as-tree') ?? 0]);
312+
$this->writer->write($operation->getResult(), $format, ['path' => $bundleTransPath, 'default_locale' => $this->defaultLocale, 'xliff_version' => $xliffVersion, 'as_tree' => $input->getOption('as-tree'), 'inline' => $input->getOption('as-tree') ?? 0]);
310313

311314
if (true === $input->getOption('dump-messages')) {
312315
$resultMessage .= ' and translation files were updated';
@@ -335,11 +338,13 @@ private function filterCatalogue(MessageCatalogue $catalogue, string $domain): M
335338
foreach ($catalogue->getResources() as $resource) {
336339
$filteredCatalogue->addResource($resource);
337340
}
341+
338342
if ($metadata = $catalogue->getMetadata('', $intlDomain)) {
339343
foreach ($metadata as $k => $v) {
340344
$filteredCatalogue->setMetadata($k, $v, $intlDomain);
341345
}
342346
}
347+
343348
if ($metadata = $catalogue->getMetadata('', $domain)) {
344349
foreach ($metadata as $k => $v) {
345350
$filteredCatalogue->setMetadata($k, $v, $domain);

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class UnusedTagsPass implements CompilerPassInterface
8585
'translation.dumper',
8686
'translation.extractor',
8787
'translation.loader',
88+
'translation.provider_factory',
8889
'twig.extension',
8990
'twig.loader',
9091
'twig.runtime',

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,7 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode, callable $e
785785
->fixXmlConfig('fallback')
786786
->fixXmlConfig('path')
787787
->fixXmlConfig('enabled_locale')
788+
->fixXmlConfig('provider')
788789
->children()
789790
->arrayNode('fallbacks')
790791
->info('Defaults to the value of "default_locale".')
@@ -822,6 +823,27 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode, callable $e
822823
->end()
823824
->end()
824825
->end()
826+
->arrayNode('providers')
827+
->info('Translation providers you can read/write your translations from')
828+
->useAttributeAsKey('name')
829+
->prototype('array')
830+
->fixXmlConfig('domain')
831+
->fixXmlConfig('locale')
832+
->children()
833+
->scalarNode('dsn')->end()
834+
->arrayNode('domains')
835+
->prototype('scalar')->end()
836+
->defaultValue([])
837+
->end()
838+
->arrayNode('locales')
839+
->prototype('scalar')->end()
840+
->defaultValue([])
841+
->info('If not set, all locales listed under framework.translator.enabled_locales are used.')
842+
->end()
843+
->end()
844+
->end()
845+
->defaultValue([])
846+
->end()
825847
->end()
826848
->end()
827849
->end()

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169
use Symfony\Component\Stopwatch\Stopwatch;
170170
use Symfony\Component\String\LazyString;
171171
use Symfony\Component\String\Slugger\SluggerInterface;
172+
use Symfony\Component\Translation\Bridge\Loco\Provider\LocoProviderFactory;
172173
use Symfony\Component\Translation\Command\XliffLintCommand as BaseXliffLintCommand;
173174
use Symfony\Component\Translation\PseudoLocalizationTranslator;
174175
use Symfony\Component\Translation\Translator;
@@ -1222,11 +1223,14 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
12221223
if (!$this->isConfigEnabled($container, $config)) {
12231224
$container->removeDefinition('console.command.translation_debug');
12241225
$container->removeDefinition('console.command.translation_update');
1226+
$container->removeDefinition('console.command.translation_pull');
1227+
$container->removeDefinition('console.command.translation_push');
12251228

12261229
return;
12271230
}
12281231

12291232
$loader->load('translation.php');
1233+
$loader->load('translation_providers.php');
12301234

12311235
// Use the "real" translator instead of the identity default
12321236
$container->setAlias('translator', 'translator.default')->setPublic(true);
@@ -1348,6 +1352,46 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
13481352
$options,
13491353
]);
13501354
}
1355+
1356+
$classToServices = [
1357+
LocoProviderFactory::class => 'translation.provider_factory.loco',
1358+
];
1359+
1360+
$parentPackages = ['symfony/framework-bundle', 'symfony/translation', 'symfony/http-client'];
1361+
1362+
foreach ($classToServices as $class => $service) {
1363+
$package = sprintf('symfony/%s-translation', substr($service, \strlen('translation.provider_factory.')));
1364+
1365+
if (!$container->hasDefinition('http_client') || !ContainerBuilder::willBeAvailable($package, $class, $parentPackages)) {
1366+
$container->removeDefinition($service);
1367+
}
1368+
}
1369+
1370+
if (!$config['providers']) {
1371+
return;
1372+
}
1373+
1374+
foreach ($config['providers'] as $name => $provider) {
1375+
if (!$config['enabled_locales'] && !$provider['locales']) {
1376+
throw new LogicException(sprintf('You must specify one of "framework.translator.enabled_locales" or "framework.translator.providers.%s.locales" in order to use translation providers.', $name));
1377+
}
1378+
}
1379+
1380+
$container->getDefinition('console.command.translation_pull')
1381+
->replaceArgument(4, array_merge($transPaths, [$config['default_path']]))
1382+
->replaceArgument(5, $config['enabled_locales'])
1383+
;
1384+
1385+
$container->getDefinition('console.command.translation_push')
1386+
->replaceArgument(2, array_merge($transPaths, [$config['default_path']]))
1387+
->replaceArgument(3, $config['enabled_locales'])
1388+
;
1389+
1390+
$container->getDefinition('translation.provider_collection_factory')
1391+
->replaceArgument(1, $config['enabled_locales'])
1392+
;
1393+
1394+
$container->getDefinition('translation.provider_collection')->setArgument(0, $config['providers']);
13511395
}
13521396

13531397
private function registerValidationConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $propertyInfoEnabled)

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
use Symfony\Component\Messenger\Command\FailedMessagesShowCommand;
4747
use Symfony\Component\Messenger\Command\SetupTransportsCommand;
4848
use Symfony\Component\Messenger\Command\StopWorkersCommand;
49+
use Symfony\Component\Translation\Command\TranslationPullCommand;
50+
use Symfony\Component\Translation\Command\TranslationPushCommand;
4951
use Symfony\Component\Translation\Command\XliffLintCommand;
5052
use Symfony\Component\Validator\Command\DebugCommand as ValidatorDebugCommand;
5153

@@ -232,6 +234,26 @@
232234
])
233235
->tag('console.command')
234236

237+
->set('console.command.translation_pull', TranslationPullCommand::class)
238+
->args([
239+
service('translation.provider_collection'),
240+
service('translation.writer'),
241+
service('translation.reader'),
242+
param('kernel.default_locale'),
243+
[], // Translator paths
244+
[], // Enabled locales
245+
])
246+
->tag('console.command', ['command' => 'translation:pull'])
247+
248+
->set('console.command.translation_push', TranslationPushCommand::class)
249+
->args([
250+
service('translation.provider_collection'),
251+
service('translation.reader'),
252+
[], // Translator paths
253+
[], // Enabled locales
254+
])
255+
->tag('console.command', ['command' => 'translation:push'])
256+
235257
->set('console.command.workflow_dump', WorkflowDumpCommand::class)
236258
->tag('console.command')
237259

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
<xsd:element name="path" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
177177
<xsd:element name="enabled-locale" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
178178
<xsd:element name="pseudo-localization" type="pseudo_localization" minOccurs="0" maxOccurs="1" />
179+
<xsd:element name="provider" type="translation_provider" minOccurs="0" maxOccurs="unbounded" />
179180
</xsd:sequence>
180181
<xsd:attribute name="enabled" type="xsd:boolean" />
181182
<xsd:attribute name="fallback" type="xsd:string" />
@@ -195,6 +196,15 @@
195196
<xsd:attribute name="parse_html" type="xsd:boolean" />
196197
</xsd:complexType>
197198

199+
<xsd:complexType name="translation_provider">
200+
<xsd:sequence>
201+
<xsd:element name="domain" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
202+
<xsd:element name="locale" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
203+
</xsd:sequence>
204+
<xsd:attribute name="name" type="xsd:string" />
205+
<xsd:attribute name="dsn" type="xsd:string" />
206+
</xsd:complexType>
207+
198208
<xsd:complexType name="validation">
199209
<xsd:choice minOccurs="0" maxOccurs="unbounded">
200210
<xsd:element name="static-method" type="xsd:string" />
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
13+
14+
use Symfony\Component\Translation\Bridge\Loco\Provider\LocoProviderFactory;
15+
use Symfony\Component\Translation\Provider\NullProviderFactory;
16+
use Symfony\Component\Translation\Provider\TranslationProviderCollection;
17+
use Symfony\Component\Translation\Provider\TranslationProviderCollectionFactory;
18+
19+
return static function (ContainerConfigurator $container) {
20+
$container->services()
21+
->set('translation.provider_collection', TranslationProviderCollection::class)
22+
->factory([service('translation.provider_collection_factory'), 'fromConfig'])
23+
->args([
24+
[], // Providers
25+
])
26+
27+
->set('translation.provider_collection_factory', TranslationProviderCollectionFactory::class)
28+
->args([
29+
tagged_iterator('translation.provider_factory'),
30+
[], // Enabled locales
31+
])
32+
33+
->set('translation.provider_factory.null', NullProviderFactory::class)
34+
->tag('translation.provider_factory')
35+
36+
->set('translation.provider_factory.loco', LocoProviderFactory::class)
37+
->args([
38+
service('http_client'),
39+
service('logger'),
40+
param('kernel.default_locale'),
41+
service('translation.loader.xliff'),
42+
])
43+
->tag('translation.provider_factory')
44+
;
45+
};

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ protected static function getBundleDefaultConfig()
418418
'parse_html' => false,
419419
'localizable_html_attributes' => [],
420420
],
421+
'providers' => [],
421422
],
422423
'validation' => [
423424
'enabled' => !class_exists(FullStack::class),
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/Tests export-ignore
2+
/phpunit.xml.dist export-ignore
3+
/.gitattributes export-ignore
4+
/.gitignore export-ignore

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.