Por favor, haz un clic sobre los anuncios cuando pases por mi blog, ya? =)

Zend Framework 6: Creando las paginas web

27 comentarios
Esta es la sexta parte de mi tutorial de ZF. la parte anterior está acá.

Lo ultimo que hicimos fue crear las clases que forman el Modelo de datos, es decir, las clases que interactuarán con la base de datos. Creamos una clase por cada tabla de la base de datos usando el comando
create db-table

Despues le pusimos algo de código a cada clase, para poder insertar, modificar, borrar y listar los datos de cada tabla.

Ahora, crearemos las páginas web que mostrarán el contenido de cada tabla.
 ¿Como hacemos eso? Pues a través de las acciones. Recuerden Que creamos los controladores:
  • AlbumController : encargado de manejar a la tabla album
  • ArtistaController : encargado de manejar a la tabla artista
  • TemaController : encargado de manejar a la tabla...(corecto, intuitivo lector: a la tabla tema)

Abramos en Netbeans la clase AlbumController.php (ubicada en /applications/controllers), y en la accion IndexAction() coloquemos lo siguiente:

public function indexAction()
    {
        //creo objeto que maneja la tabla album
        $table = new Application_Model_DbTable_Album(); 
        //obtengo listado de todas las filas de la tabla, y las
        //coloco en la variable datos de la pagina web (de la vista) 
        //que vamos a mostrar

        $this->view->datos = $table->listar();
    }


Bien, ¿que estamos haciendo aquí? Primero, creamos un objeto de la clase Application_Model_DbTable_Album, el cual ,como ya vimos, es el encargado de accecer a los datos de la tabla Album. Luego, llamamos a la funcion listar(), la cual nos devuelve todos los datos de la tabla, en un arreglo de filas, donde cada fila es un arreglo asociativo:



array(
       array( campo1=>'valor 1', campo2=>'valor 2', campo3=> 'valor 3'), //fila 1
        array( campo1=>'valor 1', campo2=>'valor 2', campo3=> 'valor 3'), //fila 2
        array( campo1=>'valor 1', campo2=>'valor 2', campo3=> 'valor 3'), //fila 3
       .....
); 

Guardamos ese listado de filas en $this->view->datos. Al hacer esto, creamos la variable 'datos' en la vista view, es decir, en la pagina web que se asocia a esta accion. Ahora, en dicha página web deberemos mostrar los datos de ese arreglo. Abramos la página web asociada (/application/views/scripts/album/index.phtml) o podemos ir directamente haciendo clic dentro de ActionIndex(), boton derecho, menu Navigate/go to View.

En /application/views/scripts/album/index.phtml colocaremos lo siguiente:

<!--creo link para agregar un album -->
<a href="<?php echo $this->url(array('controller' => 'album',
            'action' => 'add', 'id' => $d->id)); ?>">Agregar Album</a>

<!--creo una tabla para mostrar los datos-->
<table>
    <tr>
        <th>Nombre</th>
        <th>Artista</th>
        <th>Fecha</th>
        <th>Descripcion</th>
        <th>Borrar</th>
    </tr>
<!--    recorro el arreglo de datos-->
    <?php foreach ($this->datos as $d) : ?>
<!--           por cada fila, muestro sus datos -->
        <tr>
<!--            nombre del album, con un enlace para editar el album-->
            <td>
                <a href="<?php echo $this->url(array('controller' => 'album',
            'action' => 'update', 'id' => $d->id)); ?>">
                   <?php echo $d->nombre; ?>
            </a>
        </td>
<!--                id del artista-->
        <td><?php echo $this->escape($d->artista_id); ?></td>
<!--                    fecha del album-->
        <td><?php echo $this->escape($d->fecha); ?></td>
<!--                        descripcion-->
        <td><?php echo $d->descripcion; ?></td>
<!--                   enlace para borrar el album-->
        <td>

            <a href="<?php echo $this->url(array('controller' => 'album',
                       'action' => 'delete', 'id' => $d->id)); ?>">Delete</a>
            </td>
        </tr>
<!--    fin del for-->
    <?php endforeach; ?>
</table>

