简体   繁体   English

数据库翻译Zend Framework 2

[英]Database Translations Zend Framework 2

I have problem with creating custom translator from database in ZF2. 我在ZF2中从数据库创建自定义转换器时遇到问题。 I have a DB like this 我有一个这样的数据库 在此处输入图片说明

and files: 和文件:

1)Application/module.config.php 1)应用程序/ module.config.php

'service_manager' => array(
    'abstract_factories' => array(),
    'factories' => array(
        'translator' => function  (\Zend\ServiceManager\ServiceManager $serviceManager)
            {
                $pluginManager = new \Zend\I18n\Translator\LoaderPluginManager();
                $pluginManager->setServiceLocator($serviceManager);
                $pluginManager->setFactory('DatabaseTranslationLoaderFactory', function($serviceManager)
                {
                    $translator = new \Zend\I18n\Translator\DatabaseTranslationLoaderFactory();
                    return $translator->createService($serviceManager);
                });
                $translator = new \Zend\I18n\Translator\Translator(array());
                $translator->setFallbackLocale('en_US');
                $translator->setPluginManager($pluginManager);
                $translator->addRemoteTranslations('DatabaseTranslationLoaderFactory');
                return $translator;
            },
    ),
),

'translator' => array(
    'locale' => 'en_US',
    'translation_file_patterns' => array(
        array(
            'type'     => 'Zend\I18n\Translator\Loader\Database',
            'base_dir' => __DIR__ . '/../language',
            'pattern'  => '%s.mo',
        ),
    ),
),

2) Zend/I18n/Translator/Loader/Database.php 2)Zend / I18n / Translator / Loader / Database.php

<?php

namespace Zend\I18n\Translator\Loader;

use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
use Zend\I18n\Translator\Plural\Rule as PluralRule;
use Zend\I18n\Translator\TextDomain;


class Database implements RemoteLoaderInterface {

protected $dbAdapter;


public $dbAdapter;


public function __construct(Adapter $dbAdapter = null)
{
    if ($dbAdapter === null)
    {
        $configArray = array('driver' => 'Pdo_Mysql',
            'database' => 'dbname',
            'username' => 'username',
            'password' => 'pswd',
            'hostname' => 'localhost',
            'charset' => 'utf-8',
        );
        $dbAdapter = new Adapter($configArray);
    }
    $this->dbAdapter = $dbAdapter;
}


public function load($locale, $textDomain)
{
    $sql = new Sql($this->dbAdapter);
    $select = $sql->select('ic_var')->columns(array('value'))
                  ->where(array('language' => $locale, 'name' => $textDomain));

    $messages = $this->dbAdapter->query(
        $sql->getSqlStringForSqlObject($select),
        Adapter::QUERY_MODE_EXECUTE
    );

    $textDomain = new TextDomain();

    foreach ($messages as $message) {
        if (isset($textDomain[$message['name']])) {
            if (!is_array($textDomain[$message['name']])) {
                $textDomain[$message['name']] = array(
                    $message['plural_index'] => $textDomain[$message['name']]
                );
            }
            $textDomain[$message['name']][$message['plural_index']] = $message['value'];
        } else {
            $textDomain[$message['name']] = $message['value'];
        }
    }
    return $textDomain;
}
}

3) Zend/I18n/Translator/DatabaseTranslationLoaderFactory.php 3)Zend / I18n / Translator / DatabaseTranslationLoaderFactory.php

<?php

namespace Zend\I18n\Translator;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\I18n\Translator\Loader\Database;

class DatabaseTranslationLoaderFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return new Database($serviceLocator->get('Zend\Db\Adapter\Adapter'));
    }
}

4) Application/Module.php 4)Application / Module.php

public function onBootstrap(MvcEvent $e)
{
    $translator = $e->getApplication()->getServiceManager()->get('translator');
    $translator->addTranslationFile(
        'DatabaseTranslationLoader',
        'text-domain',
        'text-domain'
    );
}

