Skip to content

Commit 4fc3d73

Browse files
committed
Merge branch '5.4' into 6.0
* 5.4: fix SQLSRV throws for method_exists() [HttpKernel] Add basic support for language negotiation [Messenger] Add a middleware to log when transaction has been left open [HttpClient] Add method to set response factory in mock client Move array_merge calls out of loops to improve performance Remove references to DBALException [VarDumper] Fix handling of "new" in initializers on PHP 8.1
2 parents 736d0be + 5aa6e8f commit 4fc3d73

File tree

18 files changed

+147
-23
lines changed

18 files changed

+147
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ CHANGELOG
2424
5.4
2525
---
2626

27+
* Add `set_locale_from_accept_language` config option to automatically set the request locale based on the `Accept-Language`
28+
HTTP request header and the `framework.enabled_locales` config option
29+
* Add `set_content_language_from_locale` config option to automatically set the `Content-Language` HTTP response header based on the Request locale
30+
* Deprecate the `framework.translator.enabled_locales`, use `framework.enabled_locales` instead
2731
* Add autowiring alias for `HttpCache\StoreInterface`
2832
* Deprecate the `AdapterInterface` autowiring alias, use `CacheItemPoolInterface` instead
2933
* Deprecate the public `profiler` service to private

DependencyInjection/Configuration.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public function getConfigTreeBuilder(): TreeBuilder
7373
return $v;
7474
})
7575
->end()
76+
->fixXmlConfig('enabled_locale')
7677
->children()
7778
->scalarNode('secret')->end()
7879
->scalarNode('http_method_override')
@@ -82,6 +83,18 @@ public function getConfigTreeBuilder(): TreeBuilder
8283
->scalarNode('ide')->defaultNull()->end()
8384
->booleanNode('test')->end()
8485
->scalarNode('default_locale')->defaultValue('en')->end()
86+
->booleanNode('set_locale_from_accept_language')
87+
->info('Whether to use the Accept-Language HTTP header to set the Request locale (only when the "_locale" request attribute is not passed).')
88+
->defaultFalse()
89+
->end()
90+
->booleanNode('set_content_language_from_locale')
91+
->info('Whether to set the Content-Language HTTP header on the Response using the Request locale.')
92+
->defaultFalse()
93+
->end()
94+
->arrayNode('enabled_locales')
95+
->info('Defines the possible locales for the application. This list is used for generating translations files, but also to restrict which locales are allowed when it is set from Accept-Language header (using "set_locale_from_accept_language").')
96+
->prototype('scalar')->end()
97+
->end()
8598
->arrayNode('trusted_hosts')
8699
->beforeNormalization()->ifString()->then(function ($v) { return [$v]; })->end()
87100
->prototype('scalar')->end()
@@ -792,6 +805,7 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode, callable $e
792805
->prototype('scalar')->end()
793806
->end()
794807
->arrayNode('enabled_locales')
808+
->setDeprecated('symfony/framework-bundle', '5.3', 'Option "%node%" at "%path%" is deprecated, set the "framework.enabled_locales" option instead.')
795809
->prototype('scalar')->end()
796810
->defaultValue([])
797811
->end()
@@ -826,7 +840,7 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode, callable $e
826840
->arrayNode('locales')
827841
->prototype('scalar')->end()
828842
->defaultValue([])
829-
->info('If not set, all locales listed under framework.translator.enabled_locales are used.')
843+
->info('If not set, all locales listed under framework.enabled_locales are used.')
830844
->end()
831845
->end()
832846
->end()
@@ -1240,15 +1254,13 @@ private function addLockSection(ArrayNodeDefinition $rootNode, callable $enableI
12401254
->then(function ($v) {
12411255
$resources = [];
12421256
foreach ($v as $resource) {
1243-
$resources = array_merge_recursive(
1244-
$resources,
1245-
\is_array($resource) && isset($resource['name'])
1246-
? [$resource['name'] => $resource['value']]
1247-
: ['default' => $resource]
1248-
);
1257+
$resources[] = \is_array($resource) && isset($resource['name'])
1258+
? [$resource['name'] => $resource['value']]
1259+
: ['default' => $resource]
1260+
;
12491261
}
12501262

1251-
return $resources;
1263+
return array_merge_recursive([], ...$resources);
12521264
})
12531265
->end()
12541266
->prototype('array')

DependencyInjection/FrameworkExtension.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ public function load(array $configs, ContainerBuilder $container)
274274
}
275275
}
276276

