【问题标题】:Zend Framework 3 translator from DB来自 DB 的 Zend Framework 3 翻译器
【发布时间】:2017-06-07 07:36:50
【问题描述】:

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

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

我已经安装了 Zend\Mvc\I18n 模块,将其注册为 view_helper

// 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"

产生一个“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
    ]
]

是否有解决方法或我缺少的任何东西?任何帮助,将不胜感激。感谢您的建议!

【问题讨论】:

    标签: php zend-framework internationalization zend-framework3


    【解决方案1】:

    这有点棘手。你必须在渲染发生之前设置一个翻译加载器工厂。

    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);
    

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

    【讨论】:

      【解决方案2】:

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

      // 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
              ]
          ]
      ]
      

      【讨论】:

      • 没有任何区别 :( 翻译器仍然是直接访问Database类而不是先访问DatabaseFactory。
      • @Dragan 我已经更新了我的答案,所以它使用了插件管理器。如果这不起作用,我不知道。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多