我在Symfony中有一个Post
实体。该项目有翻译,存储在PostTranslation
中。
每一篇文章都有一段不同语言的片段。
代码看起来像:
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationParamConverter;
/**
* @I18nDoctrine
* @Route("/blog/{slug}")
* @ParamConverter("post", class="SensioBlogBundle:Post")
*/
public function showAction(Post $post)
{
}
但是我怎样才能进行findOneBy('slug')
类型的搜索呢?因为它存储在相关实体中。
我想除了slug
属性之外,您的PostTranslation
实体还存储某种语言/区域设置,例如locale
属性,对吗?我还猜测你的网站是基于URL中存储的一些参数(不同(子域)、查询字符串参数、路径前缀——这无关紧要)进行对话的,对吧?
至少有三种解决方案可以解决您的问题:
- 放弃使用
ParamConverter
,一切由自己完成 -
从SensionFrameworkExtraBundle重写
DoctrineParamConverter
,并为Post
类添加对slug
和locale
查找的支持。我还建议创建一个更健壮的解决方案:- 创建定义
getTranslations()
和setTranslations()
方法的Translatable
接口,并将其应用于Post
类 - 在您的
CustomDoctrineParamConverter
中,检查请求的类是否实现了此接口,如果是,则意味着您将根据实体的翻译来搜索实体,即locale
和一些区域设置唯一属性 - 现在,您需要一些方法来获得此区域设置唯一属性的名称。您可以为
PostTranslation
类创建另一个接口,它将定义一个方法,类似于getLocaleIdentifier/UniqueProperty
,对于PostTranslation
,它将返回"slug"
- 如果你知道,你需要找到一个
Post
属性,基于locale
和slug
属性的translations
关联,你可以很容易地创建DQL查询来做到这一点
- 创建定义
-
ParamConverter
注释具有repository_method
属性,该属性允许您使用PostRepository
中的自定义方法,该方法应检索Post
实体。唯一的问题是内置的DoctrineParamConverter
将只向该方法传递slug
参数。您的存储库必须以某种方式了解当前的区域设置。这可以通过多种不同的方式实现,以下是其中之一:- 使用单个方法
setLocale($locale)
创建LocaleAware
接口 - 在
PostRepository
中实现该接口 -
创建侦听
kernel.request
事件的事件侦听器:- 遍历所有条令的存储库
- 检查给定的存储库是否实现了
LocaleAware
接口 - 将请求的
_locale
属性注入存储库
- 使用单个方法