diff --git a/cookbook/form/data_transformers.rst b/cookbook/form/data_transformers.rst index 680758ddd6d..8a85a6d0985 100644 --- a/cookbook/form/data_transformers.rst +++ b/cookbook/form/data_transformers.rst @@ -16,24 +16,25 @@ to render the form, and then back into a ``DateTime`` object on submit. When a form field has the ``inherit_data`` option set, Data Transformers won't be applied to that field. -Simple Example: Sanitizing HTML on User Input ---------------------------------------------- +.. _simple-example-sanitizing-html-on-user-input: -Suppose you have a Task form with a description ``textarea`` type:: +Simple Example: Transforming String Tags from User Input to an Array +-------------------------------------------------------------------- + +Suppose you have a Task form with a tags ``text`` type:: // src/AppBundle/Form/TaskType.php namespace AppBundle\Form\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', TextareaType::class); + $builder->add('tags', 'text') } public function configureOptions(OptionsResolver $resolver) @@ -46,15 +47,10 @@ Suppose you have a Task form with a description ``textarea`` type:: // ... } -But, there are two complications: - -#. Your users are allowed to use *some* HTML tags, but not others: you need a way - to call :phpfunction:`strip_tags` after the form is submitted; - -#. To be friendly, you want to convert ``
`` tags into line breaks (``\n``) before - rendering the field so the text is easier to edit. +Internally the ``tags`` are stored as an array, but they are displayed +to the user as a simple string, to make them easier to edit. -This is a *perfect* time to attach a custom data transformer to the ``description`` +This is a *perfect* time to attach a custom data transformer to the ``tags`` field. The easiest way to do this is with the :class:`Symfony\\Component\\Form\\CallbackTransformer` class:: @@ -63,27 +59,23 @@ 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', TextareaType::class); + $builder->add('tags', 'text'); - $builder->get('description') + $builder->get('tags') ->addModelTransformer(new CallbackTransformer( - // transform
to \n so the textarea reads easier - function ($originalDescription) { - return preg_replace('##i', "\n", $originalDescription); + // transform array to string so the input reads easier + function ($originalTags) { + return implode(', ', $originalTags); }, - function ($submittedDescription) { - // remove most HTML tags (but not br,p) - $cleaned = strip_tags($submittedDescription, '

'); - - // transform any \n to real
- return str_replace("\n", '
', $cleaned); + function ($submittedTags) { + // transform the string back to Array + return explode(', ', $submittedTags); } )) ; @@ -106,10 +98,8 @@ 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', TextareaType::class) + $builder->create('tags', 'text') ->addModelTransformer(...) );