Después de generar todas las clases del formulario, ahora se muestra cómo crear un módulo de Symfony que permita trabajar con todos los objetos a través del navegador web. En los siguientes ejemplos se muestra cómo crear, modificar y borrar objetos de las clases Articulo
, Autor
, Categoria
y Etiqueta
.
En primer lugar se crea el modelo de la clase Autor
. Aunque el módulo se puede crear a mano, el plugin de Propel incluye una tarea llamada propel:generate-crud
que genera un módulo de tipo CRUD basado en una clase del modelo de objetos de Propel:
$ ./symfony propel:generate-crud frontend autor Autor
La tarea propel:generate-crud
requiere tres argumentos:
frontend
: nombre de la aplicación en la que se va a crear el móduloautor
: nombre del módulo que se va a crearAutor
: nombre de la clase del modelo en la que se basa el módulo
Nota El acrónimo CRUD significa Creation / Retrieval / Update / Deletion (Crear / Obtener / Modificar / Borrar) que son las cuatro operaciones básicas que se realizan sobre la información del modelo de datos.
En el listado 4-4 se muestran las cinco acciones que genera la tarea sobre la clase Autor
: listar la información (index
), crear nuevos objetos (create
), modificar los objetos existentes (edit
), guardar los cambios realizados (update
) y borrar los objetos (delete
).
Listado 4-4 - La clase autorActions
generada por la tarea
// apps/frontend/modules/autor/actions/actions.class.php
class autorActions extends sfActions
{
public function executeIndex()
{
$this->autorList = AutorPeer::doSelect(new Criteria());
}
public function executeCreate()
{
$this->form = new AutorForm();
$this->setTemplate('edit');
}
public function executeEdit($request)
{
$this->form = new AutorForm(AutorPeer::retrieveByPk($request->getParameter('id')));
}
public function executeUpdate($request)
{
$this->forward404Unless($request->isMethod('post'));
$this->form = new AutorForm(AutorPeer::retrieveByPk($request->getParameter('id')));
$this->form->bind($request->getParameter('autor'));
if ($this->form->isValid())
{
$autor = $this->form->save();
$this->redirect('autor/edit?id='.$autor->getId());
}
$this->setTemplate('edit');
}
public function executeDelete($request)
{
$this->forward404Unless($autor = AutorPeer::retrieveByPk($request->getParameter('id')));
$autor->delete();
$this->redirect('autor/index');
}
}
En este módulo, el flujo de trabajo del formulario está definido por los métodos create
, edit
y update
. También es posible indicar a la tarea propel:generate-crud
que genere sólo un método que incluya las tres funcionalidades anteriores, mediante la opción --non-atomic-actions
:
$ ./symfony propel:generate-crud frontend autor Autor --non-atomic-actions
El código generado mediante la opción --non-atomic-actions
(ver listado 4-5) es mucho más conciso.
Listado 4-5 - La clase autorActions
generada con la opción --non-atomic-actions
class autorActions extends sfActions
{
public function executeIndex()
{
$this->autorList = AutorPeer::doSelect(new Criteria());
}
public function executeEdit($request)
{
$this->form = new AutorForm(AutorPeer::retrieveByPk($request->getParameter('id')));
if ($request->isMethod('post'))
{
$this->form->bind($request->getParameter('autor'));
if ($this->form->isValid())
{
$autor = $this->form->save();
$this->redirect('autor/edit?id='.$autor->getId());
}
}
}
public function executeDelete($request)
{
$this->forward404Unless($autor = AutorPeer::retrieveByPk($request->getParameter('id')));
$autor->delete();
$this->redirect('autor/index');
}
}
Esta tarea también genera dos plantillas, indexSuccess
y editSuccess
. La plantilla editSuccess
generada no utiliza la instrucción <?php echo $form ?>
. Para modificar este comportamiento, se utiliza la opción --non-verbose-templates
:
$ ./symfony propel:generate-crud frontend autor Autor --non-verbose-templates
Esta opción es muy útil mientras se construye el prototipo de la aplicación, tal y como muestra el listado 4-6.
Listado 4-6 - La plantilla editSuccess
// apps/frontend/modules/autor/templates/editSuccess.php
<?php $autor = $form->getObject() ?>
<h1><?php echo $autor->isNew() ? 'New' : 'Edit' ?> Autor</h1>
<form action="<?php echo url_for('autor/edit'.(!$autor->isNew() ? '?id='.$autor->getId() : '')) ?>" method="post" <?php $form->isMultipart() and print 'enctype="multipart/form-data" ' ?>>
<table>
<tfoot>
<tr>
<td colspan="2">
<a href="<?php echo url_for('autor/index') ?>">Cancel</a>
<?php if (!$autor->isNew()): ?>
<?php echo link_to('Delete', 'autor/delete?id='.$autor->getId(), array('post' => true, 'confirm' => 'Are you sure?')) ?>
<?php endif; ?>
<input type="submit" value="Save" />
</td>
</tr>
</tfoot>
<tbody>
<?php echo $form ?>
</tbody>
</table>
</form>
Nota La opción --with-show
permite generar una acción y una plantilla para visualizar objetos (sólo en modo lectura).
Si ahora se accede a la dirección /frontend_dev.php/autor
, ya se puede utilizar el módulo generado (figuras 4-1 y 4-2). Juega un poco con la interfaz y añade algo de información. El módulo generado permite listar, añadir, modificar y borrar autores. Además, puedes comprobar que las reglas de validación también se aplican a los formularios.
A continuación se realiza la misma operación sobre la clase Articulo
:
$ ./symfony propel:generate-crud frontend articulo Articulo --non-verbose-templates --non-atomic-actions
El código generado es muy parecido al código de la clase Autor
. Sin embargo, si se intenta crear un artículo nuevo, el código lanza un error fatal que se muestra en la figura 4-3.
El formulario ArticuloForm
utiliza el widget sfWidgetFormPropelSelect
para representar la relación entre los objetos Articulo
y Autor
. Este widget crea una lista desplegable con todos los autores disponibles. Para mostrar los autores, los objetos de tipo Autor
se convierten en una cadena de texto mediante el método mágico __toString()
, que debe estar definido en la clase Autor
, como se muestra en el listado 4-7.
Listado 4-7 - Añadiendo el método __toString()
en la clase Autor
class Autor extends BaseAutor
{
public function __toString()
{
return $this->getNombre().' '.$this->getApellidos();
}
}
Siguiendo el ejemplo de la clase Autor
, también se pueden crear métodos __toString()
en las clases Articulo
, Categoria
y Etiqueta
.
Nota La opción method
del widget sfWidgetFormPropelSelect
permite establecer el nombre del método que se utiliza para convertir el objeto en texto.
La figura 4-4 muestra cómo crear un artículo después de incluir el método __toString()
en la clase Autor
.