У меня есть приложение 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)
во всех файлах представления будет использоваться новый языковой стандарт вместо того, который используется по умолчанию в файле конфигурации?
Вам просто нужно установить языковой стандарт 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;
}
}
Это был бы один из способов сделать это (вы получаете контейнер на этой фабрике, так что вы можете получить некоторые пользовательские данные, вероятно).
Другое решение состоит в том, чтобы использовать систему событий и объявлять только локаль в прослушивателе событий, где вы извлекаете свои данные пользователя.
Других решений пока нет …