But translation doesn`t work, because db adapter not find in loader: 但是转换不起作用,因为在加载程序中找不到数据库适配器:

Fatal error: Uncaught exception 'Zend\\I18n\\Exception\\RuntimeException' with message 'Specified loader is not a file loader' 致命错误:消息为“指定的加载器不是文件加载器”的未捕获异常'Zend \\ I18n \\ Exception \\ RuntimeException

Thanks for your answers! 感谢您的回答!

First of all you shouldn't define your custom classes in the Zend namespace as this is reserved a namespace for the ZF2 library and you don't want to touch (or add) files in the vendor directory. 首先,您不应在Zend命名空间中定义自定义类,因为这是ZF2库的保留名称空间,并且您不想触摸(或添加)供应商目录中的文件。 Just put the custom classes in your own namespace outside the vendor folder. 只需将自定义类放在供应商文件夹之外的自己的命名空间中即可。 ie MyI18n MyI18n

You can register you custom remote loader to the pluginManager in module.config.php . 您可以在module.config.php自定义远程加载程序注册到pluginManager。

return array(
    'translator' => array(
        'loaderpluginmanager' => array(
            'factories' => array(
                'database' => 'MyI18n\Translator\DatabaseTranslationLoaderFactory',
            )
        ),
        'remote_translation' => array(
            array(
                'type' => 'database' //This sets the database loader for the default textDomain
            ),
        ),
    )
);

You don't have to overwrite the Translator factory if you want to add a custom loader, so just remove that code in your Module.php . 如果要添加自定义加载程序,则不必覆盖Translator工厂,因此只需在Module.php删除该代码Module.php Als remove the configuration under translation_file_patterns as this is only needed for file loaders. Als删除了translation_file_patterns下的配置,因为只有文件加载器才需要此配置。

EDIT 编辑

For the above to work you need to overwrite the TranslatorServiceFactory because ZF has no support to register custom loaders on the plugin manager. 为了使上述工作正常进行,您需要覆盖TranslatorServiceFactory因为ZF不支持在插件管理器上注册自定义加载程序。

namespace MyNamespace\Translator;

use Zend\Mvc\Service\TranslatorServiceFactory as BaseTranslatorFactory;

class TranslatorServiceFactory extends BaseTranslatorFactory
{
    /**
     * @param ServiceLocatorInterface $serviceLocator
     * @return MvcTranslator
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $translator = parent::createService($serviceLocator);

        $config = $serviceLocator->get('Config');
        $pluginManagerConfig = isset($config['translator']['loaderpluginmanager']) ? $config['translator']['loaderpluginmanager'] : array();
        $pluginManager = new LoaderPluginManager(new Config($pluginManagerConfig));
        $pluginManager->setServiceLocator($serviceLocator);
        $translator->setPluginManager($pluginManager);

        return $translator;
    }
}

Now register your custom factory in the service configuration: 现在,在服务配置中注册您的自定义工厂:

class Module
{
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'MvcTranslator' => 'MyNamespace\Translator\TranslatorServiceFactory',
            )
        )
    }
}

I register custom remote loader to the pluginManager in module.config.php like this 我像这样在module.config.php中将自定义远程加载器注册到pluginManager

'translator' => [
    'loaderpluginmanager' => [
        'factories' => [
            'database' => function($lpm){
                $sm = $lpm->getServiceLocator();
                $loader = new Zf2Translation\Loader\DatabaseTranslationLoader($sm);
                return $loader;
            },
        ],
    ],
    'remote_translation' => [
        [
            'type' => 'database', 
        ],
    ],
]

Next in Database Loader class Database Loader类中的下一个

use Zend\I18n\Translator\Loader\RemoteLoaderInterface;
class DatabaseTranslationLoader implements RemoteLoaderInterface
{
    protected $dbAdapter;
    protected $sm;

    public function __construct(ServiceManager $sm)
    {
        $this->sm = $sm;
        $this->dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
    }
}

I hope it helps. 希望对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM