>我已经通过实体的关系实现了 tanslatable 行为,所以我有一个带有 id 属性的topic
实体,该属性与topic_id topic_i18n
关系OneToMany
,lang_code和内容。
我可以为实体设置一个私有$locale属性topic
以使主题的实体 __toString(( 方法显示内容/名称或来自topic_i18n
实体的任何内容/名称吗?怎么可能我做到了吗?
我的另一个疑问可以扩展到发生OneToMany
关系的任何上下文,是当我想插入我首先需要创建的新topic_i18n
对象或当前有一个 topic
对象,然后创建 i18n 对象。我对实体服务层/经理没有经验,但我认为我可以使用该范式来管理两个实体合二为一,但不知道如何进行,或者这是否是正确的方法。有人可以根据他的经验给出提示、意见或其他东西吗?
提前感谢!
PD:I了解教义行为捆绑,但现在是不可能的。
我认为你这样做的方式非常好。
您可以添加/覆盖一些方法来获取 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或其他功能的自动化问题在于区域设置切换,或者如何定义默认使用的默认区域设置。
这可以使用原则 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: TranslatableLocaleInitializer
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 对象。(但您必须刷新以前获取的集合(。