Skip to content

[Translation] Improve LocaleSwitcher a bit #46045

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 14, 2022

Conversation

nicolas-grekas
Copy link
Member

Q A
Branch? 6.1
Bug fix? no
New feature? no
Deprecations? no
Tickets -
License MIT
Doc PR -

Today's blog post made me review #45793. Here are changes I think would be nice doing.

This is an edgy feature btw to me because it builds on mutable services. An idea that I did not submit here would be to rename LocaleSwitcher to LocaleProvider and tell ppl that need the locale to use this instead of storing the locale as a string in a property. Dunno if that'd make sense to others.

@@ -164,22 +163,13 @@
->args([service(ContainerInterface::class)])
->tag('container.service_subscriber', ['id' => 'translator'])
->tag('kernel.cache_warmer')
;

if (class_exists(LocaleSwitcher::class)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be careful NOT doing conditional definition in the config files please. This logic is for DI extensions. Config files should remain purely declarative. /cc @symfony/mergers for future reviews.

if (class_exists(LocaleSwitcher::class)) {
$container->services()
->set('translation.locale_switcher', LocaleSwitcher::class)
->args([
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed wrong indentation also

use Symfony\Contracts\Translation\LocaleAwareInterface;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*/
final class LocaleSwitcher implements LocaleAwareInterface
class LocaleSwitcher implements LocaleAwareInterface
Copy link
Member Author

@nicolas-grekas nicolas-grekas Apr 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the class is registered as an autowiring alias, it means we're telling ppl they can type-hint for it. Type-hinting for a final class breaks many SOLID principles, so I removed the keyword.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imho, we should register LocaleAwareInterface as an autowiring alias, and not advocate typehinting implementations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works for get/setLocale, but runWithLocale isn't in any interfaces, and I'm not sure we want to add one for it.
I'm fine type-hinting with the implem personnaly, but only if it's open for inheritance of course.

{
$original = $this->getLocale();
$this->setLocale($locale);

try {
$callback();
return $callback();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's return the callback's result.

} finally {
$this->setLocale($original);
}
}

public function reset(): void
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Statefull services must at least reset their state.

Although the default locale is already set back in LocaleAwareListener::onKernelFinishRequest(), this doesn't cover eg message handlers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to implement ResetInterface?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not mandatory: ->tag('kernel.reset', ['method' => 'reset'])

@stof
Copy link
Member

stof commented Apr 14, 2022

well, we have a stateful place storing the locale anyway (\Locale::getDefault() in ext-intl). So we'll never eliminate the state entirely.
And we do have the LocaleAware contract, while adding a dependency on the LocaleSwitcher requires depending on the translation component.

@nicolas-grekas
Copy link
Member Author

adding a dependency on the LocaleSwitcher requires depending on the translation component.

LocaleSwitcher should be autowired as LocaleAwareInterface!

@kbond
Copy link
Member

kbond commented Apr 14, 2022

This is an edgy feature btw to me because it builds on mutable services.

Doesn't every LocaleAwareInterface service, by definition, carry mutable state?

@nicolas-grekas
Copy link
Member Author

Doesn't every LocaleAwareInterface service, by definition, carry mutable state?

yes, that's what I meant by "builds on mutable services" ;)

Copy link
Member

@kbond kbond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks good to me!

@fabpot
Copy link
Member

fabpot commented Apr 14, 2022

Thank you @nicolas-grekas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants