zf3 меняет локаль в зависимости от выбора пользователя

У меня есть приложение Zend Framework 3 с работающим переводчиком, использующим po-файлы.

Я настроил это так в моем файле \ config \ global.php:

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

Когда я изменяю значение «locale», он работает нормально и находит правильный .po файл.
Мне нужно иметь возможность установить языковой стандарт в зависимости от значения профиля пользователя, сохраненного в базе данных.

Я проверил документацию отсюда http://zendframework.github.io/zend-i18n/translation/ и учебник отсюда https://docs.zendframework.com/tutorials/i18n/ но они просто упоминают метод setLocale () без объяснения или примера. Здесь есть похожая тема Zend Framework 2: Как установить глобальную локаль? но это для ZF2 и не дает рабочего решения, только некоторые предложения.

Подводя итог, мой вопрос — как и где я должен использовать метод setLocale (), чтобы он был эффективным во всем приложении и $this->translate($message) во всех файлах представления будет использоваться новый языковой стандарт вместо того, который используется по умолчанию в файле конфигурации?

0

Решение

Вам просто нужно установить языковой стандарт PHP. Для этого используйте \Locale::setDefault('en-GB');,

Посмотри на SlmLocale, этот конкретный файл — то, где это сделано.


Хотя это был самый простой способ, вы также можете использовать setLocale функция на MvcTranslator, я думаю. Для этого вам нужно переопределить существующую фабрику своей собственной фабрикой, следовательно, украшая оригинальную.

Если вы посмотрите на Файл ConfigProvider в zend-mvc-i18n, Вы можете видеть, что псевдонимы и фабрики используются здесь для создания переводчика MVC. Затем вы можете увидеть, как работает эта фабрика, в основном она создает переводчик-декоратор, как указано в документе.

По умолчанию диспетчер сервисов всегда предоставляет один и тот же экземпляр (общий сервис), как одиночный.

Поэтому мы сделаем переопределение этой конфигурации (т.е. убедитесь, что ваш собственный модуль находится после Zend\Mvc\I18n в modules.config.php). Затем в конфигурации модуля мы можем предоставить нашего собственного переводчика.

Наш переводчик в основном состоит из переводчика из документации, по которой setLocale называется. Для этого мы можем использовать доверитель.

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]