2016-12-08 12 views
0

フィールド$grantedToを持つBookエンティティがあり、ユーザーロールが入っています。 このフィールドでは、ユーザーの役割に応じて書籍へのアクセスを許可または拒否することができます。Symfonyでは、ユーザーの役割に応じてエンティティをクエリする方法は?

OneToManyの関係$booksを持つLibraryという別のエンティティを考えてみましょう。

は今小枝ビューから、私はこれをやりたい:

{{ 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; 
    }); 
} 

そして、あなたのビュー内、あなたはそれをあなたの現在のユーザーの役割に合格する必要があると思います。

編集:

あなたが優れた役割を持つユーザーのケースを処理する必要がある場合、私はonPostLoadで、その後、教義のエンティティ・リスナーを使用して、そこにsecurity.role_hierarchyと@token_storage @注入示唆イベントあなたのロジックを置くことができます:あなたのリスナーで

<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

あなたの答えはありがたいですが、 'grantedTo == User'と' Admin'として接続しているので、本を見ることができるはずですが、私は 'User '!=' Admin '(セキュリティコンテキストが必要な理由) – Roubi

+0

私の編集を確認してください – Youssef

+0

すばらしい解決策!最初は 'token_storage'と' role_hierarchy'の両方ではなく 'authorization_checker'サービスを注入しなかったので複雑すぎると思いましたが、残念ながら**循環参照**エラーが発生します。 ** EntityListener **を使用するためには** EventListener **を使用するために編集することをお勧めします。そうすれば、Libraryエンティティでのみ呼び出されます。これは私がやったことです。ありがとう! – Roubi

関連する問題