1

In Symfony 4, I have a couple of different roles. I have a view in Twig which shows a user list. Users can have multiple roles. In the list, I want to show some text if a user has a role "MANAGER". Showing all roles is done with:

{% for role in user.roles %}
    {{ role }}
{% endfor %}

Now if the user has the role "MANAGER" I want to show some text. I tried:

{% for role in user.roles %}
    {% if (role is "MANAGER") %}
        Show some text.
    {% endif %}
{% endfor %}

but this returns the error

Unexpected token "string" of value "MANAGER" ("name" expected).

Same error is shown when I use {% if is "MANAGER") %} and when I use {% if "MANAGER") %} for some reason Show some text. is shown for every role the user has, no matter which role that is. What am I doing wrong?

Dirk J. Faber
  • 4,360
  • 5
  • 20
  • 58

3 Answers3

1

As an answer to your self posted answer: a single role is not an array, the containment operator (see https://twig.symfony.com/doc/2.x/templates.html#containment-operator) supports checks for substrings as well, that's what happening here.

So you check works, but might have false-positives if you have for example a role "MINI_MANAGER", e.g.

{% set role = "MINI_MANAGER" %}
{% if "MANAGER" in role %}
    Some text here.
{% endif %}

will also output "Some text here.". So the better solution would be:

{% for role in user.roles %}
    {% if role == "MANAGER" %}
    Some text here.     
    {% endif %}
{% endfor %}

This could still lead to problems when role is the boolean value "true" (that is not a Twig problem, but normal PHP behavior), so you can also have a look into the "same as" test, see https://twig.symfony.com/doc/2.x/tests/sameas.html

{% for role in user.roles %}
    {% if role is same as("MANAGER") %}
    Some text here.     
    {% endif %}
{% endfor %}
Kevin
  • 260
  • 2
  • 6
  • Thank you for correcting me. Although your answer makes perfect sense, I cannot get the desired effect. When I use your code (either the first or second suggestion) no text 'some text here' is rendered. No error either btw. – Dirk J. Faber Nov 12 '18 at 08:41
  • I am somewhat of an idiot. The role is actually called "ROLE_MANAGER" and not "MANAGER", which is why I did not get the result. Finally figured that out... – Dirk J. Faber Nov 12 '18 at 10:05
0

So it seems I have figured it out. It seems every single role is in fact an array, so you have to check for the value within the array like this:

{% for role in user.roles %}
    {% if "MANAGER" in role %}
    Some text here.     
    {% endif %}
{% endfor %}

I am still not sure why a single role is an array though, but there surely is a reason for that.

Dirk J. Faber
  • 4,360
  • 5
  • 20
  • 58
  • Can you show how you modeled your `User` class and how roles are associated to it? This might explain the behaviour. – xabbuh Nov 12 '18 at 09:47
  • I am using the FOSUser bundle. For new "manager" users I use a lazy way to give them this role with the contruct method: `$this->roles = array('ROLE_MANAGER');` – Dirk J. Faber Nov 12 '18 at 10:02
  • @xabbuh, I figured out what I did wrong. The role is not "MANAGER" but "ROLE_MANAGER". That's why it did not work. Such an elementary mistake... – Dirk J. Faber Nov 12 '18 at 10:06
0

What about this?

{% if is_granted('ROLE_MANAGER') %} 
   Some text here 
{% endif %}

Source: Symfony2 security functions in Twig? How to check the user's role?

See also Symfony Doc

Roles: When a user logs in, they receive a set of roles (e.g. ROLE_ADMIN).

baris1892
  • 981
  • 1
  • 16
  • 29
  • Thank you for the suggestion, but I am not looking for the permissions of the user that is viewing the page, I want to show something in a list of users next to users with the role "MANAGER". – Dirk J. Faber Nov 11 '18 at 16:50