FOSUserBundle Invitation ======================== Require an invitation to create a new user is a pattern mostly used for early stage of a project. User enter their invitation code in order to register. ### Invitation model First we need to add the invitation entity. An invitation is represented by a unique code/identifier generated in the constructor: ```php code = substr(md5(uniqid(rand(), true)), 0, 6); } public function getCode() { return $this->code; } public function getEmail() { return $this->email; } public function setEmail($email) { $this->email = $email; } public function isSent() { return $this->sent; } public function send() { $this->sent = true; } public function getUser() { return $this->user; } public function setUser(User $user) { $this->user = $user; } } ``` Next we map our `Invitation` entity to our `User` with a one-to-one ```php invitation = $invitation; } public function getInvitation() { return $this->invitation; } } ``` ### Add invitation to RegistrationFormType Override the default registration form with your own: ```php add('invitation', 'acme_invitation_type'); } public function getName() { return 'acme_user_registration'; } } ``` Create the invitation field: ```php invitationTransformer = $invitationTransformer; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder->addViewTransformer($this->invitationTransformer, true); } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'class' => 'Acme\UserBundle\Entity\Invitation', 'required' => true, )); } public function getParent() { return 'text'; } public function getName() { return 'acme_invitation_type'; } } ``` Create the custom data transformer: ```php entityManager = $entityManager; } public function transform($value) { if (null === $value) { return null; } if (!$value instanceof Invitation) { throw new UnexpectedTypeException($value, 'Acme\UserBundle\Entity\Invitation'); } return $value->getCode(); } public function reverseTransform($value) { if (null === $value || '' === $value) { return null; } if (!is_string($value)) { throw new UnexpectedTypeException($value, 'string'); } return $this->entityManager ->getRepository('Acme\UserBundle\Entity\Invitation') ->findOneBy(array( 'code' => $value, 'user' => null, )); } } ``` Register your custom form type in the container: ```xml %fos_user.model.user.class% ``` Or if you prefer the Yaml version: ```yaml services: acme.registration.form.type: class: Acme\UserBundle\Form\Type\RegistrationFormType arguments: [%fos_user.model.user.class%] tags: [{ name: "form.type", alias: "acme_user_registration" }] acme.invitation.form.type: class: Acme\UserBundle\Form\Type\InvitationFormType arguments: [@acme.invitation.form.data_transformer] tags: [{ name: "form.type", alias: "acme_invitation_type" }] acme.invitation.form.data_transformer: class: Acme\UserBundle\Form\DataTransformer\InvitationToCodeTransformer arguments: [@doctrine.orm.entity_manager] ``` Next overwrite the default `RegistrationFormType` with the one just created : ```yaml # config.yml fos_user: registration: form: type: acme_user_registration ``` Your done, go to your registration form to see the result.