Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b9ac645

Browse files
neghmurkennicolas-grekas
authored andcommitted
Locale aware service registration
1 parent 4ad54da commit b9ac645

File tree

15 files changed

+339
-10
lines changed

15 files changed

+339
-10
lines changed

UPGRADE-4.3.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ HttpKernel
8686
* Renamed `GetResponseForControllerResultEvent` to `ViewEvent`
8787
* Renamed `GetResponseForExceptionEvent` to `ExceptionEvent`
8888
* Renamed `PostResponseEvent` to `TerminateEvent`
89+
* Deprecated `TranslatorListener` in favor of `LocaleAwareListener`
8990

9091
Messenger
9192
---------

UPGRADE-5.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ HttpKernel
232232
* Removed `GetResponseForControllerResultEvent`, use `ViewEvent` instead
233233
* Removed `GetResponseForExceptionEvent`, use `ExceptionEvent` instead
234234
* Removed `PostResponseEvent`, use `TerminateEvent` instead
235+
* Removed `TranslatorListener` in favor of `LocaleAwareListener`
235236

236237
Messenger
237238
---------

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ CHANGELOG
44
4.3.0
55
-----
66

7-
* added `WebTestAssertions` trait (included by default in `WebTestCase`)
8-
* renamed `Client` to `KernelBrowser`
7+
* Added `WebTestAssertionsTrait` (included by default in `WebTestCase`)
8+
* Renamed `Client` to `KernelBrowser`
99
* Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will
1010
be mandatory in 5.0.
1111
* Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead
1212
* Added the ability to specify a custom `serializer` option for each
1313
transport under`framework.messenger.transports`.
14+
* Added the `RegisterLocaleAwareServicesPass` and configured the `LocaleAwareListener`
1415
* [BC Break] When using Messenger, the default transport changed from
1516
using Symfony's serializer service to use `PhpSerializer`, which uses
1617
PHP's native `serialize()` and `unserialize()` functions. To use the

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class UnusedTagsPass implements CompilerPassInterface
4040
'kernel.event_listener',
4141
'kernel.event_subscriber',
4242
'kernel.fragment_renderer',
43+
'kernel.locale_aware',
4344
'messenger.bus',
4445
'messenger.receiver',
4546
'messenger.message_handler',

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
use Symfony\Contracts\HttpClient\HttpClientInterface;
120120
use Symfony\Contracts\Service\ResetInterface;
121121
use Symfony\Contracts\Service\ServiceSubscriberInterface;
122+
use Symfony\Contracts\Translation\LocaleAwareInterface;
122123

