Symfony @Translatable 与实体管理器的刷新
Symfony @Translatable with Entity Manager's refresh
我成功地使用 StofDoctrineExtension Bundle 来处理实体翻译。
因此,我在实体中的属性具有上面的 @Translable - 注释。
当我想用相关实体(数据库中存在翻译条目)以特定语言显示实体时,出现以下问题:
假设我有一个映射到联系人实体 (OneToOne) 的作者实体,并且我想以 "fr_fr" 语言显示作者详细信息,我正在使用以下代码:
$author = ...;
$author->setTranslatableLocale('fr_fr');
$this->get('fos_user.entity_manager')->refresh($author);
此代码正在将作者翻译成语言 "fr_fr" - 但映射的联系人实体未被翻译成目标语言 "fr_fr"。我当然已经在作者实体的联系人映射中使用了 cascade=refresh 选项:
/**
* @ORM\OneToOne(targetEntity="AuthorContact", inversedBy="author",
cascade={"persist", "remove", "refresh"})
* @ORM\JoinColumn(name="contact_id", referencedColumnName="id")
*/
protected $contact;
当我在我的控制器中使用以下 "extra lines" 来获取作者时,我得到了两个实体的翻译:
$author = ...;
$author->setTranslatableLocale('fr_fr');
$author->getContact()->setTranslatableLocale('fr_fr');
$this->get('fos_user.entity_manager')->refresh($author);
$this->get('fos_user.entity_manager')->refresh($author->getContact());
根据我的口味,这有点丑陋,为什么无论如何使用 "cascade=refresh" 选项都不起作用?
@edit:我认为这是级联刷新的错误?
此致。
问题不是级联持久化而是级联本地化。文档中没有提到这种能力。在您的情况下,翻译是由 TranslatableListener
在 postLoad
事件中完成的。要定义语言环境,使用 getTranslatableLocale 方法。
有几种方法可以使上面的代码工作。
在setTranslatableLocale
方法中定义级联保存
public 函数 setTranslatableLocale($locale)
{
$this->locale = $locale;
$this->contact->setTranslatableLocale($locale);
}
不要使用 @Locale
注释并依赖 TranslatableListener
的 locale
:
$this->translatableListener->setTranslatableLocale('fr_fr');
这将适用于:TranslatableListener
和 TranslationWalker
。对于后者,您还可以使用语言环境设置提示 - 这将强制加载所需语言环境中的所有实体。
$query->setHint(
\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,
'fr_fr'
);
- 覆盖
TranslatableListener
我成功地使用 StofDoctrineExtension Bundle 来处理实体翻译。 因此,我在实体中的属性具有上面的 @Translable - 注释。
当我想用相关实体(数据库中存在翻译条目)以特定语言显示实体时,出现以下问题:
假设我有一个映射到联系人实体 (OneToOne) 的作者实体,并且我想以 "fr_fr" 语言显示作者详细信息,我正在使用以下代码:
$author = ...;
$author->setTranslatableLocale('fr_fr');
$this->get('fos_user.entity_manager')->refresh($author);
此代码正在将作者翻译成语言 "fr_fr" - 但映射的联系人实体未被翻译成目标语言 "fr_fr"。我当然已经在作者实体的联系人映射中使用了 cascade=refresh 选项:
/**
* @ORM\OneToOne(targetEntity="AuthorContact", inversedBy="author",
cascade={"persist", "remove", "refresh"})
* @ORM\JoinColumn(name="contact_id", referencedColumnName="id")
*/
protected $contact;
当我在我的控制器中使用以下 "extra lines" 来获取作者时,我得到了两个实体的翻译:
$author = ...;
$author->setTranslatableLocale('fr_fr');
$author->getContact()->setTranslatableLocale('fr_fr');
$this->get('fos_user.entity_manager')->refresh($author);
$this->get('fos_user.entity_manager')->refresh($author->getContact());
根据我的口味,这有点丑陋,为什么无论如何使用 "cascade=refresh" 选项都不起作用?
@edit:我认为这是级联刷新的错误?
此致。
问题不是级联持久化而是级联本地化。文档中没有提到这种能力。在您的情况下,翻译是由 TranslatableListener
在 postLoad
事件中完成的。要定义语言环境,使用 getTranslatableLocale 方法。
有几种方法可以使上面的代码工作。
在
setTranslatableLocale
方法中定义级联保存public 函数 setTranslatableLocale($locale) { $this->locale = $locale; $this->contact->setTranslatableLocale($locale); }
不要使用
@Locale
注释并依赖TranslatableListener
的locale
:$this->translatableListener->setTranslatableLocale('fr_fr');
这将适用于:TranslatableListener
和 TranslationWalker
。对于后者,您还可以使用语言环境设置提示 - 这将强制加载所需语言环境中的所有实体。
$query->setHint( \Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE, 'fr_fr' );
- 覆盖
TranslatableListener