Search code examples
phpsymfonyfosuserbundle

Add Role List to FOS Userbundle Profile Edit Form


This question is similar to Symfony2: Getting the list of user roles in FormBuilder but the answers there are geared towards any form but my question is specific to a form created by the User Bundle. Problem is that the UserBundle Controller creates the form like this:

$form = $this->container->get('fos_user.profile.form');

Because of this I don't know how to send roles to my Form Type.


Solution

  • My answer is similar to the one by @Mihai Aurelian answered on the similar question.

    Created a service called Role Helper:

    <?php
    
    namespace AppBundle\Services;
    
    /**
     * Roles helper displays roles set in config.
     */
    class RolesHelper
    {
      private $rolesHierarchy;
    
      public function __construct($rolesHierarchy)
      {
        $this->rolesHierarchy = $rolesHierarchy;
      }
    
      /**
       * Return roles.
       *
       * @return array
       */
      public function getRoles()
      {
        $roles = array();
    
        array_walk_recursive($this->rolesHierarchy, function($val) use (&$roles) {
          $roles[] = $val;
        });
    
        return array_unique($roles);
      }
    }
    

    Overwrote the Form Type using Overriding Default FOSUserBundle Forms instructions and updated the default constructer to include the RolesHelper as an argument.

    <?php
    
    namespace AppBundle\Form\Type;
    
    use Symfony\Component\Form\FormBuilderInterface;
    use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
    use AppBundle\Services\RolesHelper;
    
    class UserType extends BaseType
    {
      /**
       * @var RolesHelper
       */
      private $roles;
    
      /**
       * @param string $class The User class name
       * @param RolesHelper $roles Array or roles.
       */
      public function __construct($class, RolesHelper $roles)
      {
        parent::__construct($class);
    
        $this->roles = $roles;
      }
    
      /**
       * {@inheritdoc}
       */
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
        parent::buildForm($builder, $options);
    
        $builder->add('firstName')
                ->add('lastName')
                ->add('roles', 'choice', array(
                  'choices' => $this->roles->getRoles(),
                  'required' => false,
                  'multiple'=>true
                ));
      }
    
      /**
       * {@inheritdoc}
       */
      public function getName()
      {
        return 'user_registration';
      }
    }
    

    Updated services.yml

    app_roles_helper:
       class: AppBundle\Services\RolesHelper
       arguments: ['%security.role_hierarchy.roles%']
    

    Added second argument to app_user.registration.form.type in services.yml:

    app_user.registration.form.type:
      class: AppBundle\Form\Type\UserType
      arguments: [%fos_user.model.user.class%, @app_roles_helper]
      tags:
        - { name: form.type, alias: user_registration }