17 de noviembre de 2007

La nueva forma de hacer busquedas

Hoy tratando de ayudar a un usuario en el IRC, termine descubriendo existe una nueva forma de utilizar las funciones find, findAll y findCount. Resulta que buscando mas flexibilidad para un futuro (palabras del mismo gwoo :) ) estas llamadas han sido cambiadas y ahora todas se hacen con la funcion find, donde se aclara cual de los 3 tipos es:


"count"

Busca el numero de filas que cumplen la busqueda especificada. Ejemplo de uso:

Post->find('count', array('conditions' => array('Post.comments_count' => '<>));

"first"

Busca la primera fila que cumple con la busqueda especificada. Ejemplo de uso:

Post->find('first', array('conditions' => array('Post.comments_count' => '<>), 'order' => 'Post.date ASC'));

"all"

Busca todas las filas que cumplen con la busqueda especifica. Ejemplo de uso:

Post->find('all', array('limit' => 10, 'order' => 'Post.date ASC'));


Y eso es todo. No es muy dificil de implementar, pero mas vale empezar a hacerlo cuanto antes, porque prontamente findAll y findCount van a ser metodos deprecados, y son algunos de los metodos que mas se usan, por lo tanto los mas dificiles de cambiar.

Saludos!

10 de noviembre de 2007

El Form Helper


Hoy voy a escribir acerca del Form Helper, ese gran ayudante que nos brinda la version 1.2 de CakePHP para crear formularios de una forma muy simple.

Cuando comence a tratar de aprender para poder crear mi primer formulario, note que en el manual en construccion de Cake 1.2, la parte que explicaba el Form Helper solo tenia el siguiente texto: asdf. Muy interesante, y quizas haya algun mensaje en código en esas cuatro letras, pero lo que yo necesitaba era un poco mas que eso. Por esa misma razon me dirigi al segun mi profesor de Programacion Concurrente, "semidios" Google. Y ahi encontre este excelente recurso, donde se muestran ejemplos de como codificar los elementos tipicos de un formulario. Siguiente esta guia, construi mi primer formulario muy rapidamente, pero luego de terminarlo, vi algunas inconsistencias en el codigo, basicamente las dudas eran dos...

  1. ¿Por que algunos elementos (inputs) crear un label y un div contenedor, y otros (selects, textareas) no lo hacen, teniendo que crear el label y el div (en caso de necesitarlo) a mano?
  2. ¿Como hago para que mis inputs de texto no tengan label, o el div contenedor?

Antes de poder contestar estas dos preguntas, vamos a ver como crear las etiquetas que abren y cierran los formularios.

Create y End

  • FormHelper::create
( $ model = null,


$ options = array()

)


Este metodo crear la etiqueta form del modelo definido junto a sus parametros, dados en el array options. Los campos que tiene el array options son:

  • "method" -> "post" o "get" (metodo de envio del formulario)
  • "url" -> array() (arreglo que ayuda a formar el URL de destino del formulario)
Dentro del array "url", hay que definir un "controller" y un "action", para darle un destino al formulario.
Sin entrar en tantas compliciones, se puede crear este elemento haciendo lo siguiente:

$form->create("nombreDelModelo");

Por defecto, utilizara el metodo post y la URL sera la misma desde la cual se llamo al formulario.

  • FormHelper::end
( $options = null )

Este otro método crear la etiqueta de cierre del formulario, y si se le pasa un nombre como parametro, se crea automaticamente el boton de enviar, con el texto pasado.

Asi, si ponemos:

$form->end("Enviar");

estaremos creando un elemento input tipo submit con el texto "Enviar", y luego el cierre de la etiqueta form.

La forma correcta

Habiendo visto lo basico sobre como crear un formulario, voy a contar que leyendo en el Grupo Oficial de Google, vi un post que hablaba de que en Cake 1.2 todos los elementos, cualesquiera sean, se deberian crear con el comando $form->input, asignadole como parametro el tipo de elemento a construir. En ese mismo post decia que las otras formas de crear elementos (por ejemplo, $form->select) prontamente serian consideradas como formas deprecadas. No muy seguro de lo que decia esta persona, fui directo al IRC de Google y pregunte cual era la forma recomendada de crear elementos de formulario. La respuesta fue unánime:

$form->input

Bueno, ahora ya habiendo dado la intro de que se debe hacer, ahora vamos a ver como hacerlo. En la API de Cake, se define asi al metodo input:

  • FormHelper::input
( $ fieldName,


$ options = array()

)

donde $fieldName es el parametro que define el nombre del campo, y $options es el array "mágico" que permite crear todo tipo de elementos.

Ahora, dentro de ese array $options tenemos varias opciones, voy a listar algunas:

  • "type" -> "tipoDeElemento"
  • "label" -> "textoEtiqueta"
  • "id" -> "idDelElemento"
  • "class" -> "claseDelElemento"
  • "value" -> "valorPorDefecto"
  • "options" -> "opcionesDeSelect" (solo para elementos de tipo select)
  • "empty" -> true or false (solo para elementos de tipo select, muestra opcion por defecto vacia)
  • "div" -> "claseDelDivContenedor"

Hay algunos "trucos" que se pueden utilizar para controlar mejor las cosas:

  • Si se le pasa el valor false a "label", se quita la etiqueta del elemento.
  • Si se le pasa el valor false a "div", se quita el div contenedor.
  • En caso de ser un elemento checkbox, "value" define con que valor la casilla estara marcada.
¿No entendiste nada? No problem, vamos al ejemplo...

Ejemplo práctico


Ejemplo 1: Quiero crear un simple formulario para que mi novia me deje saludos todas las noches...


Tu novia sera asi! La mia es mas parecida a esta...



Emmm, bueno, volviendo a como crear el formulario...

a) Apertura de formulario:

echo $form->create('Mensajes');

Este elemento ya lo explicamos antes.

b) Elemento input donde se ingresará el nombre de la persona que deja el mensaje:

echo $form->input('Mensajes.nombre', array('type' => 'text', 'label'=>'Nombre:'));

Como explicamos antes, esto creara un input con un label "Nombre:".

c) Elemento select donde se elegira si mandar besos o abrazos:

echo $form->input('Mensajes.gesto', array('type' => 'select', 'label'=>'Tipo de gesto:', 'options'=>$gestosList, 'empty'=>true));

Esto creara un select con las opciones pasadas en el array $gestosList, que tendrá por defecto la opcion vacia y la etiqueta "Tipo de gestos:".

d) Elemento textarea donde se dejará el mensaje:

echo $form->input('Mensajes.texto', array('type'=>'textarea', 'label'=>'Texto de mensaje:'));

Esto creara un textarea con una etiqueta "Texto de mensaje:".

e) Creación de elemento submit y cierre de formulario:

echo $form->end('Enviar');

También explicado anteriormente.

Conclusión y más magia


Y esto es todo. Con tan pocas lineas de codigo, hemos creado un formulario completo. Imaginen lo poco que tendran que codificar para crear formularios mas complejos. Y si todavia no se convencieron, les tiro otra informacion que descubri hace poco:

Si declaramos en nuestra base de datos un campo como text, cuando generamos el input en la vista no hace falta poner el tipo de input, Cake solo lo reconoce como 'textarea'.
Y si declaramos en nuestra base de datos un campo como tinyint(1), o bool, cuando generamos el input en la vista no hace falta poner el tipo de input, Cake solo lo reconoce como 'checkbox'.

Y como puse en el grupo de Google, si esto no es magia, que lo es!

Para seguir investigando

Por supuesto que esto ha sido solo una introduccion al uso del Form Helper, existen muchas otras cosas que se pueden hacer. Una cosa basica que falta en este tutorial, y es muy importante, es la validacion de los campos. A pesar de no escribir sobre esto porque todavia lo estoy investigando en profundidad, les dejo un vinculo a un muy buen artículo de Mariano Iglesias
donde habla de validaciones multiples en Cake 1.2. Además, nunca esta de más mirar la API, para entender en profundidas algunas cosas.

Y eso ha sido todo por hoy. Espero que les pueda servir en sus comienzos con los forms en CakePHP. Saludos!

30 de octubre de 2007

Demasiado bien para ser el primer dia

Bueno, despues de toda la chachara de ayer, hoy me dispuse a poner las manos en el fuego y empezar a hacer algo... Nada de tutoriales de blogs ni esas pavadas, no hay tiempo para eso, ¡los clientes ya se estan quejando por las demoras!

La aplicacion que tengo que crear tiene que encargarse de manejar las propiedades de una inmobiliaria, ni mas ni menos. Tengo que poder ponerlas en diferentes estados (En venta, Para alquiler, etc.), asignarle precios, y otros chiches mas.

Vamos a ver todo lo que he podido avanzar hoy...

1) Comenze por utilizar Bake para generar los modelos y los controladores. Aunque es una herramienta muy interesante, he podido comprobar, que como lei en algun escrito de Mariano Iglesias, lo mejor es poder codificar uno. Bake genera el codigo, pero nunca es como lo quiere uno, porque la idea es que le sirva a todos, cosa que es imposible. Asi todo, de guia para aprender algunas cosas anduvo perfecto.

