2012-05-15 25 views
3

我正在使用doctrine繼承映射來啓用各種對象鏈接到評論實體。這是通過各種具體的「線索」實現的,這些「線索」與評論具有一對多的關係。因此,以'Story'元素爲例,將會有一個相關的'StoryThread'實體,它可以有很多評論。索納塔管理軟件包:可能添加一個可以有不同父母的子管理對象?

這一切都正常工作,但我有麻煩試圖爲SonataAdminBundle定義一個CommentAdmin類,可以用作父實體的子代。例如,我希望能夠利用途徑,如:

/admin/bundle/story/story/1/comment/list /admin/bundle/media/gallery/1/comment/list

沒有人有我該怎麼去實現這個任何指針?我很想發佈一些代碼提取,但我還沒有設法找到任何相關的文檔,所以不知道最好的地方開始。

我一直在嘗試使用SonataNewsBundle作爲參考,因爲他們已經在帖子和評論之間實現了類似的父/子管理關係,但看起來好像這依賴於'comment'(child)admin class被硬編碼以知道它屬於帖子,並且它似乎好像需要與父對象有直接的多對一關係,而我的是通過一個單獨的「線程」實體。

我希望這是有道理的!謝謝你的幫助。

回答

16

好吧我終於得到了這個工作。我無法使用CommentAdmin類的$parentAssociationMapping屬性,因爲註釋的父實體是線程實體的具體實例,而本例中的父級「管理」類是一個Story(它通過StoryThread)。另外,當我對其他類型的實體實施評論時,這需要保持動態。

首先,我必須配置我StoryAdmin(以及任何其他管理類,將有CommentAdmin作爲孩子)來調用addChild方法:

acme_story.admin.story: 
     class: Acme\Bundle\StoryBundle\Admin\StoryAdmin 
     tags: 
     - { name: sonata.admin, manager_type: orm, group: content, label: Stories } 
     arguments: [null, Acme\Bundle\StoryBundle\Entity\Story, AcmeStoryBundle:StoryAdmin] 
     calls: 
      - [ addChild, [ @acme_comment.admin.comment ] ] 
      - [ setSecurityContext, [ @security.context ] ] 

這讓我鏈接到子管理從故事管理部分,在我的情況從一個側面菜單,就像這樣:

protected function configureSideMenu(MenuItemInterface $menu, $action, Admin $childAdmin = null) 
{ 
    // ...other side menu stuff 

    $menu->addChild(
     'comments', 
     array('uri' => $admin->generateUrl('acme_comment.admin.comment.list', array('id' => $id))) 
    ); 
} 

然後,在我的CommentAdmin課,我有一個基於父對象上訪問相關主題的實體(如StoryThread在這情況)並將其設置爲過濾器參數。這基本上是使用$parentAssociationMapping屬性自動完成的,如果父實體與父管理相同,那麼如果不使用繼承映射,最有可能會這樣做。下面是從CommentAdmin所需的代碼:

/** 
* @param \Sonata\AdminBundle\Datagrid\DatagridMapper $filter 
*/ 
protected function configureDatagridFilters(DatagridMapper $filter) 
{ 
    $filter->add('thread'); 
} 


/** 
* @return array 
*/ 
public function getFilterParameters() 
{ 
    $parameters = parent::getFilterParameters(); 

    return array_merge($parameters, array(
     'thread' => array('value' => $this->getThread()->getId()) 
    )); 
} 

public function getNewInstance() 
{ 
    $comment = parent::getNewInstance(); 

    $comment->setThread($this->getThread()); 
    $comment->setAuthor($this->securityContext->getToken()->getUser()); 

    return $comment; 
} 

/** 
* @return CommentableInterface 
*/ 
protected function getParentObject() 
{ 
    return $this->getParent()->getObject($this->getParent()->getRequest()->get('id')); 
} 

/** 
* @return object Thread 
*/ 
protected function getThread() 
{ 
    /** @var $threadRepository ThreadRepository */ 
    $threadRepository = $this->em->getRepository($this->getParentObject()->getThreadEntityName()); 

    return $threadRepository->findOneBy(array(
     $threadRepository->getObjectColumn() => $this->getParentObject()->getId() 
    )); 
} 

/** 
* @param \Doctrine\ORM\EntityManager $em 
*/ 
public function setEntityManager($em) 
{ 
    $this->em = $em; 
} 

/** 
* @param \Symfony\Component\Security\Core\SecurityContextInterface $securityContext 
*/ 
public function setSecurityContext(SecurityContextInterface $securityContext) 
{ 
    $this->securityContext = $securityContext; 
} 
+0

Hi @RobMasters!我做錯了什麼或不明白你的代碼,也許我混了:評論,帖子,帖子,故事。你可以添加更多的細節,甚至整個管理類和相應的實體嗎?我在子管理中的''getParent()''返回''null''。謝謝? – Cassiano

+0

對不起,但我不能。這個問題已經差不多3年了,我幾乎沒有使用過這個代碼。如果您遇到特定的問題,那麼最好問一個新問題並提供您的代碼。 – RobMasters

0

你的代碼的替代直接相關實體:

public function getParentAssociationMapping() 
{ 
    // we grab our entity manager 
    $em = $this->modelManager->getEntityManager('acme\Bundle\Entity\acme'); 

    // we get our parent object table name 
    $className = $em->getClassMetadata(get_class($this->getParent()->getObject($this->getParent()->getRequest()->get('id'))))->getTableName(); 

    // we return our class name (i lower it because my tables first characted uppercased) 
    return strtolower($className); 
} 

一定要有你的inversedBy變量,才能正常工作

匹配的$ className