Guardemoslo y veamos como se ve:
coloquemos en nuestro navegador http://localhost/miproyecto/public/album
Y veremos algo como esto:


El codigo en HTML de la pagina es:

<a href="/miproyecto/public/album/add">Agregar Album</a>

<table>
    <tr>
        <th>Nombre</th>
        <th>Artista</th>
        <th>Fecha</th>
        <th>Descripcion</th>
        <th>Borrar</th>
    </tr>
    <tr>
        <td>
            <a href="/miproyecto/public/album/update/id/1">
                Nos sobran los motivos            </a>
        </td>
        <td>1</td>
        <td>2000-09-10</td>
        <td>grabacion en vivo</td>
        <td>
            <a href="/miproyecto/public/album/delete/id/1">Delete</a>
        </td>
    </tr>
    <tr>
        <td>
            <a href="/miproyecto/public/album/update/id/2">
                de juez y parte            </a>
        </td>
        <td>1</td>
        <td>1995-09-10</td>
        <td>album</td>
        <td>
            <a href="/miproyecto/public/album/delete/id/2">Delete</a>
        </td>
    </tr>
<!--    ... aca van las demas filas-->
  
</table>

 Bien, los comentarios en el código explican casi todo el proceso. Lo fundamental acá es:

<?php foreach ($this->datos as $d) : ?>
<!--                nombre del album -->
          <?php echo $d->nombre; ?>          
<!--                id del artista-->
        <?php echo $this->escape($d->artista_id); ?>
<!--                    fecha del album-->
        <?php echo $this->escape($d->fecha); ?>
<!--                        descripcion-->
        <?php echo $d->descripcion; ?>
      
<!--    fin del for-->
<?php endforeach; ?>


De esa forma recorremos los datos. El adorno que le pongamos para mostrarlo, depende de nuestras preferencias.

Con

<!--creo link para agregar un album -->
<a href="<?php echo $this->url(array('controller' => 'album',
            'action' => 'add', 'id' => $d->id)); ?>">Agregar Album</a>

Lo que hacemos es crear un link hacia el controlador/accion indicados, como podemos ver en el HTML resultante:

<a href="/miproyecto/public/album/add">Agregar Album</a>

De esa forma, podemos crear enlaces a las acciones que deseemos llamar sin preocuparnos ror la URL final. Aunque de todas formas podemos hacerlo de la forma convencional, si lo deseamos.

Observemos que tambén tenemos dos enlaces más: uno para editar el album, y otro para borrarlo.

Ahora procederemos a escribir código para que estos funcionen.

Creando formularios

Para poder crear y editar álbumes, necesitamos un formulario. ZF tiene clases especiales para crear formularios. La ventaja de usarlas es que en el momento de crealo podemos indicar los validadores para cada elemento (cuales son requeridos, cuales debne ser solo numeros, o tener un formato determinado, etc) y al ser llenados por el usuario, ZF los validará pos sí mismo, y mostrará mensajes de error si es necesario.

Para crear un formulario, abrimos la ventana con los comandos de ZF desde Netbeans (Alt+Z, como habíamos configurado antes) en el filtro escribimos form, seleccionamos el comando create form y escribimos album:



Esto creará en nuetra carpeta /application /forms un archivo llamado AlbumForm.php:

class Application_Form_Albumform extends Zend_Form
{

    public function init()
    {
     
    }
}


En la función init() deberemos crear los elementos que tendrá nuestro formulario, y al final agregarlos a este.
Reemplacen el código por este:

<?php

class Application_Form_Albumform extends Zend_Form
{

