0

I need to make translation dependent on data stored in User entity. For example, i have User entity with column Language. If user has EN in it, i need to translate views into english etc. After logging in i need to check what type of language has user and load translated view.

Should i use for that https://symfony.com/doc/current/event_dispatcher.html if i do how should i do it?

I have tried make something with Locale setDefault function in IF statement but it dosen't work.

My translation.yaml :

framework:
default_locale: '%locale%'
translator:
    default_path: '%kernel.project_dir%/translations'
    fallbacks:
        - '%locale%'

And my services.yaml

parameters:
locale: ru
app_locales: ru|uk
jakmen
  • 93
  • 10

1 Answers1

0

Yes, EventDispatcher is the way to go. Most likely you want to use the kernel.request-event for this. If you need the language from your logged in user, you have to be careful when your listener is called as it has to run after the Firewall-EventSubscriber which loads the logged in user. You can control the order by specifying the priority.

In your listener you should then be able to fetch the user and their language and overwrite the _locale attribute on the Request or add your own attribute for it. You can also store this info in the session, so you don't have to query for the user on each request. You can find examples for this on StackOverflow, e.g. here

dbrumann
  • 16,803
  • 2
  • 42
  • 58
  • Feel free to come back, when you encounter any problems with your implementation. Good luck :) – dbrumann Feb 14 '19 at 15:36
  • I have one more question, how exactly i can fetch information from user entity in EventListener? I made LanguageListener where i made $user = $this->tokenStorage->getToken()->getUser(); I see representation of User in dump() but how i can get value from one of column in User Entity? – jakmen Feb 15 '19 at 14:42
  • Yes, using the TokenStorage is the recommended way. When you call `$this->tokenStorage->getToken()->getUser()` you can check if it's an instance of your expected class, since it can also be null or just a string (when no firewall is used or the user is not logged, i.e. anonymous user). Then you can use the method from your entity class, e.g. if your user has a `getPreferredUserLocale()` it would look like this: `if ($user instanceof User::class) { $locale = $user->getPreferredUserLocale(); }` – dbrumann Feb 15 '19 at 14:48
  • I'm sorry to bother you again but i have another question, I can change my Locale based on Language in User Entity with advice you gave me but it dosen't work with translation. My services.yaml and translation.yaml files looks like above. When i change manually locale in services.yaml it works fine – jakmen Feb 18 '19 at 07:51
  • The translator is initialized with a locale, you have to tell it which locale is currently used. You can either call `$translator->setLocale($user->getPreferredLocale());`, e.g. in your listener, or you can pass the locale to each translation call as 4th argument `$translator->trans('my_key', [], null, $user->getPreferredLocale());`. In a template it's a bit shorter, because Twig supports named arguments: `{{ 'my_key'|trans(locale=app.user.preferredLocale) }}` – dbrumann Feb 18 '19 at 08:30
  • Ok, in Twig everything works fine but i can't call Translator in my listener, when i put Translator into __construct i get error Cannot autowire service "App\EventListener\LanguageListener": argument "$translator" of method "__construct()" references class "Symfony\Bundle\FrameworkBundle\Translation\Translator" but no such service exists – jakmen Feb 18 '19 at 12:17
  • It could be that the Translator locale is initialized later (which would make sense). In that case you could either create another listener that listens after Symfony's LocaleListener or you just update the Request, by overwriting the `_locale` and then the default LocaleListener will pick up the change and should use your preferred locale. – dbrumann Feb 18 '19 at 12:28