Skip to content

Commit a9ebfee

Browse files
Readded cookbook article which had been moved to MongoDBBundle documentation
1 parent 7aa023d commit a9ebfee

File tree

2 files changed

+275
-0
lines changed

2 files changed

+275
-0
lines changed

cookbook/doctrine/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ Doctrine
1111
reverse_engineering
1212
multiple_entity_managers
1313
custom_dql_functions
14+
registration_form
+274
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
.. index::
2+
single: Doctrine; Simple Registration Form
3+
single: Form; Simple Registration Form
4+
5+
How to implement a simple Registration Form
6+
===========================================
7+
8+
Some forms have extra fields whose values don't need to be stored in the
9+
database. For example, you may want to create a registration form with some
10+
extra fields (like a "terms accepted" checkbox field) and embed the form
11+
that actually stores the account information.
12+
13+
The simple User model
14+
---------------------
15+
16+
You have a simple ``User`` entity mapped to the database::
17+
18+
// src/Acme/AccountBundle/Document/User.php
19+
namespace Acme\AccountBundle\Document;
20+
21+
use Doctrine\ORM\Mapping as ORM;
22+
use Symfony\Component\Validator\Constraints as Assert;
23+
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
24+
25+
/**
26+
* @ORM\Entity
27+
* @UniqueEntity(fields="email", message="Email already taken")
28+
*/
29+
class User
30+
{
31+
/**
32+
* @ORM\Id
33+
* @ORM\Column(type="integer")
34+
* @ORM\GeneratedValue(strategy="AUTO")
35+
*/
36+
protected $id;
37+
38+
/**
39+
* @ORM\Column(type="string", length=255)
40+
* @Assert\NotBlank()
41+
* @Assert\Email()
42+
*/
43+
protected $email;
44+
45+
/**
46+
* @ORM\Column(type="string", length=255)
47+
* @Assert\NotBlank()
48+
*/
49+
protected $password;
50+
51+
public function getId()
52+
{
53+
return $this->id;
54+
}
55+
56+
public function getEmail()
57+
{
58+
return $this->email;
59+
}
60+
61+
public function setEmail($email)
62+
{
63+
$this->email = $email;
64+
}
65+
66+
public function getPassword()
67+
{
68+
return $this->password;
69+
}
70+
71+
// stupid simple encryption (please don't copy it!)
72+
public function setPassword($password)
73+
{
74+
$this->password = sha1($password);
75+
}
76+
}
77+
78+
This ``User`` document contains three fields and two of them (email and
79+
password) should display on the form. The email property must be unique
80+
in the database, this is enforced by adding this validation at the top of
81+
the class.
82+
83+
.. note::
84+
85+
If you want to integrate this User within the security system,you need
86+
to implement the :ref:`UserInterface<book-security-user-entity>` of the
87+
security component .
88+
89+
Create a Form for the Model
90+
---------------------------
91+
92+
Next, create the form for the ``User`` model::
93+
94+
// src/Acme/AccountBundle/Form/Type/UserType.php
95+
namespace Acme\AccountBundle\Form\Type;
96+
97+
use Symfony\Component\Form\AbstractType;
98+
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
99+
use Symfony\Component\Form\FormBuilder;
100+
101+
class UserType extends AbstractType
102+
{
103+
public function buildForm(FormBuilder $builder, array $options)
104+
{
105+
$builder->add('email', 'email');
106+
$builder->add('password', 'repeated', array(
107+
'first_name' => 'password',
108+
'second_name' => 'confirm',
109+
'type' => 'password'
110+
));
111+
}
112+
113+
public function getDefaultOptions(array $options)
114+
{
115+
return array('data_class' => 'Acme\AccountBundle\Document\User');
116+
}
117+
118+
public function getName()
119+
{
120+
return 'user';
121+
}
122+
}
123+
124+
There are just two fields: email and password (repeated to confirm the entered
125+
password). The ``data_class`` option tells the form the name of data class
126+
(i.e. your ``User`` document).
127+
128+
.. tip::
129+
130+
To explore more things about the form component, read this documentation :doc:`file</book/forms>`.
131+
132+
Embedding the User form into a Registration Form
133+
------------------------------------------------
134+
135+
The form that you'll use for the registration page is not the same as the
136+
form for used to simply modify the ``User`` (i.e. ``UserType``). The registration
137+
form will contain further fields like "accept the terms", whose value is
138+
won't be stored into database.
139+
140+
In other words, create a second form for registration, which embeds the ``User``
141+
form and adds the extra field needed. Start by creating a simple class which
142+
represents the "registration"::
143+
144+
// src/Acme/AccountBundle/Form/Model/Registration.php
145+
namespace Acme\AccountBundle\Form\Model;
146+
147+
use Symfony\Component\Validator\Constraints as Assert;
148+
149+
use Acme\AccountBundle\Document\User;
150+
151+
class Registration
152+
{
153+
/**
154+
* @Assert\Type(type="Acme\AccountBundle\Document\User")
155+
*/
156+
protected $user;
157+
158+
/**
159+
* @Assert\NotBlank()
160+
* @Assert\True()
161+
*/
162+
protected $termsAccepted;
163+
164+
public function setUser(User $user)
165+
{
166+
$this->user = $user;
167+
}
168+
169+
public function getUser()
170+
{
171+
return $this->user;
172+
}
173+
174+
public function getTermsAccepted()
175+
{
176+
return $this->termsAccepted;
177+
}
178+
179+
public function setTermsAccepted($termsAccepted)
180+
{
181+
$this->termsAccepted = (boolean)$termsAccepted;
182+
}
183+
}
184+
185+
Next, create the form for this ``Registration`` model::
186+
187+
// src/Acme/AccountBundle/Form/Type/RegistrationType.php
188+
namespace Acme\AccountBundle\Form\Type;
189+
190+
use Symfony\Component\Form\AbstractType;
191+
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
192+
use Symfony\Component\Form\FormBuilder;
193+
194+
class RegistrationType extends AbstractType
195+
{
196+
public function buildForm(FormBuilder $builder, array $options)
197+
{
198+
$builder->add('user', new UserType());
199+
$builder->add('terms', 'checkbox', array('property_path' => 'termsAccepted'));
200+
}
201+
202+
public function getName()
203+
{
204+
return 'registration';
205+
}
206+
}
207+
208+
You don't need to use special method for embedding the ``UserType`` form.
209+
A form is a field, too - so you can add this like any other field, with the
210+
expectation that the corresponding ``user`` property will hold an instance
211+
of the class ``UserType``.
212+
213+
Handling the Form Submission
214+
----------------------------
215+
216+
Next, you need a controller to handle the form. Start by creating a simple
217+
controller for displaying the registration form::
218+
219+
// src/Acme/AccountBundle/Controller/AccountController.php
220+
namespace Acme\AccountBundle\Controller;
221+
222+
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
223+
use Symfony\Component\HttpFoundation\Response;
224+
225+
use Acme\AccountBundle\Form\Type\RegistrationType;
226+
use Acme\AccountBundle\Form\Model\Registration;
227+
228+
class AccountController extends Controller
229+
{
230+
public function registerAction()
231+
{
232+
$form = $this->createForm(new RegistrationType(), new Registration());
233+
234+
return $this->render('AcmeAccountBundle:Account:register.html.twig', array('form' => $form->createView()));
235+
}
236+
}
237+
238+
and its template:
239+
240+
.. code-block:: html+jinja
241+
242+
{# src/Acme/AccountBundle/Resources/views/Account/register.html.twig #}
243+
244+
<form action="{{ path('create')}}" method="post" {{ form_enctype(form) }}>
245+
{{ form_widget(form) }}
246+
247+
<input type="submit" />
248+
</form>
249+
250+
Finally, create the controller which handles the form submission. This performs
251+
the validation and saves the data into the database::
252+
253+
public function createAction()
254+
{
255+
$em = $this->getDoctrine()->getEntityManager();
256+
257+
$form = $this->createForm(new RegistrationType(), new Registration());
258+
259+
$form->bindRequest($this->getRequest());
260+
261+
if ($form->isValid()) {
262+
$registration = $form->getData();
263+
264+
$em->persist($registration->getUser());
265+
$em->flush();
266+
267+
return $this->redirect(...);
268+
}
269+
270+
return $this->render('AcmeAccountBundle:Account:register.html.twig', array('form' => $form->createView()));
271+
}
272+
273+
That's it! Your form now validates, and allows you to save the ``User``
274+
object to the database.

0 commit comments

Comments
 (0)