2) Bueno, como mi "Ver todas las propiedades" estaba mas vacio que la marcha de Schiaretti cuando gano las elecciones (si hay algun cordobes, me va a entender), procedi directamente a crear la vista para agregar una propiedad. Quien diria que me llevaria toda la tarde!!!!

3) Primer escollo. No tengo ni idea como hacer funcionar el generateList que me puso Bake. Teoricamente, generateList se encarga de construirte un array con todos los datos de otro modelo, para que simplemente lo pongas en una lista de selects y se acabe el problema. Me costo horrores, pero al fin pude ponerlo en funcionamiento y hacer que mi vista lo reconozca. Basicamente, esta es la sintaxis de generateList:

generateList(string $condiciones, string $orden, int $limite, string $keyPath, string $valuePath)

Se puede llamar directamente como generateList(), pero te pierdes la posibilidad de ordenar los datos o de ponerles alguna condicion. Ah! $keyPath es el valor que se pasara a través del formulario, y $valuePath el que se mostrara en pantalla.
Despues de mucho renegar, y de no encontrar casi documentacion sobre el helper Form (en el manual no hay nada, que hago!!!!) recurri a la API y a este increible tesoro perdido y aprendi que del lado de la vista, es tan simple como poner lo siguiente:

echo $form->select('Modelo.campo,$arrayDeDatos);

siendo el primer parametro el campo del modelo a tratar, y el segundo los datos a poner en el select, que ya lo habia conseguido "magicamente" con generateList. Una verdadera pavada.

4) Ahora ya tome coraje y me agrande, voy a terminar el formulario completo me dije. Ayudado de nuevo por los documentos que liste arriba, me di cuenta que crear un input con su respectivo label es tan facil:

