Creating a Registration Form
Some forms have extra fields whose values don't need to be stored in the database. In this example, we'll create a registration form with such field ("terms accepted" checkbox field) and embed the form that actually stores the account information. We'll use MongoDB for storing the data.
The User Model
We begin this tutorial with the model for a User
document:
1 // src/Document/User.php
namespace App\Document;
use Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique as MongoDBUnique;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Symfony\Component\Validator\Constraints as Assert;
#[MongoDB\Document(collection: 'users')]
#[MongoDB\Unique(fields: 'email')]
class User
{
/**
* @MongoDB\Id
*/
#[MongoDB\Id]
protected string $id;
#[MongoDB\Field(type: 'string')]
#[Assert\NotBlank]
#[Assert\Email]
protected ?string $email = null;
#[MongoDB\Field(type: 'string')]
#[Assert\NotBlank]
protected ?string $password = null;
public function getId(): string
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): void
{
$this->email = $email;
}
public function getPassword(): ?string
{
return $this->password;
}
// stupid simple encryption (please don't copy it!)
public function setPassword(?string $password): void
{
$this->password = sha1($password);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
This User
document contains three fields and two of them (email and
password) should be displayed in the form. The email property must be unique
in the database, so we've added this validation at the top of the class.
If you want to integrate this User within the security system, you need
to implement the |
Create a Form for the Model
Next, create the form for the User
model:
1 // src/Form/Type/UserType.php
namespace App\Form\Type;
use App\Document\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('email', EmailType::class);
$builder->add('password', RepeatedType::class, [
'first_name' => 'password',
'second_name' => 'confirm',
'type' => PasswordType::class
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
We added two fields: email and password (repeated to confirm the entered
password). The data_class
option tells the form the name of the class
that holds the underlying data (i.e. your User
document).
To explore more things about the Form component, read its documentation. |
Embedding the User form into a Registration Form
The form that you'll use for the registration page is not the same as the
form used to modify the User
(i.e. UserType
). The registration
form will contain further fields like "accept the terms", whose value won't be
stored in the database.
In other words, create a second form for registration, which embeds the User
form and adds the extra field needed:
1 // src/Form/Model/Registration.php
namespace App\Form\Model;
use App\Document\User;
use Symfony\Component\Validator\Constraints as Assert;
class Registration
{
/**
* @Assert\Type(type="App\Document\User")
*/
protected $user;
/**
* @Assert\NotBlank()
* @Assert\IsTrue()
*/
protected $termsAccepted;
public function setUser(User $user)
{
$this->user = $user;
}
public function getUser()
{
return $this->user;
}
public function getTermsAccepted()
{
return $this->termsAccepted;
}
public function setTermsAccepted($termsAccepted)
{
$this->termsAccepted = (bool) $termsAccepted;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Next, create the form for this Registration
model:
1 // src/Form/Type/RegistrationType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('user', UserType::class);
$builder->add('terms', CheckboxType::class, ['property_path' => 'termsAccepted']);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
You don't need to use any special method to embed the UserType
form.
A form is a field, too - you can add it like any other field, with the
expectation that the corresponding user
property will hold an instance
of the class UserType
.
Handling the Form Submission
Next, you need a controller to handle the form. Start by creating a controller that will display the registration form:
1 // src/Controller/AccountController.php
namespace App\Controller;
use App\Form\Model\Registration;
use App\Form\Type\RegistrationType;
use Doctrine\ODM\MongoDB\DocumentManager;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class AccountController extends AbstractController
{
public function registerAction()
{
$form = $this->createForm(RegistrationType::class, new Registration());
return $this->render('Account/register.html.twig', [
'form' => $form->createView()
]);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
and its template:
Finally, create another action in AccountController
, which will handle
the form submission - perform its validation and save the User into MongoDB:
1 // src/Controller/AccountController.php
public function createAction(DocumentManager $dm, Request $request)
{
$form = $this->createForm(RegistrationType::class, new Registration());
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$registration = $form->getData();
$dm->persist($registration->getUser());
$dm->flush();
return $this->redirect(...);
}
return $this->render('Account/register.html.twig', [
'form' => $form->createView()
]);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
That's it! Your form now validates sent data and allows you to save
the User
object to MongoDB.