2017-06-07 71 views
1

我最近開始使用ZF3,並且正在致力於項目的國際化。來自DB的Zend Framework 3翻譯器

我已經設法讓它工作,但我想讓翻譯從數據庫中獲取翻譯,而不是從.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" 

的結果是 「我」,而這正是我想要的。

現在,我的問題是如何將學說實體管理器傳遞給數據庫服務?我知道我必須在這些情況下使用一個工廠,我有一個準備

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

是否有解決方法或任何我失蹤?任何幫助,將不勝感激。感謝您的建議!

回答

0

看起來你忘了註冊類和它的服務管理器工廠:

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

沒有什麼區別:(翻譯器仍然直接訪問數據庫類而不是DatabaseFactory。 – Dragan

+0

@Dragan我已經更新了我的答案,所以它使用插件管理器。如果這不起作用,我就不會不知道。 – xtreamwayz

0

這是一個有點棘手。您必須在渲染之前設置翻譯加載器工廠。

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

我不知道任何其他方式來配置服務定位爲翻譯。