    public function init()
    {
       $this->setName('albums');

        //campo hidden para guardar id de album
        $id = new Zend_Form_Element_Hidden('id');
        $id->addFilter('Int');

        //creamos <input text> para escribir nombre album
        $nombre = new Zend_Form_Element_Text('nombre');
        $nombre->setLabel('Nombre del album:')->setRequired(true)->
                addFilter('StripTags')->addFilter('StringTrim')->
                addValidator('NotEmpty');

        //creamos select para seleccionar artista
        $artista = new Zend_Form_Element_Select('artista_id');
        $artista->setLabel('Seleccione artista:')->setRequired(true);
        //cargo en un select los tipos de usuario
        $table = new Application_Model_DbTable_Artista();
        //obtengo listado de todos los artistas y los recorro en un
        //arreglo para agregarlos a la lista
        foreach ($table->listar() as $c)
        {
            $artista->addMultiOption($c->id, $c->nombre);
        }

        //descripcion album
        $descripcion = new Zend_Form_Element_Text('descripcion');
        $descripcion->setLabel('Descripcion:')->setRequired(false)->addFilter('StripTags')->addFilter('StringTrim');

        //fecha lanzamiento
        $fecha = new Zend_Form_Element_Text('fecha');
        $fecha->setLabel('Fecha lanzamiento:')->setRequired(true)->addFilter('StripTags')->
                addFilter('StringTrim')->addValidator('NotEmpty');
        //creo un validador de formato de fecha
        $valiDate = new Zend_Validate_Date();
        $valiDate->setFormat('dd-mm-YYYY');
        $fecha->addValidator($valiDate);
        $fecha->setValue(date("d-m-Y"));

        //boton para enviar formulario
        $submit = new Zend_Form_Element_Submit('submit');
        $submit->setAttrib('id', 'submitbutton');

        //agregolos objetos creados al formulario
        $this->addElements(array($id, $nombre,
            $artista, $descripcion, $fecha, $submit));
    }

}

¿Confuso? Tal vez al principio. Como puedes ver, en ZF existen objetos para crear cada elemento de un formulario:


Zend_Form_Element_Hidden: crea un elemento hidden el el form.
Ejemplo:
new Zend_Form_Element_Hidden('id') crea
<input type="hidden" name="id"value="0" id="id" />

Zend_Form_Element_Text: crea un input tipo texto.
Ejemplo:
new Zend_Form_Element_Text('nombre') crea
<input type="text" name="nombre" id="nombre" value="" />

Zend_Form_Element_Select: crea un objeto select
Ejemplo:
Zend_Form_Element_Select('artista_id') crea
<select name="artista_id" id="artista_id">
    <option value="1" label="Joaquin sabina">Joaquin sabina</option>
    <option value="2" label="bruce dickinson">bruce dickinson</option>
    <option value="3" label="yann tiernsen">yann tiernsen</option>
    <option value="4" label="Marea">Marea</option>
</select>

Zend_Form_Element_Submit: crea un botón para enviar el formulario
Ejemplo:
new Zend_Form_Element_Submit('submit')
crea
<input type="submit" name="submit" id="submitbutton" value="Add" />

Tambien hay objetos para radio buttosn y checkboxes, pero no los trataremos aquí.




Validadores y Filtros


A cada objeto del formulario le podemos agregar validadores y filtros, segun deseemos.
  • Un validador es un objeto que exige que los datos del objeto tengan cierto formato, o estén llenados  y si no es así, muestra un error al usuario, exigiendole que lo corrija.
  • Un filtro extrae caracteres o convierte los datos del objeto antes de entregarselos a la aplicacion. Por ejemplo, le saca los espacios en blanco al principio y al final, le extrae los caracteres extraños, convierte todo a mayusculas, etc.
Hay dos fomras de agregar validadores: usando el nombre de la clase, o creando un objeto validador y asignandoselo al objeto del formulario. Los mismo para los filtros.

un validador se agrega llamando a la funcion
$objeto->addValidator($validador); ó bien $objeto->addValidator('NombreClaseValidadora');
y un filtro,
$objeto->addFilter($filtro); ó bien $objeto->addFilter('NombreClaseFiltro');

Ejemplos:

//creamos <input text> para escribir nombre album
        $nombre = new Zend_Form_Element_Text('nombre');
        $nombre->setLabel('Nombre del album:')->setRequired(true)->
                addFilter('StripTags')->addFilter('StringTrim')->
                addValidator('NotEmpty'); 

