假设我有一个带有字段$grantedTo
的Book
实体,填充了用户角色。该字段允许根据用户角色授予或拒绝访问书籍。
让我们考虑一个带有OneToMany
关系$books
的称为Library
的实体。
现在从树枝视图中,我想这样做:
{{ myLibrary.grantedBooks }}
grantedBooks
方法将返回我的所有图书馆书籍允许用户看到的所有图书馆。
但是,要在我的类库中构建这样的方法,我需要调用isGranted($book->grantedTo)
之类的东西,我相信这是不可能的,因为i 无法从我的实体中访问安全上下文。<<<<<<。/p>
所以我想我应该在注入安全环境的地方进行服务,然后从twig。
访问此服务。我不确定这是最好的解决方案,很高兴听到其他可能性。
您可以在图书馆类中添加一个getter,类似的东西:
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="AppBundleEntityListenerLibraryListener">
<tag name="doctrine.orm.entity_listener" entity="AppBundleEntityLibrary" 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;
}
}
显然您需要在库课中添加getGrantedBooks方法,希望这会有所帮助!