how to check the user role inside form builder in Symfony2?

If you declare your form type as a service, you can inject the token storage in your class.

So you declare the service in services.yml like this:

my_form:
    class: AppBundle\Services\MyFormType
    public: true
    arguments:  ['@security.token_storage']

And the form class like this:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

class MyFormType extends AbstractType
{
    protected $tokenStorage;

    public function __construct(TokenStorage $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $user = $this->tokenStorage->getToken()->getUser();
        // Use the user object to build the form
    }
}

I know this is an old question, but I'd like to put forward a better alternative for checking roles inside a form type.

The issue

The issue with using the TokenInterface and the User object is that it does not check for inheritance. For example, consider the following security.yml:

security:
    role_hierarchy:
        ROLE_ADMIN: ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

If your user has ROLE_SUPER_ADMIN but not ROLE_ADMIN added to their roles, the above solutions will fail if you are using $user->hasRole('ROLE_ADMIN'), as the user does not explicitly have ROLE_ADMIN assigned to their user and hasRole() does not check hierarchy.


The solution

Use the AuthorizationCheckerInterface instead to gain access to the isGranted() function.

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class MyFormType extends AbstractType {

    protected $auth;

    public function __construct(AuthorizationCheckerInterface $auth) {
        $this->auth = $auth;
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {

        // ...

        if($this->auth->isGranted('ROLE_ADMIN')) {
            // Do the thing here
        }
    }
}

This will respect any hierarchy defined in security.yml. If we use the same yml file as above, $auth->isGranted('ROLE_ADMIN') will return true if a user has ROLE_SUPER_ADMIN but not ROLE_ADMIN assigned to their profile.


From controller you have to pass user object to form builder

$form = $this->createForm(
    new YourType(), 
    $data, 
    array('user' => $this->getUser())
);

Then in form builder you can fetch it from $options:

public function buildForm(FormBuilder $builder, array $options)
{
    $user = $options['user']
}

Don't forget to extend setDefaultOptions() with user index:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        ...
        'user' => null
    ));
}