Creamos un objeto input text , con el label 'nombre del Album', con ->setRequired(true); indicamos que es un campo obligatorio.
Con
addFilter('StripTags'); indico que al obtener el valor de este campo, se le extraegan los tags 'extraños' como los de html, en caso de que los contuviera.
->addFilter('StringTrim'); le sacará los espacios en blanco al principio y al final antes de devolver el valor.
->addValidator('NotEmpty'); exige que este campo contenga algo. Si no es así, el formulario se volverá a mostrar en pantalla, con un aviso de error.

Otro ejemplo:

//fecha lanzamiento
        $fecha = new Zend_Form_Element_Text('fecha');
        $fecha->setLabel('Fecha lanzamiento:')->setRequired(true)
        ->addFilter('StripTags')->
                addFilter('StringTrim')->addValidator('NotEmpty');
        //creo un validador de formato de fecha
        $valiDate = new Zend_Validate_Date();
        $valiDate->setFormat('dd-mm-YYYY');
        $fecha->addValidator($valiDate);
        $fecha->setValue(date("d-m-Y"));

Este caso tiene los mismos filtros y validadores del anterior, pero también tiene uno especial para validar fechas. Al agregarlo, si en este campo introducimos algo que no sea una fecha, o una fecha que no esté en la forma dia-mes-año, se mostrará un error al usuario.

Podemos encontrar un listado de todos los validadores disponibles e instrucciones de cómo crear los propios en http://framework.zend.com/manual/en/zend.validate.set.html  y de los filtros, en http://framework.zend.com/manual/en/zend.filter.set.html


Con respecto al campo select, podemos ver cómo se llena con un listado de los artistas, extraido de la base de datos.

//creamos select para seleccionar artista
        $artista = new Zend_Form_Element_Select('artista_id');
        $artista->setLabel('Seleccione artista:')->setRequired(true);
        //cargo en un select los tipos de usuario
        $table = new Application_Model_DbTable_Artista();
        //obtengo listado de todos los artistas y los recorro en un
        //arreglo para agregarlos a la lista
        foreach ($table->listar() as $c)
        {
            $artista->addMultiOption($c->id, $c->nombre);
        } 


Con
foreach ($table->listar() as $c)
 {
    $artista->addMultiOption($c->id, $c->nombre);
 }
recorro el listado de artistas y agrego nuevos elementos al select con el método
$objetoSelect->addMultiOption($clave, $texto);

Una vez creados nuestros objetos, los agregamos al formulario con el método

$this->addElements(array($id, $nombre,
            $artista, $descripcion, $fecha, $submit));

Los elementos se agregarán en el orden en que los coloquemos aquí.

IMPORTANTE:
el id de cada objeto del form debe tener el MISMO NOMBRE  del campo de la base de datos que mostrará. De esta forma los datos se cargarán 'solos' desde la base de datos al momento de querer editar un álbum (más de esto después)

Una vez creado nuestro formulario, ya estamos en posición de usarlos para agregar y modificar álbumes.
Veamos el siguiente artículo

27 comentarios :

Anónimo dijo...

Vamos!, quiero la siguiente parte!

Un abrazo y te felicito por tu gran trabajo!.

Saludos. Damián.

Travianero dijo...

cuando creo el form deberia crearse el archivo llamado AlbumForm.php, pero a mi crea el archivo llama Album.php (sin el form). Es porque no lo estoy haciendo bien?

Angelorum dijo...

MM sí, el archivo debe llamarse AlbumForm.php y debe guardarlo en la carpeta forms.

Estas seguro que en los comandos de ZF seleccionas 'create form' ?

Travianero dijo...

lo he hecho tal cual esta en el tutorial. La carpeta forms se crea atumaticamente y dentro se crea el archivo Album.php y no AlmubForm.php
A lo mejor para que salga le pongo en parametros albumform y no solo album xD

Anónimo dijo...

disculpe amigo a mi me paso igual solo sale album.php, debe ser porq uso zend framework 1.11.0 talvez uses el mismo q yo, creo q angel en este tutorial usa 1.10... lo digo solo porq el copiar pegar no funciono en ocaciones y al leer el codio, este varia un poco... Saludos y muchas gracias por el tuto!!

juan carlos dijo...

