How can I pass a full security roles list/hierarchy to a FormType class in Symfony2?

php, symfony

Solution

In your controller

$editForm = $this->createForm(new UserType(), $entity, array('roles' => $this->container->getParameter('security.role_hierarchy.roles')));

In UserType :

$builder->add('roles', 'choice', array(
    'required' => true,
    'multiple' => true,
    'choices' => $this->refactorRoles($options['roles'])
))

[...]

public function getDefaultOptions()
{
    return array(
        'roles' => null
    );
}

private function refactorRoles($originRoles)
{
    $roles = array();
    $rolesAdded = array();

    // Add herited roles
    foreach ($originRoles as $roleParent => $rolesHerit) {
        $tmpRoles = array_values($rolesHerit);
        $rolesAdded = array_merge($rolesAdded, $tmpRoles);
        $roles[$roleParent] = array_combine($tmpRoles, $tmpRoles);
    }
    // Add missing superparent roles
    $rolesParent = array_keys($originRoles);
    foreach ($rolesParent as $roleParent) {
        if (!in_array($roleParent, $rolesAdded)) {
            $roles['-----'][$roleParent] = $roleParent;
        }
    }

    return $roles;
}

Problem

I have a user edit form where I would like to administer the roles assigned to a user. Currently I have a multi-select list, but I have no way of populating it with the role hierarchy defined in security.yml. Is there some way that I get this information to the form builder in the FormType class? ``` $builder->add('roles', 'choice', array( 'required' => true, 'multiple' => true, 'choices' => array(), )); ``` Looking around I found that I can get the roles from the container in a controller with: ``` $roles = $this->container->getParameter('security.role_hierarchy.roles'); ``` I have also discovered that I could potentially set this as a dependency to be injected on the FormType class in services.xml: ``` <parameters> <parameter key="security.role_heirarchy.roles">ROLE_GUEST</parameter> </parameters> <services> <service id="base.user.form.type.user_form" class="Base\UserBundle\Form\UserType" public="false"> <tag name="form.type" /> <call method="setRoles"> <argument>%security.role_heirarchy.roles%</argument> </call> </service> </services> ``` This however does not work and does not seem to ever call the `setRoles` method. So how can I get this to work?

Original source

Related problems