Reputation: 568
I'm running Symfony 3.4 with FosUserBundle.
I customized the registration form in order to get the Roles
included:
$form->add('roles', ChoiceType::class, array(
'choices' => array(
'user' => 'ROLE_USER',
'admin' => 'ROLE_ADMIN'
),
'label' => 'Role :',
'expanded' => true,
'multiple' => true
));
Then roles are now selectable in the registration form through 2 new checkbox... but I'd like to display it with a <select>
tag. When I set the expanded
option to false
I get a select, but if I set the multiple
option to FALSE I get an error:
Array to string conversion
Any idea to fix my issue?
Below is the stack trace:
Symfony\Component\Debug\Exception\ContextErrorException:
Notice: Array to string conversion
at vendor\symfony\symfony\src\Symfony\Component\Form\ChoiceList\ArrayChoiceList.php:73
at Symfony\Component\Form\ChoiceList\ArrayChoiceList->Symfony\Component\Form\ChoiceList\{closure}(array('ROLE_USER'))
at call_user_func(object(Closure), array('ROLE_USER'))
(vendor\symfony\symfony\src\Symfony\Component\Form\ChoiceList\ArrayChoiceList.php:158)
at Symfony\Component\Form\ChoiceList\ArrayChoiceList->getValuesForChoices(array(array('ROLE_USER')))
(vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer.php:32)
at Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer->transform(array('ROLE_USER'))
(vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:1104)
at Symfony\Component\Form\Form->normToView(array('ROLE_USER'))
(vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:350)
at Symfony\Component\Form\Form->setData(array('ROLE_USER'))
(vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper.php:49)
at Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper->mapDataToForms(object(User), object(RecursiveIteratorIterator))
(vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:383)
at Symfony\Component\Form\Form->setData(object(User))
(vendor\friendsofsymfony\user-bundle\Controller\RegistrationController.php:70)
at FOS\UserBundle\Controller\RegistrationController->registerAction(object(Request))
at call_user_func_array(array(object(RegistrationController), 'registerAction'), array(object(Request)))
(var\cache\dev\classes.php:4659)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
(var\cache\dev\classes.php:4614)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
(vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php:200)
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
(web\app_dev.php:29)
Upvotes: 6
Views: 8627
Reputation: 360
2020 - Symfony 5.0.8:
in your FormType file:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('roles', ChoiceType::class, [
'required' => true,
'multiple' => false,
'expanded' => false,
'choices' => [
'User' => 'ROLE_USER',
'Admin' => 'ROLE_ADMIN',
],
]);
$builder->get('roles')
->addModelTransformer(new CallbackTransformer(
function ($rolesArray) {
// transform the array to a string
return count($rolesArray)? $rolesArray[0]: null;
},
function ($rolesString) {
// transform the string back to an array
return [$rolesString];
}
));
}
Upvotes: 6
Reputation: 592
to solve your problem you need a data transformer, because the roles field is actually an array :
add the data transformer to your FormType class along with the roles field instead of adding it in the controller:
$builder->add('roles', ChoiceType::class, array(
'choices' => array(
'user' => 'ROLE_USER',
'admin' => 'ROLE_ADMIN'
),
'label' => 'Role :'
));
//roles field data transformer
$builder->get('roles')
->addModelTransformer(new CallbackTransformer(
function ($rolesArray) {
// transform the array to a string
return count($rolesArray)? $rolesArray[0]: null;
},
function ($rolesString) {
// transform the string back to an array
return [$rolesString];
}
));
Upvotes: 11
Reputation: 384
What is happening is normal : Your property roles is AN ARRAY of string. In your entity you got something like :
/**
* @var array
*/
private $roles = [];
And logically, when you put the option multiple => 'true', Symfony form will treat it like an array and convert each element of your array in string (which they already are).
On the other hand, if you put multiple => false, it will consider the array as a single choice which it is not.
Simply put, you have an inconsistency between your model where your roles property is an array of string, and the form you are trying to create, which considers roles as a single value.
In your case, You have to put multiple => true.
Upvotes: 4