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 desfForm
- La configuración de los validadores y de los widgets se realiza en el método
setup()
, en vez de en el métodoconfigure()
- 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.