277+
$container->getDefinition('locale_listener')->replaceArgument(3, $config['set_locale_from_accept_language']);
278+
$container->getDefinition('response_listener')->replaceArgument(1, $config['set_content_language_from_locale']);
279+
277280
// If the slugger is used but the String component is not available, we should throw an error
278281
if (!ContainerBuilder::willBeAvailable('symfony/string', SluggerInterface::class, ['symfony/framework-bundle'])) {
279282
$container->register('slugger', 'stdClass')
@@ -296,6 +299,7 @@ public function load(array $configs, ContainerBuilder $container)
296299
$container->setParameter('kernel.http_method_override', $config['http_method_override']);
297300
$container->setParameter('kernel.trusted_hosts', $config['trusted_hosts']);
298301
$container->setParameter('kernel.default_locale', $config['default_locale']);
302+
$container->setParameter('kernel.enabled_locales', $config['enabled_locales']);
299303
$container->setParameter('kernel.error_controller', $config['error_controller']);
300304

301305
if (($config['trusted_proxies'] ?? false) && ($config['trusted_headers'] ?? false)) {
@@ -417,11 +421,13 @@ public function load(array $configs, ContainerBuilder $container)
417421
$this->registerEsiConfiguration($config['esi'], $container, $loader);
418422
$this->registerSsiConfiguration($config['ssi'], $container, $loader);
419423
$this->registerFragmentsConfiguration($config['fragments'], $container, $loader);
420-
$this->registerTranslatorConfiguration($config['translator'], $container, $loader, $config['default_locale']);
424+
$this->registerTranslatorConfiguration($config['translator'], $container, $loader, $config['default_locale'], $config['enabled_locales']);
421425
$this->registerProfilerConfiguration($config['profiler'], $container, $loader);
422426
$this->registerWorkflowConfiguration($config['workflows'], $container, $loader);
423427
$this->registerDebugConfiguration($config['php_errors'], $container, $loader);
424-
$this->registerRouterConfiguration($config['router'], $container, $loader, $config['translator']['enabled_locales'] ?? []);
428+
// @deprecated since Symfony 5.4, in 6.0 change to:
429+
// $this->registerRouterConfiguration($config['router'], $container, $loader, $config['enabled_locales']);
430+
$this->registerRouterConfiguration($config['router'], $container, $loader, $config['translator']['enabled_locales'] ?: $config['enabled_locales']);
425431
$this->registerAnnotationsConfiguration($config['annotations'], $container, $loader);
426432
$this->registerPropertyAccessConfiguration($config['property_access'], $container, $loader);
427433
$this->registerSecretsConfiguration($config['secrets'], $container, $loader);
@@ -1187,7 +1193,7 @@ private function createVersion(ContainerBuilder $container, ?string $version, ?s
11871193
return new Reference('assets.empty_version_strategy');
11881194
}
11891195

1190-
private function registerTranslatorConfiguration(array $config, ContainerBuilder $container, LoaderInterface $loader, string $defaultLocale)
1196+
private function registerTranslatorConfiguration(array $config, ContainerBuilder $container, LoaderInterface $loader, string $defaultLocale, array $enabledLocales)
11911197
{
11921198
if (!$this->isConfigEnabled($container, $config)) {
11931199
$container->removeDefinition('console.command.translation_debug');
@@ -1211,7 +1217,9 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
12111217
$defaultOptions['cache_dir'] = $config['cache_dir'];
12121218
$translator->setArgument(4, $defaultOptions);
12131219

1214-
$translator->setArgument(5, $config['enabled_locales']);
1220+
// @deprecated since Symfony 5.4, in 6.0 change to:
1221+
// $translator->setArgument(5, $enabledLocales);
1222+
$translator->setArgument(5, $config['enabled_locales'] ?: $enabledLocales);
12151223

12161224
$container->setParameter('translator.logging', $config['logging']);
12171225
$container->setParameter('translator.default_path', $config['default_path']);
@@ -1344,7 +1352,9 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
13441352
return;
13451353
}
13461354

1347-
$locales = $config['enabled_locales'] ?? [];
1355+
// @deprecated since Symfony 5.4, in 6.0 change to:
1356+
// $locales = $enabledLocales;
1357+
$locales = $config['enabled_locales'] ?: $enabledLocales;
13481358

13491359
foreach ($config['providers'] as $provider) {
13501360
if ($provider['locales']) {

Resources/config/schema/symfony-1.0.xsd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,15 @@
3838
<xsd:element name="rate-limiter" type="rate_limiter" minOccurs="0" maxOccurs="1" />
3939
<xsd:element name="uid" type="uid" minOccurs="0" maxOccurs="1" />
4040
<xsd:element name="notifier" type="notifier" minOccurs="0" maxOccurs="1" />
41+
<xsd:element name="enabled-locale" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
4142
</xsd:choice>
4243

4344
<xsd:attribute name="http-method-override" type="xsd:boolean" />
4445
<xsd:attribute name="ide" type="xsd:string" />
4546
<xsd:attribute name="secret" type="xsd:string" />
4647
<xsd:attribute name="default-locale" type="xsd:string" />
48+
<xsd:attribute name="set_locale_from_accept_language" type="xsd:boolean" />
49+
<xsd:attribute name="set_content_language_from_locale" type="xsd:boolean" />
4750
<xsd:attribute name="test" type="xsd:boolean" />
4851
<xsd:attribute name="error-controller" type="xsd:string" />
4952
<xsd:attribute name="trusted-hosts" type="xsd:string" />

Resources/config/web.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
->set('response_listener', ResponseListener::class)
7070
->args([
7171
param('kernel.charset'),
72+
abstract_arg('The "set_content_language_from_locale" config value'),
73+
param('kernel.enabled_locales'),
7274
])
7375
->tag('kernel.event_subscriber')
7476

@@ -80,6 +82,8 @@
8082
service('request_stack'),
8183
param('kernel.default_locale'),
8284
service('router')->ignoreOnInvalid(),
85+
abstract_arg('The "set_locale_from_accept_language" config value'),
86+
param('kernel.enabled_locales'),
8387
])
8488
->tag('kernel.event_subscriber')
8589

Tests/CacheWarmer/SerializerCacheWarmerTest.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,17 @@
1515
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
1616
use Symfony\Component\Cache\Adapter\NullAdapter;
1717
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
18+
use Symfony\Component\Serializer\Mapping\Loader\LoaderChain;
1819
use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader;
1920
use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader;
2021

2122
class SerializerCacheWarmerTest extends TestCase
2223
{
23-
public function testWarmUp()
24+
/**
25+
* @dataProvider loaderProvider
26+
*/
27+
public function testWarmUp(array $loaders)
2428
{
25-
$loaders = [
26-
new XmlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/person.xml'),
27-
new YamlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/author.yml'),
28-
];
29-
3029
$file = sys_get_temp_dir().'/cache-serializer.php';
3130
@unlink($file);
3231

@@ -41,6 +40,26 @@ public function testWarmUp()
4140
$this->assertTrue($arrayPool->getItem('Symfony_Bundle_FrameworkBundle_Tests_Fixtures_Serialization_Author')->isHit());
4241
}
4342

43+
public function loaderProvider()
44+
{
45+
return [
46+
[
47+
[
48+
new LoaderChain([
49+
new XmlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/person.xml'),
50+
new YamlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/author.yml'),
51+
]),
52+
],
53+
],
54+
[
55+
[
56+
new XmlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/person.xml'),
57+
new YamlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/author.yml'),
58+
],
59+
],
60+
];
61+
}
62+
4463
public function testWarmUpWithoutLoader()
4564
{
4665
$file = sys_get_temp_dir().'/cache-serializer-without-loader.php';

Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ protected static function getBundleDefaultConfig()
370370
'http_method_override' => true,
371371
'ide' => null,
372372
'default_locale' => 'en',
373+
'enabled_locales' => [],
374+
'set_locale_from_accept_language' => false,
375+
'set_content_language_from_locale' => false,
373376
'secret' => 's3cr3t',
374377
'trusted_hosts' => [],
375378
'trusted_headers' => [

Tests/DependencyInjection/Fixtures/php/full.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
$container->loadFromExtension('framework', [
44
'secret' => 's3cr3t',
55
'default_locale' => 'fr',
6+
'enabled_locales' => ['fr', 'en'],
67
'csrf_protection' => true,
78
'form' => [
89
'csrf_protection' => [
@@ -50,7 +51,6 @@
5051
'fallback' => 'fr',
5152
'paths' => ['%kernel.project_dir%/Fixtures/translations'],
5253
'cache_dir' => '%kernel.cache_dir%/translations',
53-
'enabled_locales' => ['fr', 'en'],
5454
],
5555
'validation' => [
5656
'enabled' => true,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'secret' => 's3cr3t',
5+
'default_locale' => 'fr',
6+
'router' => [
7+
'resource' => '%kernel.project_dir%/config/routing.xml',
8+
'type' => 'xml',
9+
'utf8' => true,
10+
],
11+
'translator' => [
12+
'enabled' => true,
13+
'fallback' => 'fr',
14+
'paths' => ['%kernel.project_dir%/Fixtures/translations'],
15+
'cache_dir' => '%kernel.cache_dir%/translations',
16+
'enabled_locales' => ['fr', 'en'],
17+
],
18+
]);

Tests/DependencyInjection/Fixtures/xml/full.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
88

99
<framework:config secret="s3cr3t" ide="file%%link%%format" default-locale="fr" http-method-override="false">
10+
<framework:enabled-locale>fr</framework:enabled-locale>
11+
<framework:enabled-locale>en</framework:enabled-locale>
1012
<framework:csrf-protection />
1113
<framework:form legacy-error-messages="false">
1214
<framework:csrf-protection field-name="_csrf"/>
@@ -28,8 +30,6 @@
2830
<framework:assets version="v1" />
2931
<framework:translator enabled="true" fallback="fr" logging="true" cache-dir="%kernel.cache_dir%/translations">
3032
<framework:path>%kernel.project_dir%/Fixtures/translations</framework:path>
31-
<framework:enabled-locale>fr</framework:enabled-locale>
32-
<framework:enabled-locale>en</framework:enabled-locale>
3333
</framework:translator>
3434
<framework:validation enabled="true" />
3535
<framework:annotations cache="file" debug="true" file-cache-dir="%kernel.cache_dir%/annotations" />

0 commit comments

Comments
 (0)