hola hace un 1 año que voy manejando zend ya que estoy elaborando una aplicacion como defensa de mi trabajo de grado la aplicacion consite en registrar y realizar unas transacciones(pago de mes de alquiler) la parte que ya desarrolle es la parte de registro ahora me toca la parte de la transaccion y esto implica recuperar datos de las tablas para poder realizar una transacion y no tengo idea de como recuperar los datos de la tabla ya que son numeros y antes de que recupere necesito calcule cuanto debe antes de que se muestre en el phtml

Angelorum dijo...

Eso en sí no es una consulta específica de Zend Framework.

Podrías calcular el cuanto $ debe usanndo una consulta SQL, o bien podrías hacerlo usando PHP, tal vez reocrriendo el arreglo de objetos que te devolvió la consulta y sumando o restando las cantidades hasta calcular la deuda.

Imagino que en alguna parte guardas el total del monto a pagar, y en otra parte los abonos de dinero que hacen. Podrias usar un sql que te devuelva la suma de tosos los abonos, y despues comparar eso con el monto total.
Saludos

turismo medico dijo...

Excelente aporte, me ha aclarado muchas dudas al respecto. un saludo!

Mt2h dijo...

excelente ;)

JuZaM dijo...

Excelente guia. Pero me ha surgido un problema, me harias un favor si me ayudas a solucionarlo.

En el momento de ejecutar
http://localhost/miproyecto/public/album

No me sale el listado que pones, en vez de eso me sale el codigo de
application/models/DbTable/Album.php

Y como bien indicabas en el capitulo anterior al crear las 3 clases de la DbTable, no las reconoce como codigo SQL.

Estoy atascado en ese paso, he revisado todos los archivos, pero estan iguales que en la guia y haciendo ligeras modificaciones no consigo nada.

Gracias de antemano.

Angelorum dijo...

"en vez de eso me sale el codigo de
application/models/DbTable/Album.php" Que quieres decir con 'el código? Te muestra en el navegador el código en PHP??

"al crear las 3 clases de la DbTable, no las reconoce como codigo SQL", las clases estan en codigo PHP, no tiendo tu pregunta.. :s

JuZaM dijo...

Lo siento, a ver si soy mas explicito.

Si, me muestra el contenido de
Application/models/DbTable/Album.php
como si fuera un bloque de texto y no el lista que deberia salir.

Y lo de no reconocerlas como codigo, me refiero a que al copiar lo que pones tu en el archivo, el editor que uso (en este caso Netbeans) creo que lo esta interpretando como un bloque de texto normal, no codigo.

Al principio pensaba que faltaria "<?php" al inicio, pero no es el caso.

No se si me he explicado mejor, de todas formas, gracias por responder tan rapido.

Anónimo dijo...

saludos,tengo un inconveniente en:
http://localhost/miproyecto/public/album
alli me muestra todo bien,pero cuando doy opcion "agregar album",
me envia al link:
http://localhost/miproyecto/public/add
me muestra una paguina en blanco,doy click en esta paguina y veo el codigo fuente y no tiene absolutamente nada,que estoy haciendo mal,he seguido al pie de la letra todo el tutorial hasta esa esa parte.

¿alguien le paso algo similar?

gracias por su apoyo

Global IP dijo...

el problema esta en la ruta que le das deberia ir a "http://localhost/miproyecto/public/album/add" primero trata de colocar en la barra de direcciones directamente, si funciona ahi entonces vas bien pero en donde definis la ruta de tu boton "add" esta mal.

Anónimo dijo...

Hola Angel que tal mi problema surge en este capitulo
al poner el link http://localhost/miproyecto/public/album me sale An error occurred Application error la verdad no se cual paso hice mal ahh ahh en la parte donde dice
array(
array( campo1=>'valor 1', campo2=>'valor 2', campo3=> 'valor 3'), //fila 1
array( campo1=>'valor 1', campo2=>'valor 2', campo3=> 'valor 3'), //fila 2
array( campo1=>'valor 1', campo2=>'valor 2', campo3=> 'valor 3'), //fila 3
.....
);


lo que no se en donde agrego exactamente
Agradeceria tu ayuda..

kchorro dijo...

