Ver índice de contenidos del libro

A.2. FormServiceProvider

El proveedor FormServiceProvider proporciona un servicio para crear formularios mediante el componente Form de Symfony.

A.2.1. Parámetros de configuración

El proveedor define los siguientes parámetros configurables:

  • form.secret: valor utilizado para generar y validar el token CSRF de cada formulario. Te recomendamos encarecidamente que establezcas un valor aleatorio y no trivial en este parámetro para proteger tus formularios. Por defecto se utiliza el valor obtenido mediante la ejecución de la expresión md5(__DIR__).

A.2.2. Servicios proporcionados

El proveedor proporciona los siguientes servicios:

A.2.3. Cómo se registra el proveedor

El siguiente código muestra un ejemplo de cómo registrar este proveedor:

use Silex\Provider\FormServiceProvider;
 
$app->register(new FormServiceProvider());

Nota Cuando tu aplicación no define su propio layout para los formularios, Silex utiliza el layout por defecto. El problema es que este layout por defecto utiliza el componente de traducción de contenidos, por lo que debes registrar también el proveedor TranslationServiceProvider.

Si quieres utilizar el servicio de validación de formularios, no olvides registrar también el proveedor ValidatorServiceProvider.

Nota El componente Form de Symfony y todas sus dependencias se incluye cuando descargas Silex en forma de archivo comprimido. Si instalas Silex mediante Composer, debes añadir esta dependencia ejecutando el siguiente comando:

$ composer require symfony/form

Si además utilizas el servicio de validación de formularios, debes añadir las dependencias symfony/config y symfony/translation:

$ composer require symfony/validator symfony/config symfony/translation

La dependencia opcional symfony/security-csrf añade protección frente a los ataques CSRF (y require usar Symfony 2.4 o superior):

$ composer require symfony/security-csrf

Por último, si tu aplicación utiliza formularios dentro de plantillas Twig, debes instalar el bridge que une Twig con los formularios (que a su vez también requiere instalar la dependencia symfony/translation):

$ composer require symfony/twig-bridge symfony/translation

A.2.4. Ejemplos de uso

El proveedor FormServiceProvider proporciona un servicio llamado form.factory para crear formularios, tal y como se muestra en el siguiente ejemplo de uso:

$app->match('/form', function (Request $request) use ($app) {
    // some default data for when the form is displayed the first time
    $data = array(
        'name' => 'Your name',
        'email' => 'Your email',
    );
 
    $form = $app['form.factory']->createBuilder('form', $data)
        ->add('name')
        ->add('email')
        ->add('gender', 'choice', array(
            'choices' => array(1 => 'male', 2 => 'female'),
            'expanded' => true,
        ))
        ->getForm();
 
    $form->handleRequest($request);
 
    if ($form->isValid()) {
        $data = $form->getData();
 
        // hacer algo con los datos enviados
 
        // redirigir al usuario a algún otro sitio
        return $app->redirect('...');
    }
 
    // mostrar el formulario
    return $app['twig']->render('index.twig', array('form' => $form->createView()));
});

La siguiente plantilla index.twig muestra el formulario anterior (recuerda que si utilizas formularios dentro de plantillas Twig, tienes que instalar también la dependencia symfony/twig-bridge):

<form action="#" method="post">
    {{ form_widget(form) }}
 
    <input type="submit" name="submit" />
</form>

Cuando se utiliza el validador de formularios, puedes definir las constraints o restricciones de cada campo al crear el formulario:

use Symfony\Component\Validator\Constraints as Assert;
 
$app->register(new Silex\Provider\ValidatorServiceProvider());
$app->register(new Silex\Provider\TranslationServiceProvider(), array(
    'translator.domains' => array(),
));
 
$form = $app['form.factory']->createBuilder('form')
    ->add('name', 'text', array(
        'constraints' => array(new Assert\NotBlank(), new Assert\Length(array('min' => 5)))
    ))
    ->add('email', 'text', array(
        'constraints' => new Assert\Email()
    ))
    ->add('gender', 'choice', array(
        'choices' => array(1 => 'male', 2 => 'female'),
        'expanded' => true,
        'constraints' => new Assert\Choice(array(1, 2)),
    ))
    ->getForm();

Los tipos propios de formulario se definen extendiendo el servicio form.types:

$app['form.types'] = $app->share($app->extend('form.types', function ($types) use ($app) {
    $types[] = new YourFormType();
 
    return $types;
}));

Las extensiones de formularios se registran extendiendo el servicio form.extensions:

$app['form.extensions'] = $app->share($app->extend('form.extensions', function ($extensions) use ($app) {
    $extensions[] = new YourTopFormExtension();
 
    return $extensions;
}));

Las extensiones de tipos de formulario se registran extendiendo el servicio form.type.extensions:

$app['form.type.extensions'] = $app->share($app->extend('form.type.extensions', function ($extensions) use ($app) {
    $extensions[] = new YourFormTypeExtension();
 
    return $extensions;
}));

Los "type guessers" propios se registran extendiendo el servicio form.type.guessers:

$app['form.type.guessers'] = $app->share($app->extend('form.type.guessers', function ($guessers) use ($app) {
    $guessers[] = new YourFormTypeGuesser();
 
    return $guessers;
}));

A.2.5. Traits

El trait Silex\Application\FormTrait definido por este proveedor añade los siguientes atajos:

  • form: crea una instancia de la clase FormBuilder.
$app->form($data);