Search code examples
symfonysymfony3

Hide a field according to its role Symfony 3


First sorry for my english because is not great!

So I want to hide a field according to it's role because if I make with Twig the field to display on the bottom form

My code for understand, this's my LinkType :

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

    ->add('title')
    ->add('link')
    ->add('description')

    // this field to hidden according the role
    ->add('published', CheckboxType::class);
}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\Link'
    ));
}

/**
 * {@inheritdoc}
 */
public function getBlockPrefix()
{
    return 'appbundle_link';
}

a part of Controler:

public function newAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $categories = $em->getRepository('AppBundle:Category')->findAll();
    $subCategories = $em->getRepository('AppBundle:SubCategory')->findAll();
    $gestionCategorie = $this->container->get('app.categorie');
    $link = new Link();

    $repository = $this
        ->getDoctrine()
        ->getManager()
        ->getRepository('AppBundle:Link');

    $category = $repository->findCategory();
    $subCategory = $repository->findSubCategory();

    $form = $this
        ->get('form.factory')
        ->create('AppBundle\Form\LinkType', $link)

        ->add('categories', ChoiceType::class, array(
            //  on inverse les clés et valeurs
            'choices'   => array_flip($category),
            'label'     => "Catégorie",
            'attr'  => ['class' => 'form-control'],
        ))
        ->add('sousCategories', ChoiceType::class, array(
            //  on inverse les clés et valeurs
            'choices'   => array_flip($subCategory),
            'label'     => "Sous-catégorie",
            'attr'  => ['class' => 'form-control'],
        ));

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

If you have other questions, don't hesitate


Solution

  • If you want to do this in the controller, first remove your field in your form class, then add:

    $user = $this->getUser();
    if (in_array('MY_ROLE_NAME', $user->getRoles())) {
        $builder->add('published', CheckboxType::class);
    }
    

    A better and cleaner approach is using a form as a service and injecting token storage service into it:

    // services.yml
    AppBundle\Form\:
        resource: '../../src/AppBundle/Form'
        public: true
        autowire: true
    
    // Form type class
    use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
    
    //...
    
    private $tokenStorage;
    
    public function __construct(TokenStorageInterface $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }
    
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $user = $this->tokenStorage->getToken()->getUser();
        $builder
    
        ->add('title')
        ->add('link')
        ->add('description');
    
        if (in_array('MY_ROLE_NAME', $user->getRoles())) {
            $builder->add('published', CheckboxType::class);
        }
    }