0

I have build user entity with roles which have field to store the roles in the database:

    /**
     * @var array
     * @ORM\Column(name="roles", type="json_array")
     */
    private $roles = array();   

    public function getRoles()
    {
        $roles = $this->roles;
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }

It is stored like a array in the database. This is build on tutorial. I realize that if it is like a array in the database it will need to be a collection in the form builder right? Here is the code:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('username')
        ->add('password')
        ->add('plainPassword', 'repeated', array('type' => 'password', 'required' => false))
        ->add('roles', 'choice', array(
           'choices' => array(
               'ROLE_USER'   => 'ROLE_USER',
               'ROLE_ADMIN' => 'ROLE_ADMIN'
           ),
           'multiple' => true,
       ))
        ->add('isActive')
        ->add('mail');
}

End the twig render

 {{ form_widget(edit_form.roles) }}

So the basic idea is to have a select field with all the roles to select for a user and then update the database. But for some reason when i remove

'multiple' => true

I got error like this ...

enter image description here

What is the best workaround here? I want not to have multiple choice but only single one.

And the last thing is that it not populate the database but i got the information and when I call before persist it saves them but not on default.

 $entity->setRoles($entity->getRoles());

1 Answer 1

1

You have to transform your values.

You can build a widget

    <?php

namespace Atix\UserBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Atix\UserBundle\Form\DataTransformer\RolesFormDataTransformer;

class RolesFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new RolesFormDataTransformer();
        $builder->add('roles', 'choice', array(
            'choices'   => array(
                            'ROLE_P1'        => 'Role p1',
                            'ROLE_RESPONSABLE'   => 'Role responsable',
                            'ROLE_ADMIN'             => 'Role admin',
                            ),
            'label' => false,
            'required'  => false
        ))->addModelTransformer($transformer);

    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        // $resolver->setDefaults(array(
        //     'data_class' => '',
        // ));
    }

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

And your datatransformer

<?php

namespace Atix\UserBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

class RolesFormDataTransformer implements DataTransformerInterface
{
    /**
     * Transforms an array to a string.
     * POSSIBLE LOSS OF DATA
     *
     * @return string
     */
    public function transform($array)
    {
        if (empty($array)) {
            return $array;
        }

        $newArray = array();
        $newArray["roles"] = $array;

        return $newArray;
    }

    /**
     * Transforms a string to an array.
     *
     * @param  string $string
     *
     * @return array
     */
    public function reverseTransform($array)
    {

        //var_dump($string);
        $aRoles = array();
        foreach($array as $allValue)
        {
            foreach($allValue as $value)
            {
                $aRoles[] = $value;
            }
        }
        return $aRoles;
    }
}

You declare the form at a service

user.form.type.roles:
    class: Atix\UserBundle\Form\Type\RolesFormType
    tags:
        - { name: form.type, alias: roles_widget }

You can now call your widget like this

$builder->add('roles', 'roles_widget');
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.