From 0820e6994ce279840c4fe1596102e1913506c2ac Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sat, 24 Oct 2015 17:43:19 +0200 Subject: [PATCH 1/6] Updated form aliases to FQCNs for forms in book and component --- book/forms.rst | 163 +++++++++++++++---------------- components/form/introduction.rst | 42 ++++---- 2 files changed, 104 insertions(+), 101 deletions(-) diff --git a/book/forms.rst b/book/forms.rst index 63c0d37651e..044703438ac 100644 --- a/book/forms.rst +++ b/book/forms.rst @@ -91,9 +91,9 @@ from inside a controller:: $task->setDueDate(new \DateTime('tomorrow')); $form = $this->createFormBuilder($task) - ->add('task', 'text') - ->add('dueDate', 'date') - ->add('save', 'submit', array('label' => 'Create Task')) + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array('label' => 'Create Task')) ->getForm(); return $this->render('default/new.html.twig', array( @@ -116,8 +116,20 @@ building the form. In this example, you've added two fields to your form - ``task`` and ``dueDate`` - corresponding to the ``task`` and ``dueDate`` properties of the ``Task`` class. -You've also assigned each a "type" (e.g. ``text``, ``date``), which, among -other things, determines which HTML form tag(s) is rendered for that field. +You've also assigned each a "type" (e.g. ``TextType`` and ``DateType``), +represented by its fully qualified class name. Among other things, it determines +which HTML form tag(s) is rendered for that field. + +.. tip:: + + If you are using PHP 5.5 or later you can use the ``::class`` constant of a + form type to get its fully qualified class name. Make sure you include the + class with a ``use`` statement. + +.. versionadded:: 2.8 + To denote the form type, you have to use the fully qualified class name. + Before Symfony 2.8, you could use an alias for each type like 'name' or + 'date'. Finally, you added a submit button with a custom label for submitting the form to the server. @@ -224,9 +236,9 @@ controller:: $task = new Task(); $form = $this->createFormBuilder($task) - ->add('task', 'text') - ->add('dueDate', 'date') - ->add('save', 'submit', array('label' => 'Create Task')) + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array('label' => 'Create Task')) ->getForm(); $form->handleRequest($request); @@ -241,7 +253,7 @@ controller:: 'form' => $form->createView(), )); } - + .. caution:: Be aware that the ``createView()`` method should be called *after* ``handleRequest`` @@ -310,10 +322,10 @@ which of the buttons was clicked to adapt the program flow in your controller. To do this, add a second button with the caption "Save and add" to your form:: $form = $this->createFormBuilder($task) - ->add('task', 'text') - ->add('dueDate', 'date') - ->add('save', 'submit', array('label' => 'Create Task')) - ->add('saveAndAdd', 'submit', array('label' => 'Save and Add')) + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array('label' => 'Create Task')) + ->add('saveAndAdd', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array('label' => 'Save and Add')) ->getForm(); In your controller, use the button's @@ -622,8 +634,8 @@ First, we need to add the two buttons to the form:: $form = $this->createFormBuilder($task) // ... - ->add('nextStep', 'submit') - ->add('previousStep', 'submit') + ->add('nextStep', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') + ->add('previousStep', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') ->getForm(); Then, we configure the button for returning to the previous step to run @@ -632,7 +644,7 @@ so we set its ``validation_groups`` option to false:: $form = $this->createFormBuilder($task) // ... - ->add('previousStep', 'submit', array( + ->add('previousStep', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array( 'validation_groups' => false, )) ->getForm(); @@ -701,7 +713,7 @@ the documentation for each type. The label for the form field can be set using the ``label`` option, which can be applied to any field:: - ->add('dueDate', 'date', array( + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType', array( 'widget' => 'single_text', 'label' => 'Due Date', )) @@ -722,7 +734,7 @@ Now that you've added validation metadata to the ``Task`` class, Symfony already knows a bit about your fields. If you allow it, Symfony can "guess" the type of your field and set it up for you. In this example, Symfony can guess from the validation rules that both the ``task`` field is a normal -``text`` field and the ``dueDate`` field is a ``date`` field:: +``TextType`` field and the ``dueDate`` field is a ``DateType`` field:: public function newAction() { @@ -731,7 +743,7 @@ guess from the validation rules that both the ``task`` field is a normal $form = $this->createFormBuilder($task) ->add('task') ->add('dueDate', null, array('widget' => 'single_text')) - ->add('save', 'submit') + ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') ->getForm(); } @@ -992,9 +1004,9 @@ ways. If you build your form in the controller, you can use ``setAction()`` and $form = $this->createFormBuilder($task) ->setAction($this->generateUrl('target_route')) ->setMethod('GET') - ->add('task', 'text') - ->add('dueDate', 'date') - ->add('save', 'submit') + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') ->getForm(); .. note:: @@ -1064,36 +1076,20 @@ that will house the logic for building the task form:: $builder ->add('task') ->add('dueDate', null, array('widget' => 'single_text')) - ->add('save', 'submit') + ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') ; } - - public function getName() - { - return 'task'; - } } -.. caution:: - - The ``getName()`` method returns the identifier of this form "type". These - identifiers must be unique in the application. Unless you want to override - a built-in type, they should be different from the default Symfony types - and from any type defined by a third-party bundle installed in your application. - Consider prefixing your types with ``app_`` to avoid identifier collisions. - This new class contains all the directions needed to create the task form. It can be used to quickly build a form object in the controller:: // src/AppBundle/Controller/DefaultController.php - // add this new use statement at the top of the class - use AppBundle\Form\Type\TaskType; - public function newAction() { $task = ...; - $form = $this->createForm(new TaskType(), $task); + $form = $this->createForm('AppBundle\Form\Type\TaskType', $task); // ... } @@ -1160,8 +1156,8 @@ the choice is ultimately up to you. Defining your Forms as Services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Defining your form type as a service is a good practice and makes it really -easy to use in your application. +Your form type might have some external dependencies. You can define your form +type as a service, and inject inject all dependencies you need. .. note:: @@ -1169,6 +1165,38 @@ easy to use in your application. :doc:`later on in this book `. Things will be more clear after reading that chapter. +You might want to use a service defined as ``app.my_service`` in your form +type. Create a constructor to your form type to receive the service:: + + // src/AppBundle/Form/Type/TaskType.php + namespace AppBundle\Form\Type; + + use App\Utility\MyService; + use Symfony\Component\Form\AbstractType; + use Symfony\Component\Form\FormBuilderInterface; + + class TaskType extends AbstractType + { + private $myService; + + public function __construct(MyService $mySevice) + { + $this->myService = $myService; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + // You can now use myService. + $builder + ->add('task') + ->add('dueDate', null, array('widget' => 'single_text')) + ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') + ; + } + } + +Define your form type as a service. + .. configuration-block:: .. code-block:: yaml @@ -1177,8 +1205,9 @@ easy to use in your application. services: app.form.type.task: class: AppBundle\Form\Type\TaskType + arguments: ["@app.my_service"] tags: - - { name: form.type, alias: task } + - { name: form.type } .. code-block:: xml @@ -1190,7 +1219,7 @@ easy to use in your application. - + @@ -1198,44 +1227,17 @@ easy to use in your application. .. code-block:: php // src/AppBundle/Resources/config/services.php + $definition = new Definition('AppBundle\Form\Type\TaskType', array( + new Reference('app.my_service'), + )); $container - ->register( + ->setDefinition( 'app.form.type.task', - 'AppBundle\Form\Type\TaskType' + $definition ) - ->addTag('form.type', array( - 'alias' => 'task', - )) + ->addTag('form.type') ; -That's it! Now you can use your form type directly in a controller:: - - // src/AppBundle/Controller/DefaultController.php - // ... - - public function newAction() - { - $task = ...; - $form = $this->createForm('task', $task); - - // ... - } - -or even use from within the form type of another form:: - - // src/AppBundle/Form/Type/ListType.php - // ... - - class ListType extends AbstractType - { - public function buildForm(FormBuilderInterface $builder, array $options) - { - // ... - - $builder->add('someTask', 'task'); - } - } - Read :ref:`form-cookbook-form-field-service` for more information. .. index:: @@ -1360,11 +1362,6 @@ create a form class so that a ``Category`` object can be modified by the user:: 'data_class' => 'AppBundle\Entity\Category', )); } - - public function getName() - { - return 'category'; - } } The end goal is to allow the ``Category`` of a ``Task`` to be modified right @@ -1380,7 +1377,7 @@ class: { // ... - $builder->add('category', new CategoryType()); + $builder->add('category', 'AppBundle\Form\Type\CategoryType'); } The fields from ``CategoryType`` can now be rendered alongside those from diff --git a/components/form/introduction.rst b/components/form/introduction.rst index b654f7bee0a..68f14e10fc9 100644 --- a/components/form/introduction.rst +++ b/components/form/introduction.rst @@ -391,9 +391,13 @@ is created from the form factory. .. code-block:: php-standalone + // PHP 5.5 and above + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; + $form = $formFactory->createBuilder() - ->add('task', 'text') - ->add('dueDate', 'date') + ->add('task', TextType::class) + ->add('dueDate', DateType::class) ->getForm(); var_dump($twig->render('new.html.twig', array( @@ -414,9 +418,10 @@ is created from the form factory. { // createFormBuilder is a shortcut to get the "form factory" // and then call "createBuilder()" on it + $form = $this->createFormBuilder() - ->add('task', 'text') - ->add('dueDate', 'date') + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') ->getForm(); return $this->render('AcmeTaskBundle:Default:new.html.twig', array( @@ -427,8 +432,9 @@ is created from the form factory. As you can see, creating a form is like writing a recipe: you call ``add`` for each new field you want to create. The first argument to ``add`` is the -name of your field, and the second is the field "type". The Form component -comes with a lot of :doc:`built-in types `. +name of your field, and the second is the fully qualified class name. If you +use PHP 5.5 or above, you can use ``::class`` constant of a form type. The Form +component comes with a lot of :doc:`built-in types `. Now that you've built your form, learn how to :ref:`render ` it and :ref:`process the form submission `. @@ -449,8 +455,8 @@ builder: ); $form = $formFactory->createBuilder('form', $defaults) - ->add('task', 'text') - ->add('dueDate', 'date') + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') ->getForm(); .. code-block:: php-symfony @@ -460,8 +466,8 @@ builder: ); $form = $this->createFormBuilder($defaults) - ->add('task', 'text') - ->add('dueDate', 'date') + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') ->getForm(); .. tip:: @@ -550,8 +556,8 @@ method: use Symfony\Component\HttpFoundation\RedirectResponse; $form = $formFactory->createBuilder() - ->add('task', 'text') - ->add('dueDate', 'date') + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') ->getForm(); $request = Request::createFromGlobals(); @@ -578,8 +584,8 @@ method: public function newAction(Request $request) { $form = $this->createFormBuilder() - ->add('task', 'text') - ->add('dueDate', 'date') + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') ->getForm(); $form->handleRequest($request); @@ -626,10 +632,10 @@ option when building each field: use Symfony\Component\Validator\Constraints\Type; $form = $formFactory->createBuilder() - ->add('task', 'text', array( + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType', array( 'constraints' => new NotBlank(), )) - ->add('dueDate', 'date', array( + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType', array( 'constraints' => array( new NotBlank(), new Type('\DateTime'), @@ -643,10 +649,10 @@ option when building each field: use Symfony\Component\Validator\Constraints\Type; $form = $this->createFormBuilder() - ->add('task', 'text', array( + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType', array( 'constraints' => new NotBlank(), )) - ->add('dueDate', 'date', array( + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType', array( 'constraints' => array( new NotBlank(), new Type('\DateTime'), From 291a42a30ead0828a3db2ba5d21787be647e1c07 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sat, 24 Oct 2015 17:46:46 +0200 Subject: [PATCH 2/6] Fixed removed XML tag in form book --- book/forms.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/book/forms.rst b/book/forms.rst index 044703438ac..50ece071427 100644 --- a/book/forms.rst +++ b/book/forms.rst @@ -1219,6 +1219,7 @@ Define your form type as a service. + From 3ab3830f2e35f2001d3283b231c2a1e449ab232f Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sat, 24 Oct 2015 17:48:43 +0200 Subject: [PATCH 3/6] Fixed PHP 5.5+ reference in form component --- components/form/introduction.rst | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/components/form/introduction.rst b/components/form/introduction.rst index 68f14e10fc9..a1c8f14d575 100644 --- a/components/form/introduction.rst +++ b/components/form/introduction.rst @@ -391,13 +391,9 @@ is created from the form factory. .. code-block:: php-standalone - // PHP 5.5 and above - use Symfony\Component\Form\Extension\Core\Type\TextType; - use Symfony\Component\Form\Extension\Core\Type\DateType; - $form = $formFactory->createBuilder() - ->add('task', TextType::class) - ->add('dueDate', DateType::class) + ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') ->getForm(); var_dump($twig->render('new.html.twig', array( From 3237a340e658d3b27ea1d3d9e9c71f3e8f71e006 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Mon, 23 Nov 2015 22:14:27 +0100 Subject: [PATCH 4/6] Updated form constant usage --- book/forms.rst | 84 +++++++++++++++++--------------- components/form/introduction.rst | 74 +++++++++++++++++++++------- 2 files changed, 101 insertions(+), 57 deletions(-) diff --git a/book/forms.rst b/book/forms.rst index 50ece071427..7ee7bff700d 100644 --- a/book/forms.rst +++ b/book/forms.rst @@ -80,6 +80,9 @@ from inside a controller:: use AppBundle\Entity\Task; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; + use Symfony\Component\Form\Extension\Core\Type\SubmitType; class DefaultController extends Controller { @@ -91,9 +94,11 @@ from inside a controller:: $task->setDueDate(new \DateTime('tomorrow')); $form = $this->createFormBuilder($task) - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') - ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array('label' => 'Create Task')) + ->add('task', TextType::class) + // If you use PHP 5.3 or 5.4 you must use + // ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', DateType::class) + ->add('save', SubmitType::class, array('label' => 'Create Task')) ->getForm(); return $this->render('default/new.html.twig', array( @@ -120,16 +125,10 @@ You've also assigned each a "type" (e.g. ``TextType`` and ``DateType``), represented by its fully qualified class name. Among other things, it determines which HTML form tag(s) is rendered for that field. -.. tip:: - - If you are using PHP 5.5 or later you can use the ``::class`` constant of a - form type to get its fully qualified class name. Make sure you include the - class with a ``use`` statement. - .. versionadded:: 2.8 To denote the form type, you have to use the fully qualified class name. - Before Symfony 2.8, you could use an alias for each type like 'name' or - 'date'. + Before Symfony 2.8, you could use an alias for each type like ``'name'`` or + ``'date'``. Finally, you added a submit button with a custom label for submitting the form to the server. @@ -236,9 +235,9 @@ controller:: $task = new Task(); $form = $this->createFormBuilder($task) - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') - ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array('label' => 'Create Task')) + ->add('task', TextType::class) + ->add('dueDate', DateType::class) + ->add('save', SubmitType::class, array('label' => 'Create Task')) ->getForm(); $form->handleRequest($request); @@ -322,10 +321,10 @@ which of the buttons was clicked to adapt the program flow in your controller. To do this, add a second button with the caption "Save and add" to your form:: $form = $this->createFormBuilder($task) - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') - ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array('label' => 'Create Task')) - ->add('saveAndAdd', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array('label' => 'Save and Add')) + ->add('task', TextType::class) + ->add('dueDate', DateType::class) + ->add('save', SubmitType::class, array('label' => 'Create Task')) + ->add('saveAndAdd', SubmitType::class, array('label' => 'Save and Add')) ->getForm(); In your controller, use the button's @@ -634,8 +633,8 @@ First, we need to add the two buttons to the form:: $form = $this->createFormBuilder($task) // ... - ->add('nextStep', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') - ->add('previousStep', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') + ->add('nextStep', SubmitType::class) + ->add('previousStep', SubmitType::class) ->getForm(); Then, we configure the button for returning to the previous step to run @@ -644,7 +643,7 @@ so we set its ``validation_groups`` option to false:: $form = $this->createFormBuilder($task) // ... - ->add('previousStep', 'Symfony\Component\Form\Extension\Core\Type\SubmitType', array( + ->add('previousStep', SubmitType::class, array( 'validation_groups' => false, )) ->getForm(); @@ -681,7 +680,7 @@ boxes. However, the :doc:`date field ` can be configured to be rendered as a single text box (where the user would enter the date as a string in the box):: - ->add('dueDate', 'date', array('widget' => 'single_text')) + ->add('dueDate', DateType::class, array('widget' => 'single_text')) .. image:: /images/book/form-simple2.png :align: center @@ -713,7 +712,7 @@ the documentation for each type. The label for the form field can be set using the ``label`` option, which can be applied to any field:: - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType', array( + ->add('dueDate', DateType::class, array( 'widget' => 'single_text', 'label' => 'Due Date', )) @@ -743,7 +742,7 @@ guess from the validation rules that both the ``task`` field is a normal $form = $this->createFormBuilder($task) ->add('task') ->add('dueDate', null, array('widget' => 'single_text')) - ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') + ->add('save', SubmitType::class) ->getForm(); } @@ -1004,9 +1003,9 @@ ways. If you build your form in the controller, you can use ``setAction()`` and $form = $this->createFormBuilder($task) ->setAction($this->generateUrl('target_route')) ->setMethod('GET') - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') - ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') + ->add('task', TextType::class) + ->add('dueDate', DateType::clas) + ->add('save', SubmitType::class) ->getForm(); .. note:: @@ -1068,6 +1067,7 @@ that will house the logic for building the task form:: use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; + use Symfony\Component\Form\Extension\Core\Type\SubmitType; class TaskType extends AbstractType { @@ -1076,7 +1076,7 @@ that will house the logic for building the task form:: $builder ->add('task') ->add('dueDate', null, array('widget' => 'single_text')) - ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') + ->add('save', SubmitType::class) ; } } @@ -1085,11 +1085,12 @@ This new class contains all the directions needed to create the task form. It ca be used to quickly build a form object in the controller:: // src/AppBundle/Controller/DefaultController.php + use AppBundle\Form\Type\TaskType; public function newAction() { $task = ...; - $form = $this->createForm('AppBundle\Form\Type\TaskType', $task); + $form = $this->createForm(TaskType::class, $task); // ... } @@ -1136,7 +1137,7 @@ the choice is ultimately up to you. $builder ->add('task') ->add('dueDate', null, array('mapped' => false)) - ->add('save', 'submit') + ->add('save', SubmitType::class) ; } @@ -1174,6 +1175,7 @@ type. Create a constructor to your form type to receive the service:: use App\Utility\MyService; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; + use Symfony\Component\Form\Extension\Core\Type\SubmitType; class TaskType extends AbstractType { @@ -1190,7 +1192,7 @@ type. Create a constructor to your form type to receive the service:: $builder ->add('task') ->add('dueDate', null, array('widget' => 'single_text')) - ->add('save', 'Symfony\Component\Form\Extension\Core\Type\SubmitType') + ->add('save', SubmitType::class) ; } } @@ -1228,7 +1230,9 @@ Define your form type as a service. .. code-block:: php // src/AppBundle/Resources/config/services.php - $definition = new Definition('AppBundle\Form\Type\TaskType', array( + use AppBundle\Form\Type\TaskType; + + $definition = new Definition(TaskType::class, array( new Reference('app.my_service'), )); $container @@ -1373,12 +1377,13 @@ class: .. code-block:: php use Symfony\Component\Form\FormBuilderInterface; + use AppBundle\Form\Type\CategoryType; public function buildForm(FormBuilderInterface $builder, array $options) { // ... - $builder->add('category', 'AppBundle\Form\Type\CategoryType'); + $builder->add('category', CategoryType::class); } The fields from ``CategoryType`` can now be rendered alongside those from @@ -1849,10 +1854,10 @@ an array of the submitted data. This is actually really easy:: { $defaultData = array('message' => 'Type your message here'); $form = $this->createFormBuilder($defaultData) - ->add('name', 'text') - ->add('email', 'email') - ->add('message', 'textarea') - ->add('send', 'submit') + ->add('name', TextType::class) + ->add('email', EmailType::class) + ->add('message', TextareaType::class) + ->add('send', SubmitType::class) ->getForm(); $form->handleRequest($request); @@ -1913,12 +1918,13 @@ but here's a short example: use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; + use Symfony\Component\Form\Extension\Core\Type\TextType; $builder - ->add('firstName', 'text', array( + ->add('firstName', TextType::class, array( 'constraints' => new Length(array('min' => 3)), )) - ->add('lastName', 'text', array( + ->add('lastName', TextType::class, array( 'constraints' => array( new NotBlank(), new Length(array('min' => 3)), diff --git a/components/form/introduction.rst b/components/form/introduction.rst index a1c8f14d575..36a13fb9d28 100644 --- a/components/form/introduction.rst +++ b/components/form/introduction.rst @@ -391,9 +391,16 @@ is created from the form factory. .. code-block:: php-standalone + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; + + // ... + $form = $formFactory->createBuilder() - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('task', TextType::class) + // If you use PHP 5.3 or 5.4, you must use + // ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', DateType::class) ->getForm(); var_dump($twig->render('new.html.twig', array( @@ -407,6 +414,8 @@ is created from the form factory. use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; class DefaultController extends Controller { @@ -416,8 +425,10 @@ is created from the form factory. // and then call "createBuilder()" on it $form = $this->createFormBuilder() - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('task', TextType::class) + // If you use PHP 5.3 or 5.4, you must use + // ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') + ->add('dueDate', DateType::class) ->getForm(); return $this->render('AcmeTaskBundle:Default:new.html.twig', array( @@ -446,24 +457,34 @@ builder: .. code-block:: php-standalone + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; + + // ... + $defaults = array( 'dueDate' => new \DateTime('tomorrow'), ); $form = $formFactory->createBuilder('form', $defaults) - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('task', TextType::class) + ->add('dueDate', DateType::class) ->getForm(); .. code-block:: php-symfony + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; + + // ... + $defaults = array( 'dueDate' => new \DateTime('tomorrow'), ); $form = $this->createFormBuilder($defaults) - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('task', TextType::class) + ->add('dueDate', DateType::class) ->getForm(); .. tip:: @@ -515,7 +536,11 @@ by ``handleRequest()`` to determine whether a form has been submitted): .. code-block:: php-standalone - $formBuilder = $formFactory->createBuilder('form', null, array( + use Symfony\Component\Form\Extension\Core\Type\FormType; + + // ... + + $formBuilder = $formFactory->createBuilder(FormType::class, null, array( 'action' => '/search', 'method' => 'GET', )); @@ -524,11 +549,13 @@ by ``handleRequest()`` to determine whether a form has been submitted): .. code-block:: php-symfony + use Symfony\Component\Form\Extension\Core\Type\FormType; + // ... public function searchAction() { - $formBuilder = $this->createFormBuilder('form', null, array( + $formBuilder = $this->createFormBuilder(FormType::class, null, array( 'action' => '/search', 'method' => 'GET', )); @@ -550,10 +577,14 @@ method: use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; + + // ... $form = $formFactory->createBuilder() - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('task', TextType::class) + ->add('dueDate', DateType::class) ->getForm(); $request = Request::createFromGlobals(); @@ -575,13 +606,16 @@ method: .. code-block:: php-symfony + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; + // ... public function newAction(Request $request) { $form = $this->createFormBuilder() - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType') - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType') + ->add('task', TextType::class) + ->add('dueDate', DateType::class) ->getForm(); $form->handleRequest($request); @@ -626,12 +660,14 @@ option when building each field: use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Type; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; $form = $formFactory->createBuilder() - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType', array( + ->add('task', TextType::class, array( 'constraints' => new NotBlank(), )) - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType', array( + ->add('dueDate', DateType::class, array( 'constraints' => array( new NotBlank(), new Type('\DateTime'), @@ -643,12 +679,14 @@ option when building each field: use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Type; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\DateType; $form = $this->createFormBuilder() - ->add('task', 'Symfony\Component\Form\Extension\Core\Type\TextType', array( + ->add('task', TextType::class, array( 'constraints' => new NotBlank(), )) - ->add('dueDate', 'Symfony\Component\Form\Extension\Core\Type\DateType', array( + ->add('dueDate', DateType::class, array( 'constraints' => array( new NotBlank(), new Type('\DateTime'), From f8b080d713baed6232f11039ae79cb7611b56d95 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Mon, 23 Nov 2015 23:20:53 +0100 Subject: [PATCH 5/6] Found more places which use old form types --- best_practices/forms.rst | 24 ++-- components/form/form_events.rst | 28 +++-- components/form/type_guesser.rst | 14 ++- cookbook/doctrine/registration_form.rst | 17 ++- cookbook/form/create_form_type_extension.rst | 22 ++-- cookbook/form/data_transformers.rst | 107 +++++++++++++----- cookbook/form/dynamic_form_modification.rst | 52 +++++---- cookbook/form/inherit_data_option.rst | 29 +++-- reference/forms/types/date.rst | 10 +- reference/forms/types/options/attr.rst.inc | 2 +- .../forms/types/options/by_reference.rst.inc | 4 +- 11 files changed, 189 insertions(+), 120 deletions(-) diff --git a/best_practices/forms.rst b/best_practices/forms.rst index 86b57e633d6..2df876680a1 100644 --- a/best_practices/forms.rst +++ b/best_practices/forms.rst @@ -22,6 +22,9 @@ form in its own PHP class:: use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; + use Symfony\Component\Form\Extension\Core\Type\EmailType; + use Symfony\Component\Form\Extension\Core\Type\DateTimeType; class PostType extends AbstractType { @@ -29,10 +32,10 @@ form in its own PHP class:: { $builder ->add('title') - ->add('summary', 'textarea') - ->add('content', 'textarea') - ->add('authorEmail', 'email') - ->add('publishedAt', 'datetime') + ->add('summary', TextareaType::class) + ->add('content', TextareaType::class) + ->add('authorEmail', EmailType::class) + ->add('publishedAt', DateTimeType::class) ; } @@ -42,14 +45,9 @@ form in its own PHP class:: 'data_class' => 'AppBundle\Entity\Post' )); } - - public function getName() - { - return 'post'; - } } -To use the class, use ``createForm`` and instantiate the new class:: +To use the class, use ``createForm`` and pass the fully qualified class name:: use AppBundle\Form\PostType; // ... @@ -57,7 +55,7 @@ To use the class, use ``createForm`` and instantiate the new class:: public function newAction(Request $request) { $post = new Post(); - $form = $this->createForm(new PostType(), $post); + $form = $this->createForm(PostType::class, $post); // ... } @@ -97,7 +95,7 @@ directly in your form class, this would effectively limit the scope of that form { $builder // ... - ->add('save', 'submit', array('label' => 'Create Post')) + ->add('save', SubmitType::class, array('label' => 'Create Post')) ; } @@ -122,7 +120,7 @@ some developers configure form buttons in the controller:: public function newAction(Request $request) { $post = new Post(); - $form = $this->createForm(new PostType(), $post); + $form = $this->createForm(PostType::class, $post); $form->add('submit', 'submit', array( 'label' => 'Create', 'attr' => array('class' => 'btn btn-default pull-right') diff --git a/components/form/form_events.rst b/components/form/form_events.rst index 5fb51d59fa1..5bde8df6b42 100644 --- a/components/form/form_events.rst +++ b/components/form/form_events.rst @@ -288,10 +288,13 @@ Creating and binding an event listener to the form is very easy:: use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\CheckboxType; + use Symfony\Component\Form\Extension\Core\Type\EmailType; $form = $formFactory->createBuilder() - ->add('username', 'text') - ->add('show_email', 'checkbox') + ->add('username', TextType::class) + ->add('show_email', CheckboxType::class) ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { $user = $event->getData(); $form = $event->getForm(); @@ -304,7 +307,7 @@ Creating and binding an event listener to the form is very easy:: // If the data was submitted previously, the additional value that is // included in the request variables needs to be removed. if (true === $user['show_email']) { - $form->add('email', 'email'); + $form->add('email', EmailType::class } else { unset($user['email']); $event->setData($user); @@ -317,14 +320,17 @@ Creating and binding an event listener to the form is very easy:: When you have created a form type class, you can use one of its methods as a callback for better readability:: + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\CheckboxType; + // ... class SubscriptionType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->add('username', 'text'); - $builder->add('show_email', 'checkbox'); + $builder->add('username', TextType::class); + $builder->add('show_email', CheckboxType::class); $builder->addEventListener( FormEvents::PRE_SET_DATA, array($this, 'onPreSetData') @@ -351,6 +357,7 @@ Event subscribers have different uses: use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; + use Symfony\Component\Form\Extension\Core\Type\EmailType; class AddEmailFieldListener implements EventSubscriberInterface { @@ -370,7 +377,7 @@ Event subscribers have different uses: // Check whether the user from the initial data has chosen to // display his email or not. if (true === $user->isShowEmail()) { - $form->add('email', 'email'); + $form->add('email', EmailType::class); } } @@ -387,7 +394,7 @@ Event subscribers have different uses: // If the data was submitted previously, the additional value that // is included in the request variables needs to be removed. if (true === $user['show_email']) { - $form->add('email', 'email'); + $form->add('email', EmailType::class); } else { unset($user['email']); $event->setData($user); @@ -397,11 +404,14 @@ Event subscribers have different uses: To register the event subscriber, use the addEventSubscriber() method:: + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\CheckboxType; + // ... $form = $formFactory->createBuilder() - ->add('username', 'text') - ->add('show_email', 'checkbox') + ->add('username', TextType::class) + ->add('show_email', CheckboxType::class) ->addEventSubscriber(new AddEmailFieldListener()) ->getForm(); diff --git a/components/form/type_guesser.rst b/components/form/type_guesser.rst index 13a64400118..e1f88f3e96d 100644 --- a/components/form/type_guesser.rst +++ b/components/form/type_guesser.rst @@ -91,6 +91,10 @@ With this knowledge, you can easily implement the ``guessType`` method of the use Symfony\Component\Form\Guess\Guess; use Symfony\Component\Form\Guess\TypeGuess; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\IntegerType; + use Symfony\Component\Form\Extension\Core\Type\NumberType; + use Symfony\Component\Form\Extension\Core\Type\CheckboxType; class PHPDocTypeGuesser implements FormTypeGuesserInterface { @@ -107,25 +111,25 @@ With this knowledge, you can easily implement the ``guessType`` method of the case 'string': // there is a high confidence that the type is text when // @var string is used - return new TypeGuess('text', array(), Guess::HIGH_CONFIDENCE); + return new TypeGuess(TextType::class, array(), Guess::HIGH_CONFIDENCE); case 'int': case 'integer': // integers can also be the id of an entity or a checkbox (0 or 1) - return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE); + return new TypeGuess(IntegerType::class, array(), Guess::MEDIUM_CONFIDENCE); case 'float': case 'double': case 'real': - return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE); + return new TypeGuess(NumberType::class, array(), Guess::MEDIUM_CONFIDENCE); case 'boolean': case 'bool': - return new TypeGuess('checkbox', array(), Guess::HIGH_CONFIDENCE); + return new TypeGuess(CheckboxType::class, array(), Guess::HIGH_CONFIDENCE); default: // there is a very low confidence that this one is correct - return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); + return new TypeGuess(TextType::class, array(), Guess::LOW_CONFIDENCE); } } diff --git a/cookbook/doctrine/registration_form.rst b/cookbook/doctrine/registration_form.rst index 062969242c1..9e19eb205f5 100644 --- a/cookbook/doctrine/registration_form.rst +++ b/cookbook/doctrine/registration_form.rst @@ -157,15 +157,18 @@ Next, create the form for the ``User`` entity:: use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; + use Symfony\Component\Form\Extension\Core\Type\EmailType; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\RepeatedType; class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('email', 'email') - ->add('username', 'text') - ->add('plainPassword', 'repeated', array( + ->add('email', EmailType::class) + ->add('username', TextType::class) + ->add('plainPassword', RepeatedType::class, array( 'type' => 'password', 'first_options' => array('label' => 'Password'), 'second_options' => array('label' => 'Repeat Password'), @@ -213,7 +216,7 @@ controller for displaying the registration form:: { // 1) build the form $user = new User(); - $form = $this->createForm(new UserType(), $user); + $form = $this->createForm(UserType::class, $user); // 2) handle the submit (will only happen on POST) $form->handleRequest($request); @@ -368,15 +371,17 @@ To do this, add a ``termsAccepted`` field to your form, but set its // src/AppBundle/Form/UserType.php // ... use Symfony\Component\Validator\Constraints\IsTrue; + use Symfony\Component\Form\Extension\Core\Type\CheckboxType; + use Symfony\Component\Form\Extension\Core\Type\EmailType; class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('email', 'email'); + ->add('email', EmailType::class); // ... - ->add('termsAccepted', 'checkbox', array( + ->add('termsAccepted', CheckboxType::class, array( 'mapped' => false, 'constraints' => new IsTrue(), )) diff --git a/cookbook/form/create_form_type_extension.rst b/cookbook/form/create_form_type_extension.rst index ec22d8a94a3..ed7d8f2694e 100644 --- a/cookbook/form/create_form_type_extension.rst +++ b/cookbook/form/create_form_type_extension.rst @@ -300,14 +300,16 @@ next to the file field. For example:: use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\FileType; class MediaType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('name', 'text') - ->add('file', 'file', array('image_path' => 'webPath')); + ->add('name', TextType::class) + ->add('file', FileType::class, array('image_path' => 'webPath')); } public function getName() @@ -324,13 +326,13 @@ Generic Form Type Extensions You can modify several form types at once by specifying their common parent (:doc:`/reference/forms/types`). For example, several form types natively -available in Symfony inherit from the ``text`` form type (such as ``email``, -``search``, ``url``, etc.). A form type extension applying to ``text`` -(i.e. whose ``getExtendedType`` method returns ``text``) would apply to all of -these form types. +available in Symfony inherit from the ``TextType`` form type (such as ``email``, +``SearchType``, ``UrlType``, etc.). A form type extension applying to ``TextType`` +(i.e. whose ``getExtendedType`` method returns ``TextType::class``) would apply + to all of these form types. In the same way, since **most** form types natively available in Symfony inherit -from the ``form`` form type, a form type extension applying to ``form`` would -apply to all of these. A notable exception are the ``button`` form types. Also -keep in mind that a custom form type which extends neither the ``form`` nor -the ``button`` type could always be created. +from the ``FormType`` form type, a form type extension applying to ``FormType`` +would apply to all of these. A notable exception are the ``ButtonType`` form +types. Also keep in mind that a custom form type which extends neither the +``FormType`` nor the ``ButtonType`` type could always be created. diff --git a/cookbook/form/data_transformers.rst b/cookbook/form/data_transformers.rst index 72af8108659..c63bce0e54f 100644 --- a/cookbook/form/data_transformers.rst +++ b/cookbook/form/data_transformers.rst @@ -26,13 +26,14 @@ Suppose you have a Task form with a description ``textarea`` type:: use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; // ... class TaskType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->add('description', 'textarea'); + $builder->add('description', TextareaType::class); } public function configureOptions(OptionsResolver $resolver) @@ -62,13 +63,14 @@ class:: use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\FormBuilderInterface; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; // ... class TaskType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->add('description', 'textarea'); + $builder->add('description', TextareaType::class); $builder->get('description') ->addModelTransformer(new CallbackTransformer( @@ -104,8 +106,10 @@ in your code. You can also add the transformer, right when adding the field by changing the format slightly:: + use Symfony\Component\Form\Extension\Core\Type\TextareaType; + $builder->add( - $builder->create('description', 'textarea') + $builder->create('description', TextareaType::class) ->addModelTransformer(...) ); @@ -123,14 +127,17 @@ Start by setting up the text field like normal:: // src/AppBundle/Form/TaskType.php namespace AppBundle\Form\Type; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; + use Symfony\Component\Form\Extension\Core\Type\TextType; + // ... class TaskType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('description', 'textarea') - ->add('issue', 'text') + ->add('description', TextareaType::class) + ->add('issue', TextType::class) ; } @@ -247,13 +254,15 @@ Next, you need to instantiate the ``IssueToNumberTransformer`` class from inside of the entity manager (because ``IssueToNumberTransformer`` needs this). No problem! Just add a ``__construct()`` function to ``TaskType`` and force this -to be passed in. Then, you can easily create and add the transformer:: +to be passed in by registering ``TaskType`` as a service.:: // src/AppBundle/Form/TaskType.php namespace AppBundle\Form\Type; use AppBundle\Form\DataTransformer\IssueToNumberTransformer; use Doctrine\Common\Persistence\ObjectManager; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; + use Symfony\Component\Form\Extension\Core\Type\TextType; // ... class TaskType extends AbstractType @@ -268,8 +277,8 @@ to be passed in. Then, you can easily create and add the transformer:: public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('description', 'textarea') - ->add('issue', 'text', array( + ->add('description', TextareaType::class) + ->add('issue', TextType::class, array( // validation message if the data transformer fails 'invalid_message' => 'That is not a valid issue number', )); @@ -283,18 +292,62 @@ to be passed in. Then, you can easily create and add the transformer:: // ... } -Now, when you create your ``TaskType``, you'll need to pass in the entity manager:: +Define the form type as a service in your configuration files. - // e.g. in a controller somewhere - $manager = $this->getDoctrine()->getManager(); - $form = $this->createForm(new TaskType($manager), $task); +.. configuration-block:: - // ... + .. code-block:: yaml -.. note:: + # src/AppBundle/Resources/config/services.yml + services: + app.form.type.task: + class: AppBundle\Form\Type\TaskType + arguments: ["@doctrine.orm.entity_manager"] + tags: + - { name: form.type } - To make this step easier (especially if ``TaskType`` is embedded into other - form type classes), you might choose to :ref:`register your form type as a service `. + .. code-block:: xml + + + + + + + + + + + + + + .. code-block:: php + + // src/AppBundle/Resources/config/services.php + use AppBundle\Form\Type\TaskType; + + $definition = new Definition(TaskType::class, array( + new Reference('doctrine.orm.entity_manager'), + )); + $container + ->setDefinition( + 'app.form.type.task', + $definition + ) + ->addTag('form.type') + ; +.. tip:: + + For more information about defining form types as services, read + :ref:`register your form type as a service `. + +Now, you can easily use your ``TaskType``:: + + // e.g. in a controller somewhere + $form = $this->createForm(TaskType::class, $task); + + // ... Cool, you're done! Your user will be able to enter an issue number into the text field and it will be transformed back into an Issue object. This means @@ -312,7 +365,7 @@ its error message can be controlled with the ``invalid_message`` field option. // THIS IS WRONG - TRANSFORMER WILL BE APPLIED TO THE ENTIRE FORM // see above example for correct code - $builder->add('issue', 'text') + $builder->add('issue', TextType::class) ->addModelTransformer($transformer); .. _using-transformers-in-a-custom-field-type: @@ -360,12 +413,7 @@ First, create the custom field type class:: public function getParent() { - return 'text'; - } - - public function getName() - { - return 'issue_selector'; + return TextType::class; } } @@ -385,7 +433,7 @@ it's recognized as a custom field type: class: AppBundle\Form\IssueSelectorType arguments: ["@doctrine.orm.entity_manager"] tags: - - { name: form.type, alias: issue_selector } + - { name: form.type } .. code-block:: xml @@ -401,7 +449,7 @@ it's recognized as a custom field type: - + @@ -421,9 +469,7 @@ it's recognized as a custom field type: new Reference('doctrine.orm.entity_manager'), ) ) - ->addTag('form.type', array( - 'alias' => 'issue_selector', - )) + ->addTag('form.type') ; Now, whenever you need to use your special ``issue_selector`` field type, @@ -433,6 +479,7 @@ it's quite easy:: namespace AppBundle\Form\Type; use AppBundle\Form\DataTransformer\IssueToNumberTransformer; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; // ... class TaskType extends AbstractType @@ -440,8 +487,8 @@ it's quite easy:: public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('description', 'textarea') - ->add('issue', 'issue_selector') + ->add('description', TextareaType::class) + ->add('issue', IssueSelectorType::class) ; } diff --git a/cookbook/form/dynamic_form_modification.rst b/cookbook/form/dynamic_form_modification.rst index db442c85740..cf2bca09d11 100644 --- a/cookbook/form/dynamic_form_modification.rst +++ b/cookbook/form/dynamic_form_modification.rst @@ -128,7 +128,7 @@ the event listener might look like the following:: // If no data is passed to the form, the data is "null". // This should be considered a new "Product" if (!$product || null === $product->getId()) { - $form->add('name', 'text'); + $form->add('name', TextType::class); } }); } @@ -178,6 +178,7 @@ class:: use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; + use Symfony\Component\Form\Extension\Core\Type\TextType; class AddNameFieldSubscriber implements EventSubscriberInterface { @@ -194,7 +195,7 @@ class:: $form = $event->getForm(); if (!$product || null === $product->getId()) { - $form->add('name', 'text'); + $form->add('name', TextType::class); } } } @@ -224,24 +225,21 @@ Using an event listener, your form might look like this:: use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvent; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; class FriendMessageFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('subject', 'text') - ->add('body', 'textarea') + ->add('subject', TextType::class) + ->add('body', TextareaType::class) ; $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { // ... add a choice list of friends of the current application user }); } - - public function getName() - { - return 'friend_message'; - } } The problem is now to get the current user and create a choice field that @@ -277,6 +275,10 @@ and fill in the listener logic:: use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Doctrine\ORM\EntityRepository; + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; + use Symfony\Bridge\Doctrine\Form\Type\EntityType; + // ... class FriendMessageFormType extends AbstractType @@ -291,8 +293,8 @@ and fill in the listener logic:: public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('subject', 'text') - ->add('body', 'textarea') + ->add('subject', TextType::class) + ->add('body', TextareaType::class) ; // grab the user, do a quick sanity check that one exists @@ -323,7 +325,7 @@ and fill in the listener logic:: // create the field, this is similar the $builder->add() // field name, field type, data, options - $form->add('friend', 'entity', $formOptions); + $form->add('friend', EntityType::class, $formOptions); } ); } @@ -339,7 +341,7 @@ and fill in the listener logic:: .. note:: The ``multiple`` and ``expanded`` form options will default to false - because the type of the friend field is ``entity``. + because the type of the friend field is ``EntityType::class``. Using the Form ~~~~~~~~~~~~~~ @@ -388,7 +390,7 @@ it with :ref:`dic-tags-form-type`. class: AppBundle\Form\Type\FriendMessageFormType arguments: ["@security.token_storage"] tags: - - { name: form.type, alias: friend_message } + - { name: form.type } .. code-block:: xml @@ -396,7 +398,7 @@ it with :ref:`dic-tags-form-type`. - + @@ -404,7 +406,7 @@ it with :ref:`dic-tags-form-type`. // app/config/config.php $definition = new Definition('AppBundle\Form\Type\FriendMessageFormType'); - $definition->addTag('form.type', array('alias' => 'friend_message')); + $definition->addTag('form.type'); $container->setDefinition( 'app.form.friend_message', $definition, @@ -420,7 +422,7 @@ access to the form factory, you then use:: { public function newAction(Request $request) { - $form = $this->get('form.factory')->create('friend_message'); + $form = $this->get('form.factory')->create(FriendMessageFormType::class); // ... } @@ -428,14 +430,14 @@ access to the form factory, you then use:: If you extend the ``Symfony\Bundle\FrameworkBundle\Controller\Controller`` class, you can simply call:: - $form = $this->createForm('friend_message'); + $form = $this->createForm(FriendMessageFormType::class); You can also easily embed the form type into another form:: // inside some other "form type" class public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->add('message', 'friend_message'); + $builder->add('message', FriendMessageFormType::class); } .. _cookbook-form-events-submitted-data: @@ -461,6 +463,7 @@ sport like this:: use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; + use Symfony\Bridge\Doctrine\Form\Type\EntityType; // ... class SportMeetupType extends AbstractType @@ -468,7 +471,7 @@ sport like this:: public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('sport', 'entity', array( + ->add('sport', EntityType::class, array( 'class' => 'AppBundle:Sport', 'placeholder' => '', )) @@ -485,7 +488,7 @@ sport like this:: $sport = $data->getSport(); $positions = null === $sport ? array() : $sport->getAvailablePositions(); - $form->add('position', 'entity', array( + $form->add('position', EntityType::class, array( 'class' => 'AppBundle:Position', 'placeholder' => '', 'choices' => $positions, @@ -532,6 +535,7 @@ The type would now look like:: // ... use Symfony\Component\Form\FormInterface; + use Symfony\Bridge\Doctrine\Form\Type\EntityType; use AppBundle\Entity\Sport; class SportMeetupType extends AbstractType @@ -539,7 +543,7 @@ The type would now look like:: public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('sport', 'entity', array( + ->add('sport', EntityType::class, array( 'class' => 'AppBundle:Sport', 'placeholder' => '', )); @@ -548,7 +552,7 @@ The type would now look like:: $formModifier = function (FormInterface $form, Sport $sport = null) { $positions = null === $sport ? array() : $sport->getAvailablePositions(); - $form->add('position', 'entity', array( + $form->add('position', EntityType::class, array( 'class' => 'AppBundle:Position', 'placeholder' => '', 'choices' => $positions, @@ -605,7 +609,7 @@ your application. Assume that you have a sport meetup creation controller:: public function createAction(Request $request) { $meetup = new SportMeetup(); - $form = $this->createForm(new SportMeetupType(), $meetup); + $form = $this->createForm(SportMeetupType::class, $meetup); $form->handleRequest($request); if ($form->isValid()) { // ... save the meetup, redirect etc. diff --git a/cookbook/form/inherit_data_option.rst b/cookbook/form/inherit_data_option.rst index 7429baae325..f4e6fdf88d6 100644 --- a/cookbook/form/inherit_data_option.rst +++ b/cookbook/form/inherit_data_option.rst @@ -52,14 +52,15 @@ Start with building two forms for these entities, ``CompanyType`` and ``Customer use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; + use Symfony\Component\Form\Extension\Core\Type\TextType; class CompanyType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('name', 'text') - ->add('website', 'text'); + ->add('name', TextType::class) + ->add('website', TextType::class); } } @@ -70,14 +71,15 @@ Start with building two forms for these entities, ``CompanyType`` and ``Customer use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\AbstractType; + use Symfony\Component\Form\Extension\Core\Type\TextType; class CustomerType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('firstName', 'text') - ->add('lastName', 'text'); + ->add('firstName', TextType::class) + ->add('lastName', TextType::class); } } @@ -91,16 +93,18 @@ for that:: use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; + use Symfony\Component\Form\Extension\Core\Type\TextType; class LocationType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('address', 'textarea') - ->add('zipcode', 'text') - ->add('city', 'text') - ->add('country', 'text'); + ->add('address', TextareaType::class) + ->add('zipcode', TextType::class) + ->add('city', TextType::class) + ->add('country', TextType::class); } public function configureOptions(OptionsResolver $resolver) @@ -109,11 +113,6 @@ for that:: 'inherit_data' => true )); } - - public function getName() - { - return 'location'; - } } The location form has an interesting option set, namely ``inherit_data``. This @@ -135,7 +134,7 @@ Finally, make this work by adding the location form to your two original forms:: { // ... - $builder->add('foo', new LocationType(), array( + $builder->add('foo', LocationType::class, array( 'data_class' => 'AppBundle\Entity\Company' )); } @@ -147,7 +146,7 @@ Finally, make this work by adding the location form to your two original forms:: { // ... - $builder->add('bar', new LocationType(), array( + $builder->add('bar', LocationType::class, array( 'data_class' => 'AppBundle\Entity\Customer' )); } diff --git a/reference/forms/types/date.rst b/reference/forms/types/date.rst index a4fda47bba1..e374b93f946 100644 --- a/reference/forms/types/date.rst +++ b/reference/forms/types/date.rst @@ -56,10 +56,10 @@ This field type is highly configurable, but easy to use. The most important options are ``input`` and ``widget``. Suppose that you have a ``publishedAt`` field whose underlying date is a -``DateTime`` object. The following configures the ``date`` type for that +``DateTime`` object. The following configures the ``DateType`` type for that field as three different choice fields:: - $builder->add('publishedAt', 'date', array( + $builder->add('publishedAt', DateType::class, array( 'input' => 'datetime', 'widget' => 'choice', )); @@ -68,7 +68,7 @@ The ``input`` option *must* be changed to match the type of the underlying date data. For example, if the ``publishedAt`` field's data were a unix timestamp, you'd need to set ``input`` to ``timestamp``:: - $builder->add('publishedAt', 'date', array( + $builder->add('publishedAt', DateType::class, array( 'input' => 'timestamp', 'widget' => 'choice', )); @@ -94,13 +94,13 @@ If your widget option is set to ``choice``, then this field will be represented as a series of ``select`` boxes. The ``placeholder`` option can be used to add a "blank" entry to the top of each select box:: - $builder->add('dueDate', 'date', array( + $builder->add('dueDate', DateType::class, array( 'placeholder' => '', )); Alternatively, you can specify a string to be displayed for the "blank" value:: - $builder->add('dueDate', 'date', array( + $builder->add('dueDate', DateType::class, array( 'placeholder' => array('year' => 'Year', 'month' => 'Month', 'day' => 'Day') )); diff --git a/reference/forms/types/options/attr.rst.inc b/reference/forms/types/options/attr.rst.inc index bbee5888a4a..46238ac023b 100644 --- a/reference/forms/types/options/attr.rst.inc +++ b/reference/forms/types/options/attr.rst.inc @@ -7,6 +7,6 @@ If you want to add extra attributes to an HTML field representation you can use the ``attr`` option. It's an associative array with HTML attributes as keys. This can be useful when you need to set a custom class for some widget:: - $builder->add('body', 'textarea', array( + $builder->add('body', TextareaType::class, array( 'attr' => array('class' => 'tinymce'), )); diff --git a/reference/forms/types/options/by_reference.rst.inc b/reference/forms/types/options/by_reference.rst.inc index a2e80e1d544..1023e625cd9 100644 --- a/reference/forms/types/options/by_reference.rst.inc +++ b/reference/forms/types/options/by_reference.rst.inc @@ -15,8 +15,8 @@ To explain this further, here's a simple example:: ->add('title', 'text') ->add( $builder->create('author', 'form', array('by_reference' => ?)) - ->add('name', 'text') - ->add('email', 'email') + ->add('name', TextType::class) + ->add('email', EmailType::class) ) If ``by_reference`` is true, the following takes place behind the scenes From e1036270a48170f61466f61a71787a98d0ab5194 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Mon, 23 Nov 2015 23:23:56 +0100 Subject: [PATCH 6/6] Fixed wrong indendation --- cookbook/form/create_form_type_extension.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbook/form/create_form_type_extension.rst b/cookbook/form/create_form_type_extension.rst index ed7d8f2694e..85a786066f4 100644 --- a/cookbook/form/create_form_type_extension.rst +++ b/cookbook/form/create_form_type_extension.rst @@ -329,7 +329,7 @@ You can modify several form types at once by specifying their common parent available in Symfony inherit from the ``TextType`` form type (such as ``email``, ``SearchType``, ``UrlType``, etc.). A form type extension applying to ``TextType`` (i.e. whose ``getExtendedType`` method returns ``TextType::class``) would apply - to all of these form types. +to all of these form types. In the same way, since **most** form types natively available in Symfony inherit from the ``FormType`` form type, a form type extension applying to ``FormType``