2017-03-02 91 views
0

我有Zend Framework 3应用程序与工作翻译使用po文件。zf3更改区域设置取决于用户选择

我有这样的配置在我的\设置\ global.php文件:

'translator' => [ 
    'locale' => 'en_US', 
    'translation_file_patterns' => [ 
     [ 
      'type'  => 'gettext', 
      'base_dir' => getcwd() . '/data/language/', 
      'pattern' => '/%s/general.mo', 
     ], 
    ], 
], 

当我改变的价值“区域设置”它的工作原理确定并找到正确的.po文件。 我需要能够根据保存在数据库中的用户配置文件的值来设置区域设置。

我检查了这里的文档http://zendframework.github.io/zend-i18n/translation/和这里的教程https://docs.zendframework.com/tutorials/i18n/,但他们只是提到setLocale()方法,没有解释或例子。这里有类似的线程Zend framework 2 : How to set locale globaly?,但它是ZF2,它不提供工作解决方案只是一些建议。

总结我的问题 - 我应该如何以及在哪里使用setLocale()方法,以便在整个应用程序中有效,并且所有视图文件中的$this->translate($message)将使用新的区域设置,而不是配置文件中使用的默认区域?

回答

0

你只需要设置PHP语言环境。为此,请使用\Locale::setDefault('en-GB');

看看SlmLocale,这个特定的文件就是在那里完成的。


虽然这是最简单的方法,你也可以使用上我猜MvcTranslator的setLocale功能。为此,您需要用自己的工厂覆盖现有的工厂,因此可以装饰原有的工厂。

如果你看看ConfigProvider file in zend-mvc-i18n,你可以看到在这里使用别名和工厂来创建MVC转换器。然后你可以看到问题工厂的工作原理,它基本上创建了一个装饰翻译器,如stated in the doc

默认情况下,服务管理器总是提供相同的实例(共享服务),就像单例一样。

因此,我们要做的就是覆盖这个配置(即确保你自己的模块位于Zend\Mvc\I18nmodules.config.php之后)。然后,在模块配置中,我们可以提供我们自己的翻译器。

我们的翻译基本上由文档翻译器组成,其中调用了setLocale。为了做到这一点,我们可以使用delegator

return [ 
    'factories' => [ 
     TranslatorInterface::class => TranslatorServiceFactory::class, 
    ], 
    'delegators' => [ 
     TranslatorInterface::class => [ 
      \Application\Factory\TranslatorFactory::class, 
     ], 
    ], 
]; 

然后是TranslatorFactory

use Interop\Container\ContainerInterface; 
use Zend\ServiceManager\Factory\DelegatorFactoryInterface; 

class TranslatorFactory implements DelegatorFactoryInterface 
{ 
    public function __invoke(ContainerInterface $container, $name, callable $callback, array $options = null) 
    { 
     $translator = call_user_func($callback); 
     $translator->setLocale('en-GB'); 
     return $translator; 
    } 
} 

这将是这样做(你得到的容器在那家工厂,所以你可以得到一些用户的数据可能)的一种方式。


另一种解决方案是使用事件系统,并且只声明事件侦听器中的区域设置,以检索用户详细信息。

+0

谢谢托马斯,这真的有用,我也会尝试与工厂,但我会感谢一些帮助。我认为在这种情况下使用框架工具会更加一致。我会给其他人建议其他东西的机会,如果没有人跳过,我会将您的答案标记为“已接受”。再次感谢你, – Ivomasterche

+0

我刚刚更新了答案...这是一个稍长的IMO,可能在某个时候有点混淆,如果需要,请询问更多细节。 –

+0

再次感谢您。我想我明白了 - 我们用这个委托人“包装”翻译服务,每次调用'$ this-> translate($ msg)'时都应该调用它(并设置语言环境)。不幸的是,我无法让它工作,我已经将配置添加到应用程序模块的module.config.php,并且我在/Application/src/Factory/TranslatorFactory.php文件中创建了TranslatorFactory类是这一切吗? – Ivomasterche