Php 来自DB的Zend Framework 3转换器

Php 来自DB的Zend Framework 3转换器,php,zend-framework,internationalization,zend-framework3,Php,Zend Framework,Internationalization,Zend Framework3,我最近开始与ZF3合作,并致力于项目的国际化 我已经设法让它工作,但我想让翻译器从数据库中获取翻译,而不是从.mo文件中读取。这样,用户就可以在应用程序的管理部分编辑它们 我已经安装了Zend\Mvc\I18n模块,并将其注册为view\u助手 // module's module.config.php: 'view_helpers' => [ 'invokables' => [ 'translate' => \Zend\I18n\View\He

我最近开始与ZF3合作,并致力于项目的国际化

我已经设法让它工作,但我想让翻译器从数据库中获取翻译,而不是从.mo文件中读取。这样,用户就可以在应用程序的管理部分编辑它们

我已经安装了Zend\Mvc\I18n模块,并将其注册为view\u助手

// module's module.config.php:    
'view_helpers' => [
    'invokables' => [
        'translate' => \Zend\I18n\View\Helper\Translate::class
    ]
]
而不是

// module's module.config.php:
'translator' => [
    'locale' => 'en_US',
    'translation_file_patterns' => [
        [
            'type'     => 'gettext',
            'base_dir' => __DIR__ . '/../language',
            'pattern'  => '%s.mo',
        ],
    ],
]
我有

// module's module.config.php:
'translator' => [
    'locale' => 'en_US',
    'remote_translation' => [
        [
            'type' => Service\Database::class
        ]
    ]
]
数据库服务按照文档中的要求实现RemoteLoaderInterface,现在它有一个硬编码数组,但稍后将被实际查询替换

//Database.php
namespace Core\Service;

use Zend\I18n\Translator\Loader\RemoteLoaderInterface;

class Database implements RemoteLoaderInterface {

    private $entityManager;

    public function __construct($entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function load($locale, $textDomain)
    {
        $array = [];
        $array['and'] = 'i';
        return $array;
    }
}
在我的版式打印中

// layout.phtml
$this->translate("and") // prints "i"
结果是“我”,这正是我想要的

现在,我的问题是如何将条令实体管理器传递给数据库服务?我知道在这种情况下我必须使用工厂,我已经准备好了

//DatabaseFactory.php
namespace Core\Service\Factory;

use Core\Service\Database;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;

class DatabaseFactory implements FactoryInterface 
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $entityManager = $container->get('doctrine.entitymanager.orm_default');

        // Instantiate the service and inject dependencies
        return new Database($entityManager);
    }

}
但我无法在模块配置中传递它,因为它需要类来实现RemoteLoaderInterface

// module's module.config.php:   
'remote_translation' => [
    [
        'type' => Service\Factory\DatabaseFactory::class // does not work
    ]
]

有没有解决办法或者我遗漏了什么?任何帮助都将不胜感激。谢谢你的建议

您似乎忘记向服务管理器注册类及其工厂:

// module's module.config.php
'translator' => [
    'loaderpluginmanager' => [
        'factories' => [
            Core\Service\Database::class => Service\Factory\DatabaseFactory::class,
        ],
    ],
    'locale' => 'en_US',
    'remote_translation' => [
        [
            'type' => Core\Service\Database::class
        ]
    ]
]

您似乎忘记向服务管理器注册类及其工厂:

// module's module.config.php
'translator' => [
    'loaderpluginmanager' => [
        'factories' => [
            Core\Service\Database::class => Service\Factory\DatabaseFactory::class,
        ],
    ],
    'locale' => 'en_US',
    'remote_translation' => [
        [
            'type' => Core\Service\Database::class
        ]
    ]
]

这有点棘手。在进行渲染之前,必须设置翻译加载程序工厂

module\Application\src\module.php

public function init (ModuleManager $manager)
{
    $eventManager = $manager->getEventManager();
    $sharedEventManager = $eventManager->getSharedManager();

    $sharedEventManager->attach(__NAMESPACE__, 'dispatch',
        [$this, 'onDispatch'], 100);
}

public function onDispatch (MvcEvent $event)
{
    $translator = $event->getApplication ()->getServiceManager ()->get (\Zend\I18n\Translator\TranslatorInterface::class);
    $translator->getPluginManager()->setFactory(\Application\Translator\Database::class, \Application\Translator\DatabaseFactory::class);

我不知道还有什么其他方法可以为翻译器配置服务定位器。

这有点棘手。在进行渲染之前,必须设置翻译加载程序工厂

module\Application\src\module.php

public function init (ModuleManager $manager)
{
    $eventManager = $manager->getEventManager();
    $sharedEventManager = $eventManager->getSharedManager();

    $sharedEventManager->attach(__NAMESPACE__, 'dispatch',
        [$this, 'onDispatch'], 100);
}

public function onDispatch (MvcEvent $event)
{
    $translator = $event->getApplication ()->getServiceManager ()->get (\Zend\I18n\Translator\TranslatorInterface::class);
    $translator->getPluginManager()->setFactory(\Application\Translator\Database::class, \Application\Translator\DatabaseFactory::class);

我不知道有什么其他方法可以为转换器配置服务定位器。

没有任何区别:(转换器仍然直接访问数据库类,而不是首先访问数据库工厂。@Dragan我已经更新了我的答案,因此它使用插件管理器。如果这不起作用,我不知道。没有任何区别:(翻译程序仍然直接访问数据库类,而不是首先访问DatabaseFactory。@Dragan我已经更新了我的答案,所以它使用插件管理器。如果这不起作用,我就不知道了。