我认为你做这件事的方式非常好。
您可以添加/重写一些获取i18n数据的方法,例如getTitle($ locale)(或者get * Whatever *),它会添加一些逻辑,在topic_i18n集合中找到合适的值。
// in your Topic class
public function getTitle()
{
return $this
->getTopicI18nCollection()
->findByLocale($this->getLocale()) // actually findByLocale does not exist, you will have to find another way, like iterating over all collection
->getTitle()
;
}
与__toString或他人的自动化问题是与现场切换,或如何定义默认语言环境默认使用。
这可以使用doctrine postLoad事件侦听器解决,该侦听器将当前语言环境设置为由EntityManager(http://www.doctrine-project.org/docs/orm/2.1/en/reference/events.html#lifecycle-events)获取的任何实体,例如使用请求或会话信息。
使用Symfony2中,它可能是这样的:
# app/config/config.yml
services:
postload.listener:
class: Translatable\LocaleInitializer
arguments: [@session]
tags:
- { name: doctrine.event_listener, event: postLoad }
// src/Translatable/LocaleInitalizer.php
class LocaleInitializer
{
public function __construct(Session $session)
{
$this->session = $session;
}
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if ($entity implements TranslatableInterface) { // or whatever check
$entity->setLocale($this->session->getLocale());
}
}
}
最后,你不有得到一个主题对象来创建一个新的topic_i18n对象,你可以简单地插入的i18n对象independantly 。 (但你将不得不刷新以前提取的集合)。
非常感谢,您的解释就是我一直在寻找的!你能解释为什么findByLocale()不会存在吗?是由于语言环境是一个私有变量而不是@ORM \列?另一个问题是,为了能够同时管理两个实体,我应该创建一个服务层/管理器,或者只需将所需的字段/变量添加到Topic实体,并将侦听器注册为prepersist事件,然后从实体中获取变量,实例化一个Entity_i18n对象并将它们设置为它?我的意思是我希望能够运行$ t = new Topic(); $ t-> setLocale('es'); $ t-> setContent(foo);并坚持下去 – user846226 2012-02-03 08:10:35