Los formularios de Symfony 1.4

4.2. Generando las clases del formulario

En los siguientes ejemplos se va a modificar la información de las tablas articulo, autor, categoria y etiqueta. Para ello, se crean formularios asociados a cada una de las tablas y se configuran los widgets y validadores relacionados con el esquema de la base de datos. Aunque es posible crear estos formularios a mano, se trata de una tarea tediosa y pesada, además de que obliga a repetir la misma información en varios archivos (nombre de columans y campos, máximo tamaño de columnas y campos, etc.) Además, si los formularios se hacen a mano, cada vez que se modifica el modelo, se debe modificar la clase del formulario asociado. Afortunadamente, el plugin de Propel incluye una tarea llamada propel_build-forms que automatiza todo este proceso y genera los formularios relacionados con un objeto del modelo de datos:

$ ./symfony propel:build-forms

Cuando se generan los formularios, esta tarea crea una clase por cada tabla y le añade los validadores y widgets necesarios para cada columna teniendo en cuenta la información disponible en el modelo y la relación entre las tablas.

Nota Las tareas propel:build-all y propel:build-all-load también actualizan las clases de los formularios, ya que invocan de forma automática la clase propel:build-forms.

Después de ejecutar esta tarea, se crea una estructura de archivos en el directorio lib/form/. Considerando el modelo de datos del ejemplo anterior, se crea la siguiente estructura de archivos:

lib/
  form/
    BaseFormPropel.class.php
    ArticuloForm.class.php
    ArticuloEtiquetaForm.class.php
    AutorForm.class.php
    CategoriaForm.class.php
    EtiquetaForm.class.php
    base/
      BaseArticuloForm.class.php
      BaseArticuloEtiquetaForm.class.php
      BaseAutorForm.class.php
      BaseCategoriaForm.class.php
      BaseEtiquetaForm.class.php

La tarea propel:build-forms genera dos clases para cada tabla del esquema, una en el directorio lib/form/base y la otra en el directorio lib/form/. Para la tabla autor por ejemplo, se generan las clases BaseAutorForm y AutorForm que se guardan respectivamente en los archivos lib/form/base/BaseAutorForm.class.php y lib/form/AutorForm.class.php.

La siguiente tabla muestra la jerarquía de las diferentes clases relacionadas con la definición del formulario AutorForm.

Clase Paquete Quién trabaja con ella Descripción
AutorForm Proyecto El programador Redefine el formulario generado automáticamente
BaseAutorForm Proyecto Symfony Basado en el esquema y generado cada vez que se ejecuta la tarea propel:build-forms
BaseFormPropel Proyecto El programador Permite personalizar de forma global los formularios Propel
sfFormPropel Plugin de Propel Symfony Base de todos los formularios Propel
sfForm Symfony Symfony Base de todos los formularios Symfony

Para crear o modificar un objeto de la clase Autor, se utiliza la clase AutorForm que se muestra en el listado 4-2. Como se puede observar, esta clase no contiene ningún método, ya que hereda de BaseAutorForm, que es la clase que se genera automáticamente en función de la configuración. La clase AutorForm es la clase que se utiliza para personalizar y redefinir la configuración del formulario.

Listado 4-2 - Clase AutorForm

class AutorForm extends BaseAutorForm
{
  public function configure()
  {
  }
}

El listado 4-3 muestra el contenido de la clase BaseAutorForm con los validadores y widgets que se han creado automáticamente mediante la introspección de la tabla autor del modelo de datos.

Listado 4-3 - Clase BaseAutorForm que representa el formulario de la tabla autor

class BaseAutorForm extends BaseFormPropel
{
  public function setup()
  {
    $this->setWidgets(array(
      'id'         => new sfWidgetFormInputHidden(),
      'nombre'     => new sfWidgetFormInput(),
      'apellidos'  => new sfWidgetFormInput(),
      'email'      => new sfWidgetFormInput(),
    ));

    $this->setValidators(array(
      'id'         => new sfValidatorPropelChoice(array('model' => 'Autor', 'column' => 'id', 'required' => false)),
      'nombre'     => new sfValidatorString(array('max_length' => 20, 'required' => false)),
      'apellidos'  => new sfValidatorString(array('max_length' => 20, 'required' => false)),
      'email'      => new sfValidatorString(array('max_length' => 255)),
    ));

    $this->widgetSchema->setNameFormat('autor[%s]');

    $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);

    parent::setup();
  }

  public function getModelName()
  {
    return 'Autor';
  }
}

La clase generada automáticamente es muy parecida a los formularios que se han creado en los capítulos anteriores, con las siguientes excepciones:

  • La clase base es BaseFormPropel en vez de sfForm
  • La configuración de los validadores y de los widgets se realiza en el método setup(), en vez de en el método configure()
  • El método getModelName() devuelve el nombre de la clase Propel relacionada con el formulario

Nota Las clases base utilizan el método setup() en vez de configure() para realizar su configuración. De esta forma es posible redefinir la configuración de las clases generadas vacías sin tener que incluir la instrucción parent::configure()

Los nombres de los campos del formulario son idénticos a los nombres de las columnas del esquema de datos: id, nombre, apellidos y email.

Para cada columna de la tabla autor, la tarea propel:build-forms genera un widget y un validador que cumplan con la definición del esquema de datos. Esta tarea siempre genera los validadores más seguros que sean posible. Si se considera por ejemplo el campo id, se podría validar solamente que sea un número entero. Sin embargo, el validador generado automáticamente también comprueba que ese identificador existe (cuando se quiere modificar un objeto existente) o que ese identificador no exista (cuando se quiere crear un nuevo objeto). De esta forma, el validador utilizado es mucho más seguro que simplemente comprobar que es un número entero.

Los formularios generados de forma automática están listos para utilizarse sin realizar ningún cambio. Si se añade la instrucción <?php echo $formulario ?> en la plantilla, ya se dispone de un formulario completamente funcional y con validación de datos sin tener que escribir ni una sola línea de código.

Además de la posibilidad de crear prototipos de forma muy rápida, los formularios generados automáticamente son fáciles de modificar sin tener que editar las clases generadas. La razón es la herencia de las clases base y las clases del formulario.

Cada vez que se modifica el esquema de la base de datos, esta tarea permite volver a generar los formularios para que tengan en cuenta todas las modificaciones realizadas y sin perder toda la configuración realizada en los formularios.