In a TWIG view of my Symfony 5 project, I have the following piece of code :
<table class="table table-hover table-striped datatable"> <thead> <tr> <th>ID</th> <th>Username</th> <th>Email</th> <th>Created at</th> </tr> </thead> <tbody> {% for user in users %} <tr> <td>{{ user.id }}</td> <td>{{ user.name }}</td> <td>{{ user.email }}</td> <td>{{ user.createdAt|date('d/m/Y H:i') }}</td> </tr> {% endfor %} </tbody> </table>
Nothing impressive. I wanted to know if there was a way to check if the user
in my loop has a specific role, let’s say ROLE_STAFF
(More precisely, I want to check it against the hierarchy. If he has a role that “inherits” ROLE_STAFF
, it should also satisfy the condition). I have seen this post but it’s quite old, and I’m hoping maybe something has been implemented since the moment it was written.
I tried injecting the AccessDecisionManagerInterface
in my User
entity without any good result. My method (thereafter) does not work because $this->decisionManager
is null. I guess it has not been injected properly. I inject it by the constructor :
public function __construct(AccessDecisionManagerInterface $decisionManager) { $this->decisionManager = $decisionManager; } public function hasRolePermissions(string $role) { $decisionManager = new AccessDecisionManager(); $token = new UsernamePasswordToken($this, '', '', $this->getRoles()); return $this->decisionManager->decide($token, [$role]); }
Although a solution that does not use isGranted
, like a service, or an injection, is perfectly acceptable to me, I would prefer to keep it simple. I was planning to build a twig function, but I would like to know if I’m reinventing the wheel or not. This seems a common enough issue, so I hope there is some built-in functionality I’m not aware of.
Advertisement
Answer
You can use the RoleHierarchy
class to find all “reachable” roles for a current user.
In the Symfony framework, this class is available as the security.role_hierarchy
service (autowirable as SymfonyComponentSecurityCoreRoleRoleHierarchyInterface
).
// check for ROLE_STAFF while taking the role hierarchy into account $isStaff = in_array( 'ROLE_STAFF', $roleHierarchy->getReachableRoles($user->getRoles()) );
You can write a custom Twig extension (e.g. a custom Twig test) to be able to do this in your templates.