I'd like to insert a checkbox in my form with Symfony. I used CheckboxType in my UserType.php file for field "role". I would like to set the value "ROLE_ADMIN" for when the checkbox is checked. The value of a checkbox is a boolean and at the moment this is why I am stuck. I currently have this error message : Unable to transform value for property path "roles": Expected a Boolean. Which doesn't correspond with the value my database is asking (json type). I think I am missing a step and I don't know how I can move forward in the construction of my form.
How can I set my checkbox value so that "user" role value changes for "ROLE_ADMIN" (instead of "ROLE_USER") when checkbox is checked ?
Register.html.twig
{% extends 'base.html.twig' %}
{% block title %}Incris-toi !{% endblock %}
{% block main %}
<main>
<header></header>
{{form_start(userform)}}
<div class="form container">
<div class="form-floating mb-3">
{{form_widget(userform.email, {'attr' : {'placeholder' : 'Mon adresse e-mail', 'class' : 'form-control'}})}}
{{form_label(userform.email, 'Mon adresse e-mail', {'label_attr' : {'class' : 'label'}})}}
</div>
<div class="form-floating mb-3">
{{form_widget(userform.password.first, {'attr' : {'placeholder' : 'Mon mot de passe', 'class' : 'form-control'}})}}
{{form_label(userform.password.first, 'Mon mot de passe', {'label_attr' : {'class' : 'label'}})}}
</div>
<div class="form-floating">
{{form_widget(userform.password.second, {'attr' : {'placeholder' : 'Confirmation de mon mot de passe', 'class' : 'form-control'}})}}
{{form_label(userform.password.second, 'Confirmation de mon mot de passe', {'label_attr' : {'class' : 'label'}})}}
</div>
<div class="checkbox">
<label class="remember-me-label">
{{form_widget(userform.roles)}}
<span class="checkmark"></span>
Je m'inscris uniquement en tant qu'organisateur.
</label>
</div>
<button class="btn btn-lg btn-outline-primary mt-4 d-flex mx-auto">Je m'inscris</button>
</div>
{{form_end(userform)}}
</main>
{% endblock %}
UserType.php
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('gender')
->add('lastname')
->add('firstname')
->add('birthdate')
->add('occupation')
->add('nationality')
->add('nativelanguage')
->add('wishedlanguages')
->add('email')
->add('password', PasswordType::class, [
'mapped' => false
])
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Les deux mots de passe doivent être identiques.',
'options' => ['attr' => ['class' => 'password-field']],
'required' => true,
'first_options' => ['label' => 'Password'],
'second_options' => ['label' => 'Repeat Password'],
])
->add('roles', CheckboxType::class, [
'label' => 'Role :',
'required' => false,
])
->add('Subcription', SubmitType::class);
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
UserController.php
<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\UserType;
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class UserController extends AbstractController
{
#[Route('/register', name: 'register', methods: ['GET', 'POST'])]
public function createUser(
Request $request,
EntityManagerInterface $entityManagerInterface,
UserPasswordHasherInterface $userPasswordHasherInterface
){
$user = new User();
$userform = $this->createForm(UserType::class, $user);
$userform->handleRequest($request);
if ($userform->isSubmitted() && $userform->isValid()) {
$user->setRoles(["ROLE_USER"]);
$plainPassword = $userform->get('password')->getData();
$hashedPassword = $userPasswordHasherInterface->hashPassword($user, $plainPassword);
$user->setPassword($hashedPassword);
$entityManagerInterface->persist($user);
$entityManagerInterface->flush();
return $this->redirectToRoute('home');
}
return $this->render('front/register.html.twig', [
'userform' => $userform->createView()
]);
}
}
DataTransformerdocumentation. You'll have to return an array with the appropiate value for therolesfield based on the boolean you get from the submission. Or you could do it in the controller with anunmappedfield, but the first option is cleaner.