9

I have to change the locale dynamically depending which language the user wants.

I can set the locale in the Application/Module.php like this :

public function onBootstrap(MvcEvent $e)
{
    $translator = $e->getApplication()->getServiceManager()->get('translator');
    $translator->setLocale('hu_HU');
}

But, how can I do this in the controller, if I want to change languages ? I tried this, but after this I can change the locale only for this one request and not global.

$translator = $this->getServiceLocator()->get('translator');
$translator->setLocale('srb_SRB');
sgleser87
  • 235
  • 1
  • 3
  • 11

5 Answers5

2

Set up the default locale at configuration level! See #61 of module.config.php from ZendSkeletonApplications Application Module

'translator' => array(
    'locale' => 'en_US',
)
Sam
  • 16,435
  • 6
  • 55
  • 89
  • But I have to change it dynamically, depending on user. – sgleser87 Apr 11 '13 at 11:03
  • That would be set per Request then, based on Users Session data (or UserEntity) – Sam Apr 11 '13 at 11:26
  • @sgleser87 the point is that you **must not** change it in the code, which must contain only the default value – Matteo Tassinari Apr 11 '13 at 12:19
  • Ok, but how do you handle than language changes ? You have to set it on every request again? That's too much code which you should set only once. – sgleser87 Apr 11 '13 at 13:37
  • This is what SESSION-DATA is about. Yes, you have to re-change it on every single request. You can not write an application on a per-user-basis, but you can change data depending on the user. THis is what you code for Oo – Sam Apr 11 '13 at 14:17
  • @Sam i am trying to set local $translator->getLocale('hin_IN'); but found always a default local when i am using this $translator->getLocale(); give en_IN but i am wondor i did not add this local in any location in my project . this is working in 2.1.1 perfect but not work in 2.3.3dev when i upgrade this version . please help me. – Bineet Chaubey Aug 22 '13 at 07:36
1

This work for me:

public function onBootstrap(MvcEvent $e)
{
    $localeFromHttp = \Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
            if (false === stripos($localeFromHttp, '-')) {
                $locale = $localeFromHttp . '_' . strtoupper($localeFromHttp);

                $e->getApplication()
                    ->getServiceManager()
                    ->get('MvcTranslator')
                    ->setLocale($locale);               
               }
               else {

                   $e->getApplication()->getServiceManager()->get('MvcTranslator')->setFallbackLocale('en_US');
               }

}

And my modal.config.php:

'service_manager' => array(
     'abstract_factories' => array(
         'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
         'Zend\Log\LoggerAbstractServiceFactory',
     ),
     'aliases' => array(
         'translator' => 'MvcTranslator',
     ),
 ),
 'service_manager' => array(
     'factories' => array(
         'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
     ),
 ),
 'translator' => array(
     'translation_file_patterns' => array(
         array(
             'type'     => 'gettext',
             'base_dir' => __DIR__ . '/../language',
             'pattern'  => '%s.mo',
             'text_domain' => __NAMESPACE__,
         ),
     ),
 ),
Oskar
  • 2,522
  • 32
  • 37
1

I had the same issue. In my user login module, I registered for MvcEvent on bootstrap:

use Zend\Mvc\MvcEvent;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Session\SessionManager;
use Zend\Session\Container as SessionContainer;
use \Zend\I18n\Translator\TranslatorInterface;

... 

public function onBootstrap(MvcEvent $event)
{
    // Get event manager.
    $eventManager = $event->getApplication()->getEventManager();
    $sharedEventManager = $eventManager->getSharedManager();
    // Register the event listener method. 
    $sharedEventManager->attach(AbstractActionController::class, 
            MvcEvent::EVENT_DISPATCH, [$this, 'onDispatch'], 100);
}

Then when that event comes, I set the locale based on info from the URL:

public function onDispatch(MvcEvent $event)
{
    $servicemanager = $event->getApplication()->getServiceManager();
    $lang = $event->getRouteMatch()->getParam('lang','jp-JP');

    $translator = $servicemanager->get(TranslatorInterface::class);
    if( $translator != null )
    {
        $translator->setLocale($lang);
    } 
    ...

In the end, this does not really make the locale global - instead, it just sets it for every request. The net effect is the same, from the code point of view - i.e., I don't have to set the locale on every controller.

Hope that helps.

alex gimenez
  • 163
  • 11
0

In the modal.config file, I do not think that the following is required as you have used the alias 'MvcTranslator' for translator.

'service_manager' => array(
'factories' => array(
    'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
Cleb
  • 25,102
  • 20
  • 116
  • 151
Pat
  • 325
  • 2
  • 11
0

In ZF2 locale is set always per request. You can do that on bootstrap:

$translator = $event->getApplication()->getServiceManager()->get('translator');
$translator->setLocale($locale);
$translator->addTranslationFile(
        'phpArray', DATA_PATH . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . $locale . '.php', 'default', $locale
);

and later in controller, if You want to change:

$translator = $this->getServicelocator()->get('translator');
$translator->setLocale($locale);

if You change selected locale, You have to add translation file path again to make it works

Marcin Żurek
  • 145
  • 1
  • 3