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:我认为这是级联刷新的错误?

此致。

问题不是级联持久化而是级联本地化。文档中没有提到这种能力。在您的情况下,翻译是由 TranslatableListenerpostLoad 事件中完成的。要定义语言环境,使用 getTranslatableLocale 方法。

有几种方法可以使上面的代码工作。

  1. setTranslatableLocale方法中定义级联保存

    public 函数 setTranslatableLocale($locale) { $this->locale = $locale; $this->contact->setTranslatableLocale($locale); }

  2. 不要使用 @Locale 注释并依赖 TranslatableListenerlocale:

    $this->translatableListener->setTranslatableLocale('fr_fr');

这将适用于:TranslatableListenerTranslationWalker。对于后者,您还可以使用语言环境设置提示 - 这将强制加载所需语言环境中的所有实体。

$query->setHint( \Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE, 'fr_fr' );

link

  1. 覆盖 TranslatableListener