首先我要感谢stackoverflow社区在过去几年里给予我的所有帮助!我通常都能找到解决办法,但这一次,经过长时间的研究和测试,我还是找不到任何解决办法。这是我的问题:
在我的页面的顶部,我有一个菜单,是从一个DB与类别生成的。下面是我的一部分代码:
CategoryController:
public function renderMenuAction() {
$em = $this->getDoctrine()->getManager();
$manager = new CategoryManager($em);
$request = $this->getRequest();
$categories = $manager->loadMenu();
foreach($categories as $category) {
$this->getLocalizedCategoryTranslations($category, $request);
}
return $this->render('HeidanCoreBundle:Includes/Category:category_menu.html.twig', array(
'categories' => $categories,
));
}
函数loadMenu从我的经理引用这个请求,以获得lv0类别:
CategoryRepository:
public function findMenuElements() {
$qb = $this->_em->createQueryBuilder();
$qb->select('category', 'translation')
->from('HeidanCoreBundle:Category', 'category')
->leftJoin('category.translations', 'translation')
->where('category.lvl = 0')
;
return $query = $qb->getQuery()
->getResult();
}
getLocalizedCategoryTranslations调用侦听器,该侦听器设置类别(标题,描述等)的翻译值
public function getLocalizedCategory(TranslatableEvent $event)
{
$object = $event->getObject();
$locale = $event->getLocale();
if($object instanceof TranslatableInterface) {
if(get_class($object) == 'Heidan'CoreBundle'Entity'Category') {
$this->localizeObject($object, $locale);
$this->localizeCategoryChildren($object, $locale);
}
}
}
这是我的问题:这段代码在任何页面上都没有任何问题,除了那些对元素有自定义请求的页面。
IndexController
public function indexAction()
{
$news = $this->getNews();
$announcements = $this->getAnnouncements();
return $this->render('HeidanCoreBundle:Public:index.html.twig', array(
'news' => $news,
'announcements' => $announcements,
));
}
public function getNews() {
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$qb->select('article')
->from('HeidanCoreBundle:Article', 'article')
->orderBy('article.createdAt', 'DESC')
->setMaxResults(4);
$query = $qb->getQuery();
$results = $query->getResult();
return $results;
}
这是我的菜单的描述。
管理页面(没有像上面的getNews这样的自定义查询-所有这些对象都是类别):
,
条——社会
——业务
——艺术品
,书
——歌曲
——艺术家
——作者
——歌手
索引页(有一个请求文章的getNews查询):
——没有翻译
——没有翻译
——没有翻译
——艺术品
,书
——歌曲
——艺术家
——作者
——歌手
可以看到,对象翻译没有显示在索引页上。我检查了Symfony调试模式,它根本没有被要求。(对于ID为1、13、14的类别,没有选择翻译查询来获取翻译,而对于其他类别,查询已经完成)。
我尝试了几种方法:
如果我删除getNews()并将其替换为null,它将在索引页上工作。
如果我添加$query->setHint(query::HINT_FORCE_PARTIAL_LOAD, true);在我的getNews函数结束时:它也在索引页上工作!
如果我用getArtist(根据菜单)替换我的函数getNews,同样的问题出现在设置为'No Translation'的Artist菜单类别
我认为这是一个从学说的延迟加载问题,但可能有什么我没有理解。
如果你有任何想法,我在等待你的帮助!我终于在使用调试器后找到了解决方案。我的第一个想法一半对,一半错。问题是由于Doctrine行为,但它来自我的一行代码。
public function getLocalizedCategory(TranslatableEvent $event)
{
$object = $event->getObject();
$locale = $event->getLocale();
if($object instanceof TranslatableInterface) {
if(get_class($object) == 'Heidan'CoreBundle'Entity'Category') {
$this->localizeObject($object, $locale);
$this->localizeCategoryChildren($object, $locale);
}
}
}
在这个函数中(我编辑了问题,也让这部分代码出现),我调用get_class方法。
当我使用调试器时,我发现当我调用getNews()方法(返回文章对象)时,返回的类别(仅适用于具有文章的类别)不是Heidan'CoreBundle'Entity'Category而是Proxies__CG__'Heidan'CoreBundle'Entity'Category的对象
因此,这设置了我的条件if(get_class($object) == 'Heidan'CoreBundle'Entity'Category')为false并且Category未被翻译
为了获得正确的行为,我必须将实体管理器注入到事件中,并使用函数getClassMetadata
获取类名正确getLocalizedCategory函数:
public function getLocalizedCategory(TranslatableEvent $event)
{
$object = $event->getObject();
$locale = $event->getLocale();
$em = $event->getEm();
if($object instanceof TranslatableInterface) {
$className = $em->getClassMetadata(get_class($object))->getName();
if($className == 'Heidan'CoreBundle'Entity'Category') {
$this->localizeObject($object, $locale);
$this->localizeCategoryChildren($object, $locale);
}
}
}
这个链接帮助我从类对象中获取实体名称