echo $form->input('Modelo.campo');

Algo que no pude conseguir es como hacer para que no me salga el titulo Campo (referido al valor campo que puse en el helper). Supongo que sera una de los datos que le puedo enviar al helper como segundo parametro para la creacion del input...

ACTUALIZACIÓN:

echo $form->input('Modelo.campo', array('label' => 'Mi titulo'));

5) Otra cosa a tener en cuenta es que los demas elementos que no son input no generan un label automatico, por lo tanto hay que hacerlo. De nuevo, generar un label parece un chiste:

echo $form->label('Modelo.campo','Texto en el Label');

ACTUALIZACIÓN:

Segun lo que he averiguado, lo ideal es generar todos los elementos del formulario con input, ya que en el segundo parametro, que es un array, definimos el tipo de elemento:

echo $form->input('Modelo.campo', array('type' => 'select'));

Asi, homogeneizamos todos los elementos, y no hay que utilizar mas el elemento label. Un verdadero avance.

6) Una vez terminado el formulario, me dispuse a relajarme y como sobrando el partido, aprete el boton enviar para ver que pasaba. Parecia que estaba todo mas que bien... Pero, pero, estas cosas nunca salen de una. Cuando revise mi base de datos, vi que en los lugares donde tenia que ir un ID Foraneo me habia ingresado 0 (cero). Indignado, empece a golpear la pc, buscando la forma de encontar a Larry Masters y ahorcarlo con mi mouse (mentira Larry, esta todo bien con vos) Ahi fue cuando encontre la salvacion en el grupo de Google, donde encontre un post de el usuario Pablo Ramirez (te nombro, hermano, porque sin querer me salvaste la tarde!) preguntando sobre otra cosa, mostro su controlador y lo que hacia el era realizar el generateList antes de cualquier pregunta sobre si habia datos o no. La verdad, esta parte no la entendi bien, porque se supone que el generateList es solo para la vista, pero despues a la hora de guardar los datos, en el array data deberia venir ese valor tambien (tarea para averiguar). Bueno, la cuestion es que hice este cambio, y FUNCIONO!

ACTUALIZACION:

