У меня проблема с использованием MVCTranslator с переводами, хранящимися в базе данных.
Я настроил переводы для использования remote_translation, но не могу создать фабрику для своего пользовательского загрузчика.
Мои файлы выглядят так:
module.config.php
'translator' => [
'locale' => 'en_US',
'translation_file_patterns' => [
[
'type' => 'phparray',
'base_dir' => getcwd() . '/data/language',
'pattern' => '%s.php',
'text_domain' => 'default',
],
],
'remote_translation' => [
[
'type' => Model\DatabaseTranslationLoader::class,
'text_domain' => 'default',
]
],
],
module.php
namespace MyNamespace;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface
{
public function getConfig()
{
return include __DIR__ . '/../config/module.config.php';
}
/*
....
...
....
*/
public function getControllerConfig()
{
return [
'factories' => [
Controller\MyController::class => function($container) {
$translator = $container->get('MvcTranslator');
$translator->getPluginManager()->setFactory(Translator\DatabaseTranslationLoader::class, Factory\DatabaseTranslationLoaderFactory::class);
return new Controller\MyController(
$translator
);
},
],
];
}
}
Переводчик \ DatabaseTranslationLoader.php
namespace MyNamespace\Translator;
use Zend\Db\Adapter\Adapter as DbAdapter;
use Zend\I18n\Translator\Loader\RemoteLoaderInterface;
class DatabaseTranslationLoader implements RemoteLoaderInterface
{
protected $dbAdapter;
public function __construct(DbAdapter $adapter)
{
$this->dbAdapter = $adapter;
}
public function load($locale, $filename)
{
// Database operations
}
Завод \ DatabaseTranslationLoaderFactory.php
namespace MyNamespace\Factory\DatabaseTranslation;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class DatabaseTranslationLoaderFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$dbAdapter = $container->get(Zend\Db\Adapter\AdapterInterface:class);
return new Translator\DatabaseTranslationLoader($dbAdapter);
}
}
При такой конфигурации, когда я пытаюсь получить адаптер базы данных в DatabaseTranslationLoaderFactory получает исключение от диспетчера служб:
Не удалось разрешить службу «Zend \ Db \ Adapter \ Adapter» на заводе; Вы уверены, что предоставили его во время настройки?
Похоже, что на фабрике есть пустой контейнер (новый экземпляр ServiceManager?).
Что я делаю неправильно?
У кого-нибудь есть идеи, как это сделать?
Буду благодарен за любые предложения.
РЕДАКТИРОВАТЬ:
Как упоминалось выше, похоже, что это новый экземпляр serviceMenager в DatabaseTranslationLoaderFactory.
Та же ошибка возникает, когда я пытаюсь сделать:
$container->get('router')
или же
$container->get('request')
Во-первых, я вижу, вы делаете опечатку при вызове службы. Вы называете переменную $conteiner
, Так должно быть $container
,
$conteiner->get('Zend\Db\Adapter\Adapter')
И для извлечения службы адаптера базы данных использовать
$container->get(Zend\Db\Adapter\AdapterInterface::class);
вместо
$container->get('Zend\Db\Adapter\Adapter')
После нескольких часов поисков я нашел решение своей проблемы.
Объяснение проблемы было найдено в Zend \ I18n \ Translator \ Translator.php:
public function setPluginManager(LoaderPluginManager $pluginManager)
{
$this->pluginManager = $pluginManager;
return $this;
}
public function getPluginManager()
{
if (! $this->pluginManager instanceof LoaderPluginManager) {
$this->setPluginManager(new LoaderPluginManager(new ServiceManager));
}
return $this->pluginManager;
}
Исходя из вышесказанного, getPluginManager по умолчанию создает новый экземпляр LoaderPluginManager с новым экземпляром ServiceManager.
В моем случае, чтобы получить доступ к ServiceManager в DatabaseTranslationLoaderFactory, мне сначала нужно было использовать метод setPluginManager, как показано ниже:
module.php
namespace MyNamespace;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface
{
public function getConfig()
{
return include __DIR__ . '/../config/module.config.php';
}
/*
....
...
....
*/
public function getControllerConfig()
{
return [
'factories' => [
Controller\MyController::class => function($container) {
$translator = $container->get('MvcTranslator');
// This line solved my problem
$translator->setPluginManager(new \Zend\I18n\Translator\LoaderPluginManager($container));
$translator->getPluginManager()->setFactory(Translator\DatabaseTranslationLoader::class, Factory\DatabaseTranslationLoaderFactory::class);
return new Controller\MyController(
$translator
);
},
],
];
}
}
Я не знаю, правильно ли это решение, но оно работает.
Может быть, это кому-то поможет 🙂