2016-12-08 86 views
0

比方說,我有一個Book實體,其字段爲$grantedTo,填充了用戶角色。 此字段允許根據用戶角色授予或拒絕對圖書的訪問。使用Symfony,如何根據用戶角色查詢實體?

讓我們考慮另一個實體LibraryOneToMany關係$books

現在,從樹枝的看法,我想這樣做:

{{ myLibrary.grantedBooks }} 

其中grantedBooks方法將返回我所有的圖書允許用戶查看。

但在我的班級圖書館建立這樣一個方法,我需要調用類似isGranted($book->grantedTo),我相信這是不可能的,因爲我無法從我的實體內訪問的安全上下文。

所以我想我應該做一個服務,我會注入安全上下文,並從Twig訪問此服務。

我不確定這是最好的解決方案,並且很樂意聽到其他可能性。

回答

1

您可將吸氣添加到您的庫類,像這樣:

public function getGrantedBook($role) { 
    return array_filter($this->books, function(Book $book) use($role){ 
     return $book->getGrantedTo() == $role; 
    }); 
} 

而且你的視圖中你需要通過它您的當前用戶的角色。

編輯:

如果您需要處理與上級角色的用戶的情況下,我建議使用一種學說實體監聽器和注射@ security.role_hierarchy和@token_storage進去,然後在onPostLoad事件中,你可以把你的邏輯:

<service id="my_bundle.library_listener" class="AppBundle\EntityListener\LibraryListener"> 
    <tag name="doctrine.orm.entity_listener" entity="AppBundle\Entity\Library" event="postLoad" /> 
    <argument type="service" id="security.token_storage" /> 
    <argument type="service" id="security.role_hierarchy" /> 
</service> 

在您的聽衆:

class LibraryListener { 

    private $roleHierarchy; 
    private $tokenStorage; 

    //Constructor... 

    /** 
    * @param Library $library 
    * @param LifecycleEventArgs $eventArgs 
    */ 
    public function postLoad(Library $library, LifecycleEventArgs $eventArgs) 
    { 
     $currentUser = $this->tokenStorage->getToken()->getUser(); 
     $library->setGrantedBooks(array_filter($library->getBooks(), function($book) use($currentUser){ 
      return $this->isGranted($book, $currentUser); 
     })); 
    } 

    /** 
    * isGranted 
    * 
    * @param Book $book 
    * @param $user 
    * @return bool 
    */ 
    private function isGranted($book, $user) { 

     $role = new Role($book->getGrantedTo(); 

     foreach($user->getRoles() as $userRole) { 
      if (in_array($role, $this->roleHierarchy->getReachableRoles(array(new Role($userRole))))) 
       return true; 
     } 

     return false; 
    } 
} 

顯然you'l我需要在你的庫類中添加一個getGrantedBooks方法,希望這有助於!

+0

感謝Youssef爲你的答案,但它不會工作,因爲如果'grantedTo == User'和我連接爲'Admin',我應該能夠看到這本書,但我不會因爲'User '!='Admin'(這就是爲什麼需要安全環境) – Roubi

+0

請檢查我的編輯 – Youssef

+0

偉大的解決方案!起初我認爲它太複雜了,因爲你沒有注入'authorization_checker'服務而不是'token_storage'和'role_hierarchy',但是這樣做不幸會導致**循環引用**錯誤。您可能需要編輯它,以便使用** EntityListener **而不是** EventListener **,因此僅在庫實體上調用它。這就是我所做的。謝謝! – Roubi