El problema es que tenia el DEBUG en 0, por lo tanto no actualizaba la aplicacion con respecto a la base de datos. Si estan desarrollando, no se olviden de poner DEGUG en un numero mayor que 0! Y el generateList va donde tiene que ir, no al principio.

7) Me puse a saltar como si hubiese ganado la medalla de oro de Judo, no podia creer lo facil que era hacer esto, una vez que se averigua como hacerlo. Ya no mas codigo HTML insoportable para generar un formulario, esto si que es magia!


Y asi se termino mi primer round con CakePHP, creo que para ser el primer dia, mucho he podido hacer. Me faltan muchas cosas, como aprender a subir imagenes, o manejar relaciones de muchos a muchos, pero vamos por partes, como dijo mi amigo, Jack el Destripador...


Saludos a todos! Cualquier consulta me preguntan a traves de los comentarios del blog, estoy siempre dispuesto a ayudar a gente que esta en la misma que yo!

29 de octubre de 2007

¿Como funciona el modelo MVC en CakePHP?

Voy a trasladar mi primer aprendizaje a una documento que sea facil de entender para todos aquellos que recien empiezan con CakePHP, y que no entiendan el ingles del manual.
La mayoria del texto y la imagen principal salen de esta parte del manual 1.2 de CakePHP.





En el gráfico mostrado arriba, se explica claramente como funciona CakePHP. Para los que no entienden nada de esto (a mi tambien me costo entenderlo), vamos a ver un ejemplo claro.

Antes, les presento a los tres participantes del proceso:

a) El Controlador:


b) El Modelo:


c) La Vista:


Ahora vamos al caso concreto:

Mi amigo Roger esta viendo que su tenis ha bajado de nivel, por lo que quiere comprarse una raqueta nueva. Para eso, ha decidido entrar al sitio www.teniscake.com, sitio que vende raquetas por Internet, obviamente utilizando Cake como sistema. A continuacion, una foto de mi amigo preocupado:


Los pasos que seguiran el Controlador, la Vista y en Modelo para lograr que Roger tenga su nueva raqueta son los siguientes:

Paso 1: Roger encuentra la raqueta que le gusta, y clickea sobre el boton que dice "Comprar". Este boton apunta a la direccion http://www.teniscake.com/racquet/buy...


Paso 2: El despachador analiza la URL solicitada (racquet/buy) y pasa el pedido al controlador adecuado...

Paso 3: El controlador realiza la lógica especifica de la aplicación. Por ejemplo, chequea si Roger ha iniciado una sesión....



Paso 4: El controlador también utiliza a los modelos para acceder a los datos de la aplicacion. Lo mas común es que los modelos representen bases de datos, pero también pueden representar feeds RSS, o archivos en sistemas. En este ejemplo, el controlador utiliza al modelo para obtener las ultimas compras que ha hecho Roger en el sitio web, dato guardado en la base de datos...

Paso 5: Una vez que el controlador ha realizado todos los procesos necesarios sobre los datos, envia los mismos hacia la vista. Esta toma la informacion y la prepara para presentarsela al usuario. Las vistas en CakePHP en la mayoria de los casos son archivos HTML, pero tambien pueden ser documentos PDF, XML, etc...

Paso 6: Una vez que la vista ha utilizado los datos del controlador para armar una presentacion adecuada, el contenido de la vista es retornado al navegador de Roger....



Y hasta aqui llegamos. A simples rasgos, eso es todo. Ahora puedes volver al primer gráfico, y entenderás tecnicamente como funciona esto que he explicado con gráficos no tan técnicos...
Para la próxima, prometo preparar algo que explique mas a fondo como interactuan otros elementos, como componentes, layouts, helpers y comportamientos. Espero que les haya gustado este primer post, y si no les gusto, miren quien se quedo muy contento con su compra...



Saludos, hasta la próxima!

¡Bienvenidos!

Bueno, he comenzado a utilizar CakePHP para el inicio de una nueva empresa que he creado con varios compañeros de la universidad, en la cual nos dedicaremos a desarrollar aplicaciones web. La idea de este blog es ir llevando algo asi como un "diario" de mi aprendizaje de este Framework, y a la vez tratar de centralizar un poco la informacion sobre Cake, que esta bastante distribuida entre los diferentes blogs.
Espero que alguien pueda utilizar este blog como una herramienta, y sino, que por lo menos se diviertan leyendo lo que voy a renegar para aprender Cake!

Saludos.