que paso con el problema de albumform
cuando creo el form deberia crearse el archivo llamado AlbumForm.php, peroo se crea el archivo llama Album.php
es por la version???
como se soluciona porfa ....
o ya lo solucionaron y no me entere???

Cristian Reyes dijo...

en que parte creamos con controladores de stos tres ???

parece que falta eso ?
Recuerden Que creamos los controladores:

* AlbumController : encargado de manejar a la tabla album
* ArtistaController : encargado de manejar a la tabla artista
* TemaController : encargado de manejar a la tabla...(corecto, intuitivo lector: a la tabla tema)

Cristian Reyes dijo...

me pasa lo mismo con el form album ...
no me aparece el albumform y tampco el addAction que pasa ?

Ing. Juan Manuel Rivera dijo...

Hermano, excelente tuto, ya lo aplique todo y la manera como lo explicas, barbarooo... mas facil no podia ser.... solo con todo esto me genero una duda, si quiero hacer un formulario pero que no sea todo vertical sino que cada fila tenga los N elementos que quiera ( y que el diseño lo permita) como podria hacerlo.. si tienes alguna idea o codigo seria super.. por que ahi si que me metooo del todo con zend..!!!

Angelorum dijo...

Hola, Ing. Juan Manuel Rivera.
Lo que tu quieres hacer se hace merdiante CSS. Zend no tiene que ver con como se mostrará la página. Solo genera el html del form, y mediante CSS lo puedes acomodar como desees.

Saludos

Ing. Juan Manuel Rivera dijo...

Gracias por responder Angelorum, estuve revisando y se habla de un hack de decoradores para el tema de la presentación del formulario, pero todavia no se acomoda a lo que necesito, es decir un formulario que digamos si estuviera maquetada en una tabla en el primer tr tuviera 5 objetos html, en el segundo tr digamos 6 objetos html y en el tercer tr digamos 4 objetos html y por el ultimo tr el boton, lo digo por que el diseño del formulario lo entregan de esa manera, la presentación del resto del sitio no hay problema, el layout de la aplicacion esta bien.. pero es como se presenta el formulario lo que no he podido, un objeto html debajo de otro no nos sirve por que son muchisimos objetos html en un solo formulario y quieren evitar al maximo el scroll... voy a seguir intentando con css a ver que me sale por lo pronto encontre tambien esta pag super de formularios para complementar tu blog...

http://domeq.net/development/zend-form-styled.html

Anónimo dijo...

buen tuto gracias

Ian Maguiña Mendoza dijo...

Bueno angelorum buen tuto este , he estado siguiendo hasta aqui, en en mi caso como el de varios ME SALE Album.php en la carpeta form, quiza sea la version , ya q tengo al ultima, pero un modo de corregir esto en lo demas, x q intente agregarle el form, y luego quitarle a todos el form de album, asi que solo sale un pagina en blanco... que hago?

Anónimo dijo...

El método de rellenar los select option cuando los monto en un hosting me generan error, que puedo hacer...

Aaron dijo...

Hola Angel:
Hasta el paso 5 me salió todo bien, pero en el paso 6, dice:
"Recuerden Que creamos los controladores:
AlbumController : encargado de manejar a la tabla album
ArtistaController : encargado de manejar a la tabla artista
TemaController : encargado de manejar a la tabla...(corecto, intuitivo lector: a la tabla tema)"


Pero yo no ví esos archivos en la carpeta /application/controllers/ y cuando los hice con "alt + z", a través del comando controller, en el paso 7 pedía como index add.phtml, lo cual no funcionó.
¿Podrìas decirme qué me faltó?
Saludos

ian maguiña dijo...

bueno Aaron, para eso se supone que ya habia creado albumcontroller, asi que se hace lo mismo para los demas, y de necesitaruna accion se la crea , como el primer ejemplo, y sale, pero el otro problema es el q me falla, al crear los formularios, parece que no se referencian bien, sigo los pasos , e incluso añado Albumform a la hora de crear, pero aun asi no se referencia, sale en blanco

Anónimo dijo...

Buenas, he seguido todos los pasos, pero cuando llego aqui me da un problema con la variable $d, me dice que undefined variable d. ¿Me podeis dar alguna pista de por qué pasa esto?. Gracias