vendor/bundles/FOS/UserBundle/Resources/doc/overriding_forms.md
changeset 3 e54dfe4d0b2b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/bundles/FOS/UserBundle/Resources/doc/overriding_forms.md	Fri Sep 30 11:24:53 2011 +0200
@@ -0,0 +1,305 @@
+Overriding Default FOSUserBundle Forms
+======================================
+
+## Overriding a Form Type
+
+The default forms packaged with the FOSUserBundle provide functionality for 
+registering new user, updating your profile, changing your password and 
+much more. These forms work well with the bundle's default classes and controllers. 
+But, as you start to add more properties to your `User` 
+class or you decide you want to add a few options to the registration form you 
+will find that you need to override the forms in the bundle.
+
+Suppose that you have created an ORM user class with the following class name, 
+`Acme\UserBundle\Entity\User`. In this class, you have added a `name` property 
+because you would like to save the user's name as well as their username and 
+email address. Now, when a user registers for your site they should enter in their 
+name as well as their username, email and password. Below is an example `$name` 
+property and its validators.
+
+``` php
+// src/Acme/UserBundle/Entity/User.php
+<?php
+
+use FOS\UserBundle\Entity\User as BaseUser;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
+
+class User extends BaseUser
+{
+    /**
+     * @ORM\Id
+     * @ORM\Column(type="integer")
+     * @ORM\GeneratedValue(strategy="AUTO")
+     */
+    protected $id;
+    
+    /**
+     * @ORM\Column(type="string", length="255")
+     *
+     * @Assert\NotBlank(message="Please enter your name.", groups={"Registration", "Profile"})
+     * @Assert\MinLength(limit="3", message="The name is too short.", groups={"Registration", "Profile"})
+     * @Assert\MaxLength(limit="255", message="The name is too long.", groups={"Registration", "Profile"})
+     */
+    protected $name;
+
+    // ...
+}
+```
+
+**Note:**
+
+```
+By default, the Registration validation group is used when validating a new 
+user registration. Unless you have overriden this value in the configuration, 
+make sure you add the validation group named Registration to your name property.
+```
+
+If you try and register using the default registration form you will find that 
+your new `name` property is not part of the form. You need to create a custom 
+form type and configure the bundle to use it.
+
+The first step is to create a new form type in your own bundle. The following 
+class extends the base FOSUserBundle `RegistrationFormType` and then adds the 
+custom `name` field.
+
+``` php
+// src/Acme/UserBundle/Form/Type/RegistrationFormType.php
+<?php
+
+namespace Acme\UserBundle\Form\Type;
+
+use Symfony\Component\Form\FormBuilder;
+use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
+
+class RegistrationFormType extends BaseType
+{
+    public function buildForm(FormBuilder $builder, array $options)
+    {
+        parent::buildForm($builder, $options);
+
+        // add your custom field
+        $builder->add('name');
+    }
+
+    public function getName()
+    {
+        return 'acme_user_registration';
+    }
+}
+```
+
+Now that you have created your custom form type, you must declare it as a service 
+and add a tag to it. The tag must have a `name` value of `form.type` and an `alias` 
+value that is the equal to the string returned from the `getName` method of your 
+form type class. The `alias` that you specify is what you will use in the FOSUserBundle 
+configuration to let the bundle know that you want to use your custom form.
+
+Below is an example of configuring your form type as a service in XML:
+
+``` xml
+<!-- src/Acme/UserBundle/Resources/config/services.xml -->
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
+
+    <services>
+
+        <service id="acme_user.registration.form.type" class="Acme\UserBundle\Form\Type\RegistrationFormType">
+            <tag name="form.type" alias="acme_user_registration" />
+            <argument>%fos_user.model.user.class%</argument>
+        </service>
+
+    </services>
+
+</container>
+```
+
+Or if you prefer YAML:
+
+``` yaml
+# src/Acme/UserBundle/Resources/config/services.yml
+services:
+    acme_user.registration.form.type:
+        class: Acme\UserBundle\Form\Type\RegistrationFormType
+        arguments: [%fos_user.model.user.class%]
+        tags:
+            - { name: form.type, alias: acme_user_registration }
+```
+
+**Note:**
+
+```
+In the form type service configuration you have specified the `fos_user.model.user.class` 
+container parameter as a constructor argument. Unless you have redefined the 
+constructor in your form type class, you must include this argument as it is a 
+requirement of the FOSUserBundle form type that you extended.
+```
+
+Finally, you must update the configuration of the FOSUserBundle so that it will 
+use your form type instead of the default one. Below is the configuration for 
+changing the registration form type in YAML.
+
+``` yaml
+# app/config/config.yml
+fos_user:
+    # ...
+    registration:
+        form:
+            type: acme_user_registration
+```
+
+Note how the `alias` value used in your form type's service configuration tag 
+is used in the bundle configuration to tell the FOSUserBundle to use your custom 
+form type.
+
+## Overriding Form Handlers
+
+There are two ways to override the default functionality provided by the 
+FOSUserBundle form handlers. The easiest way is to  override the `onSuccess` 
+method of the handler. The `onSuccess` method is called after the form has been 
+bound and validated.
+
+The second way is to override the `process` method. Overriding 
+the `process` method should only be necessary when more advanced functionality 
+is necessary when binding and validating the form.
+
+Suppose you want to add some functionality that takes place after a successful 
+user registration. First you need to create a new class that extends 
+`FOS\UserBundle\Form\Handler\RegistrationFormHandler` and then override the 
+protected `onSuccess` method.
+
+``` php
+// src/Acme/UserBundle/Form/Handler/RegistrationFormHandler.php
+<?php
+
+namespace Acme\UserBundle\Form\Handler;
+
+use FOS\UserBundle\Form\Handler\RegistrationFormHandler as BaseHandler;
+use FOS\UserBundle\Model\UserInterface;
+
+class RegistrationFormHandler extends BaseHandler
+{
+    protected function onSuccess(UserInterface $user, $confirmation)
+    {
+        // Note: if you plan on modifying the user then do it before calling the 
+        // parent method as the parent method will flush the changes
+
+        parent::onSuccess($user, $confirmation);
+
+        // otherwise add your functionality here
+    }
+}
+```
+
+**Note:**
+
+```
+If you do not call the onSuccess method of the parent class then the default 
+logic that the FOSUserBundle handler normally executes upon a successful 
+submission will not be performed.
+```
+
+You can also choose to override the `process` method of the handler. If you choose 
+to override the `process` method then you will be responsible for binding the form 
+data and validating it, as well as implementing the logic required upon a 
+successful submission.
+
+``` php
+// src/Acme/UserBundle/Form/Handler/RegistrationFormHandler.php
+<?php
+
+namespace Acme\UserBundle\Form\Handler;
+
+use FOS\UserBundle\Form\Handler\RegistrationFormHandler as BaseHandler;
+
+class RegistrationFormHandler extends BaseHandler
+{
+    public function process($confirmation = false)  
+    {
+        $user = $this->userManager->createUser();
+        $this->form->setData($user);
+
+        if ('POST' == $this->request->getMethod()) {
+            $this->form->bindRequest($this->request);
+            if ($this->form->isValid()) {
+              
+                // do your custom logic here
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
+```
+
+**Note:**
+
+```
+The process method should return true for a successful submission and false 
+otherwise.
+```
+
+Now that you have created and implemented your custom form handler class, you 
+must configure it as a service in the container. Below is an example of 
+configuring your form handler as a service in XML:
+
+``` xml
+<!-- src/Acme/UserBundle/Resources/config/services.xml -->
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
+
+    <services>
+
+        <service id="acme_user.form.handler.registration" class="Acme\UserBundle\Form\Handler\RegistrationFormHandler" scope="request" public="false">
+            <argument type="service" id="fos_user.registration.form" />
+            <argument type="service" id="request" />
+            <argument type="service" id="fos_user.user_manager" />
+            <argument type="service" id="fos_user.mailer" />
+        </service>
+
+    </services>
+
+</container>
+```
+
+Or if you prefer YAML:
+
+``` yaml
+# src/Acme/UserBundle/Resources/config/services.yml
+services:
+    acme_user.form.handler.registration:
+        class: Acme\UserBundle\Form\Handler\RegistrationFormHandler
+        arguments: ["@fos_user.registration.form", "@request", "@fos_user.user_manager", "@fos_user.mailer"]
+        scope: request
+        public: false
+```
+
+Here you have injected other services as arguments to the constructor of our class 
+because these arguments are required by the base FOSUserBundle form handler class 
+which you extended.
+
+Now that your new form handler has been configured in the container, all that is 
+left to do is update the FOSUserBundle configuration.
+
+``` yaml
+# app/config/config.yml
+fos_user:
+    # ...
+    registration:
+        form:
+            handler: acme_user.form.handler.registration
+```
+
+Note how the `id` of your configured service is used in the bundle configuration 
+to tell the FOSUserBundle to use your custom form handler.
+
+At this point, when a user registers on your site your service will be used to 
+handle the form submission.