JeremyC JeremyC - 4 months ago 39
PHP Question

How do I edit user permissions in symfony 2 with a form?

I am having a problem creating a new/edit user form in symfony 2 + FOSUserBundle. I would like to enable an admin to select the user role from a dropdown or radio button list but I can't seem to get it to work. I found this answer here How can I pass a full security roles list/hierarchy to a FormType class in Symfony2? which is the most relevent thing that I could find but it doesn't work.

This is the UserType form as it currently stands. I would like to get the roles from the container but I can't seem to get that to work either without it throwing an error. The roles will populate the dropdown properly but it will not show which role is currently assigned and it won't allow for the information to be updated because it expected it to be an array

$entity->addRoles(array('ROLE_SUPER_ADMIN'));
, but it just submits as a string.

namespace Wes\AdminBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class UserType extends AbstractType
{
private $roles;

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

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
->add('email')
->add('enabled')
->add('roles', 'choice', array(
'choices' => $this->flattenArray($this->roles),
))
->add('firstName')
->add('lastName')
;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Wes\AdminBundle\Entity\User',
'roles' => null,
'userRole' => null,
));
}

public function getName()
{
return 'wes_adminbundle_usertype';
}

private function flattenArray(array $data)
{
$returnData = array();

foreach($data as $key => $value)
{
$tempValue = str_replace("ROLE_", '', $key);
$tempValue = ucwords(strtolower(str_replace("_", ' ', $tempValue)));
$returnData[$key] = $tempValue;
}
return $returnData;
}
}


This is the controller.

public function editAction($id)
{
$em = $this->getDoctrine()->getManager();

$entity = $em->getRepository('WesAdminBundle:User')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find User entity.');
}

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

return $this->render('WesAdminBundle:User:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}

/**
* Edits an existing User entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();

$entity = $em->getRepository('WesAdminBundle:User')->find($id);

if (!$entity) {
throw $this->createNotFoundException('Unable to find User entity.');
}

$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createForm(new UserType($this->container->getParameter('security.role_hierarchy.roles')), $entity);
$editForm->bind($request);

if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();

return $this->redirect($this->generateUrl('wes_admin_user_edit', array('id' => $id)));
}

return $this->render('WesAdminBundle:User:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}


I have been fighting this for a few days now and I can't seem to get it to work properly. Any thoughts?

Answer

Use the userManager provided by FOSUserBundle instead of custom persistence method, because roles array need to be serialized before it is stored to database.

$userManager = $this->container->get('fos_user.user_manager');
$user = $userManager->findUserBy(array('id' => $id));

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

if ($editForm->isValid()) {
    $userManager->updateUser($user);

    return $this->redirect($this->generateUrl('wes_admin_user_edit',
        array('id' => $id)));
}

See https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/user_manager.rst (edited) for more info.

Comments