123124
/**
124125
* FrameworkExtension.
@@ -370,6 +371,8 @@ public function load(array $configs, ContainerBuilder $container)
370371
->addTag('kernel.cache_warmer');
371372
$container->registerForAutoconfiguration(EventSubscriberInterface::class)
372373
->addTag('kernel.event_subscriber');
374+
$container->registerForAutoconfiguration(LocaleAwareInterface::class)
375+
->addTag('kernel.locale_aware');
373376
$container->registerForAutoconfiguration(ResetInterface::class)
374377
->addTag('kernel.reset', ['method' => 'reset']);
375378

src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass;
4242
use Symfony\Component\HttpKernel\DependencyInjection\LoggerPass;
4343
use Symfony\Component\HttpKernel\DependencyInjection\RegisterControllerArgumentLocatorsPass;
44+
use Symfony\Component\HttpKernel\DependencyInjection\RegisterLocaleAwareServicesPass;
4445
use Symfony\Component\HttpKernel\DependencyInjection\RemoveEmptyControllerArgumentLocatorsPass;
4546
use Symfony\Component\HttpKernel\DependencyInjection\ResettableServicePass;
4647
use Symfony\Component\HttpKernel\KernelEvents;
@@ -121,6 +122,7 @@ public function build(ContainerBuilder $container)
121122
$this->addCompilerPassIfExists($container, FormPass::class);
122123
$container->addCompilerPass(new WorkflowGuardListenerPass());
123124
$container->addCompilerPass(new ResettableServicePass());
125+
$container->addCompilerPass(new RegisterLocaleAwareServicesPass());
124126
$container->addCompilerPass(new TestServiceContainerWeakRefPass(), PassConfig::TYPE_BEFORE_REMOVING, -32);
125127
$container->addCompilerPass(new TestServiceContainerRealRefPass(), PassConfig::TYPE_AFTER_REMOVING);
126128
$this->addCompilerPassIfExists($container, AddMimeTypeGuesserPass::class);

src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,5 +112,11 @@
112112
<argument type="service_locator" />
113113
</service>
114114
<service id="Symfony\Component\DependencyInjection\ReverseContainer" alias="reverse_container" />
115+
116+
<service id="locale_aware_listener" class="Symfony\Component\HttpKernel\EventListener\LocaleAwareListener">
117+
<argument type="collection" /> <!-- locale aware services -->
118+
<argument type="service" id="request_stack" />
119+
<tag name="kernel.event_subscriber" />
120+
</service>
115121
</services>
116122
</container>

src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<call method="setConfigCacheFactory">
2020
<argument type="service" id="config_cache_factory" />
2121
</call>
22+
<tag name="kernel.locale_aware" />
2223
</service>
2324
<service id="Symfony\Component\Translation\TranslatorInterface" alias="translator" />
2425
<service id="Symfony\Contracts\Translation\TranslatorInterface" alias="translator" />
@@ -140,11 +141,5 @@
140141
<tag name="kernel.cache_warmer" />
141142
<argument type="service" id="Psr\Container\ContainerInterface" />
142143
</service>
143-
144-
<service id="translator_listener" class="Symfony\Component\HttpKernel\EventListener\TranslatorListener">
145-
<argument type="service" id="translator" />
146-
<argument type="service" id="request_stack" />
147-
<tag name="kernel.event_subscriber" />
148-
</service>
149144
</services>
150145
</container>

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ CHANGELOG
88
* `KernelInterface` doesn't extend `Serializable` anymore
99
* deprecated the `Kernel::serialize()` and `unserialize()` methods
1010
* increased the priority of `Symfony\Component\HttpKernel\EventListener\AddRequestFormatsListener`
11-
* made `Symfony\Component\HttpKernel\EventListenerLocaleListener` set the default locale early
11+
* made `Symfony\Component\HttpKernel\EventListener\LocaleListener` set the default locale early
12+
* deprecated `TranslatorListener` in favor of `LocaleAwareListener`
13+
* added the registration of all `LocaleAwareInterface` implementations into the `LocaleAwareListener`
1214
* made `FileLinkFormatter` final and not implement `Serializable` anymore
1315
* the base `DataCollector` doesn't implement `Serializable` anymore, you should
1416
store all the serialized state in the data property instead
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\HttpKernel\DependencyInjection;
13+
14+
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
15+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
19+
/**
20+
* Register all services that have the "kernel.locale_aware" tag into the listener.
21+
*
22+
* @author Pierre Bobiet <[email protected]>
23+
*/
24+
class RegisterLocaleAwareServicesPass implements CompilerPassInterface
25+
{
26+
private $listenerServiceId;
27+
private $localeAwareTag;
28+
29+
public function __construct(string $listenerServiceId = 'locale_aware_listener', string $localeAwareTag = 'kernel.locale_aware')
30+
{
31+
$this->listenerServiceId = $listenerServiceId;
32+
$this->localeAwareTag = $localeAwareTag;
33+
}
34+
35+
public function process(ContainerBuilder $container)
36+
{
37+
if (!$container->hasDefinition($this->listenerServiceId)) {
38+
return;
39+
}
40+
41+
$services = [];
42+
43+
foreach ($container->findTaggedServiceIds($this->localeAwareTag) as $id => $tags) {
44+
$services[] = new Reference($id);
45+
}
46+
47+
if (!$services) {
48+
$container->removeDefinition($this->listenerServiceId);
49+
50+
return;
51+
}
52+
53+
$container
54+
->getDefinition($this->listenerServiceId)
55+
->setArgument(0, new IteratorArgument($services))
56+
;
57+
}
58+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\HttpKernel\EventListener;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\RequestStack;
17+
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
18+
use Symfony\Component\HttpKernel\Event\RequestEvent;
19+
use Symfony\Component\HttpKernel\KernelEvents;
20+
use Symfony\Contracts\Translation\LocaleAwareInterface;
21+
22+
/**
23+
* Pass the current locale to the provided services.
24+
*
25+
* @author Pierre Bobiet <[email protected]>
26+
*/
27+
class LocaleAwareListener implements EventSubscriberInterface
28+
{
29+
private $localeAwareServices;
30+
private $requestStack;
31+
32+
/**
33+
* @param LocaleAwareInterface[] $localeAwareServices
34+
*/
35+
public function __construct(iterable $localeAwareServices, RequestStack $requestStack)
36+
{
37+
$this->localeAwareServices = $localeAwareServices;
38+
$this->requestStack = $requestStack;
39+
}
40+
41+
public function onKernelRequest(RequestEvent $event): void
42+
{
43+
$this->setLocale($event->getRequest()->getLocale(), $event->getRequest()->getDefaultLocale());
44+
}
45+
46+
public function onKernelFinishRequest(FinishRequestEvent $event): void
47+
{
48+
if (null === $parentRequest = $this->requestStack->getParentRequest()) {
49+
$this->setLocale($event->getRequest()->getDefaultLocale());
50+
51+
return;
52+
}
53+
54+
$this->setLocale($parentRequest->getLocale(), $parentRequest->getDefaultLocale());
55+
}
56+
57+
public static function getSubscribedEvents()
58+
{
59+
return [
60+
// must be registered after the Locale listener
61+
KernelEvents::REQUEST => [['onKernelRequest', 15]],
62+
KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', -15]],
63+
];
64+
}
65+
66+
private function setLocale(string $locale, ?string $defaultLocale = null): void
67+
{
68+
foreach ($this->localeAwareServices as $service) {
69+
try {
70+
$service->setLocale($locale);
71+
} catch (\InvalidArgumentException $e) {
72+
$service->setLocale($defaultLocale);
73+
}
74+
}
75+
}
76+
}

src/Symfony/Component/HttpKernel/EventListener/TranslatorListener.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\HttpKernel\EventListener;
1313

14+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3 and will be removed in 5.0, use LocaleAwareListener instead.', TranslatorListener::class), E_USER_DEPRECATED);
15+
1416
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1517
use Symfony\Component\HttpFoundation\Request;
1618
use Symfony\Component\HttpFoundation\RequestStack;
@@ -25,7 +27,7 @@
2527
*
2628
* @author Fabien Potencier <[email protected]>
2729
*
28-
* @final since Symfony 4.3
30+
* @deprecated since Symfony 4.3, use LocaleAwareListener instead
2931
*/
3032
class TranslatorListener implements EventSubscriberInterface
3133
{
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace Symfony\Component\HttpKernel\Tests\DependencyInjection;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
7+
use Symfony\Component\DependencyInjection\ContainerBuilder;
8+
use Symfony\Component\DependencyInjection\Reference;
9+
use Symfony\Component\HttpKernel\DependencyInjection\RegisterLocaleAwareServicesPass;
10+
use Symfony\Component\HttpKernel\EventListener\LocaleAwareListener;
11+
use Symfony\Contracts\Translation\LocaleAwareInterface;
12+
13+
class RegisterLocaleAwareServicesPassTest extends TestCase
14+
{
15+
public function testCompilerPass()
16+
{
17+
$container = new ContainerBuilder();
18+
19+
$container->register('locale_aware_listener', LocaleAwareListener::class)
20+
->setPublic(true)
21+
->setArguments([null, null]);
22+
23+
$container->register('some_locale_aware_service', LocaleAwareInterface::class)
24+
->setPublic(true)
25+
->addTag('kernel.locale_aware');
26+
27+
$container->register('another_locale_aware_service', LocaleAwareInterface::class)
28+
->setPublic(true)
29+
->addTag('kernel.locale_aware');
30+
31+
$container->addCompilerPass(new RegisterLocaleAwareServicesPass());
32+
$container->compile();
33+
34+
$this->assertEquals(
35+
[
36+
new IteratorArgument([
37+
0 => new Reference('some_locale_aware_service'),
38+
1 => new Reference('another_locale_aware_service'),
39+
]),
40+
null,
41+
],
42+
$container->getDefinition('locale_aware_listener')->getArguments()
43+
);
44+
}
45+
46+
public function testListenerUnregisteredWhenNoLocaleAwareServices()
47+
{
48+
$container = new ContainerBuilder();
49+
50+
$container->register('locale_aware_listener', LocaleAwareListener::class)
51+
->setPublic(true)
52+
->setArguments([null, null]);
53+
54+
$container->addCompilerPass(new RegisterLocaleAwareServicesPass());
55+
$container->compile();
56+
57+
$this->assertFalse($container->hasDefinition('locale_aware_listener'));
58+
}
59+
}

0 commit comments

Comments
 (0)