28 May, 2008

Componentes y helpers en cakephp

Tanto los componentes como los helpers están diseñados para extender las funcionalidades que el propio núcleo cake nos ofrece. La diferencia? bien sencilla. Mientras los componentes añaden lógica de negocio a nuestro proyecto, los helpers añaden lógica de presentación.

Componentes:
Existen multitud de componentes que podemos descargar y utilizar: Sending Email With PHPMailer, Integrate CakePHP with Kcaptcha, Google Geocoder, LastRSS CakePHP Component, Pagination Component, etc. Y otros que ya vienen incluidos con el núcleo cake: AuthComponent (Gestión y autenticación de usuarios), RequestHandler (Obtener información de las peticiones http), CookieComponent (Gestor de cookies), AclComponent (Access Control List), EmailComponent (Envio de mails), SecurityComponent (Incrementar la seguridad de tu aplicación), SessionComponent (Gestor de session). Y podemos crear nuestros propios componentes para cumplir diferentes requisitos:

Crear un nuevo componente para cakephp es muy sencillo. Basta con crear un fichero en app/controllers/components/fichero.php con una clase nombrada FicheroComponent que tendrá una variable $controller y un método:

  1. function startup( &$controller ) {
  2.      $this->controller = &$controller;
  3. }

Luego para hacer uso de un componente en uno de nuestros controladores simplemente lo añadimos al array

  1. var $components = array('NuestroComponente','OtroComponente');

y ya lo tendremos disponible como

  1. $this->NuestroComponente

Aqui tenemos un buen ejemplo de uso del json component.

Helpers:
Respecto a los helpers también los tenemos incluidos en el núcleo cake: html (ayuda a contruir tags html), form (ayuda a contruir formularios), number (ayuda a formatear numeros), timer (ayuda a formatear fechas), xml (simplifica la construcción de documentos xml), ajax (uso de ajax mediante prototype). Su uso es tan sencillo como:

  1. <div id="header">
  2.    <h1><?php echo $html->link(__('Portada', true), $html->base.'/portada'); ?></h1>
  3. </div>
  4. <!--Hacemos uso del helper $html tanto para crear un link como para obtener la dirección base de nuestra web.-->

Al igual que los componentes también podemos desarrollar nuestros propios helpers, aqui tenemos un buen ejemplo donde se crea un helper para autocompletar un input text mediante ajax .

20 May, 2008

Netbeans IDE for PHP

Hoy, después de pelearme con el eclipse un rato (tampoco fue como para una separación seria, solo unos días hasta que se me pase) me he dado una vuelta por netbeans y me entero de que la nueva versión 6.1 ya trae el plugin integrado para soportar php. Es mas, nos podemos descargar una versión de este ide solo con el plugin para php por la módica cantidad de 16MB.

La he instalado y las primeras impresiones son buenas pero...

El editor está bien, el autocompletado de funciones funciona!, la refactorización se reduce a renombrado de ficheros y ni siquiera lo hace bien, excelente integración con svn (igual que la versión javera), en principio parece que la integración con xdebug es bastante buena pero solo lo he usado con proyectos demo.

Pero... el mismo pero de siempre, sigue siendo muy pesado, consume una grandísima cantidad de memoria. Será momento de plantearme un cambio de equipo? mmm, no se no se, creo que aguantaremos un poquillo mas.

http://wiki.netbeans.org/PHP

6 May, 2008

Extendiendo el controlador de cakephp

Este fin de semana el cake me hizo otra de las suyas. Aunque pensándolo bien siempre podemos disculparlo por trabajar en beta.

El caso es que yo necesitaba mi propio AppController para incluir una serie de acciones comunes a todas las peticiones, y que se ejecutarían en el beforeRender() (justo antes de renderizar la vista y después de ejecutar toda la lógica de los controladores).

Esto en cake 1.1 se hacía copiando el app_controller.php a la raíz de /app, sobreescribíamos los métodos necesarios y listo. Y claro antes de leer nada fue lo primero que hice en cake 1.2. Pero no tuve suerte. Resulta que no encontraba los métodos que estaba declarando. Cake no estaba cargando mi app_controller sino el por defecto en /cake/libs/controller.

De primeras acudí a google (no conozco otra forma mas rápida de encontrar solución a este tipo de problemas) y tras comprobar que era al único que le sucedía tal cosa me fuí directo a http://manual.cakephp.org/complete/3/the-manual y la sorpresa cuando me encuentro con estas líneas:

Both controllers, helpers and models have a parent class you can use to define application-wide changes. AppController (located at /app/app_controller.php), AppHelper (located at /app/app_helper.php) and AppModel (located at /app/app_model.php) are great places to put methods you want to share between all controllers, helpers or models.

Lo estaba haciendo bien!, tras navegar por el registro de bugs llegué a esta conversación en el grupo de google , que seria de mi sin la comunidad!, resulta que para extender el app_controller en cakephp 1.2 debes situarlo en /app/controllers/app_controller.php y no en /app/app_controllers.php.

No me quejo, es el riesgo que se corre por trabajar en betas, además, quitando estos dos detalles cake y yo nos llevamos bastante bien. Aunque eso si, prefiero no tener documentación a tener documentación mentirosa.

23 April, 2008

Sistemas de plantillas para PHP o PHP como sistema de plantillas

Cuantas veces este ha sido motivo de debate. ¿Merece la pena utilizar un sistema de plantillas estilo smarty para php?. ¿Acaso no es php un lenguaje de script suficientemente limpio y potente como para poder valerse por si solo como motor de plantillas?. ¿Que diferencia encontráis entre estas 2 lineas?:

  1. <div>{nombre}</div>
  2. <div><?=$nombre?></div>

¿De verdad creéis que la primera es mas sencilla?.

Como ya habréis intuido yo nunca estuve de acuerdo en utilizar un lenguaje añadido de plantillas, básicamente porque no me aporta nada. Por supuesto que estoy de acuerdo en separar las capas de presentación y lógica pero esto lo podemos hacer tanto con php como no hacerlo con cualquier motor de plantillas. Todo depende de como lo utilicemos.

Pero yo prefiero esto:

  1. //posts.php
  2. $posts = getPosts();
  3. include("posts.html");

  1. //posts.html
  2. <?foreach( $posts as $post);?>
  3.      <h1><?=$post->getTitle()?></h1>
  4. <?endforeach;?>
  5. </div>

y no esto:

  1. //posts.php
  2. require("smarty/Smarty.class.php");
  3. $template = new Smarty;
  4.  
  5. $template->template_dir=".";
  6. $template->assign("posts",getPosts);
  7. $template->display(posts.html);

  1. //posts.html
  2. {foreach from=$posts item=post}
  3.      <h1>{person.getTitle}</h1>
  4. {/foreach}
  5. </div>

Por cierto tanto cakephp como zend framework han adoptado la primera opción de forma nativa, lo que no quiere decir que no existan plugins para poder utilizar algún lenguaje propio de plantillas.

5 March, 2008

Cuidadín con las stables, cake

Logo CakePHPEsta noche he soñado con el bug que soluciona este changeset (https://trac.cakephp.org/changeset/3983).

Resulta que hasta ayer había estado probando la beta de cakephp y todo era una maravilla. Ayer mismo me bajé la stable para comenzar a trabajar en el proyecto final y dejarme de pruebas, la primera en la frente. Nada mas crear mi controlador y mi modelo para el scaffolding aparece el primer error, algo como:

Notice: Trying to get property of non-object in /home/javi/proyectos/php/cakephp/cake/libs/controller/controller.php on line 666

Me aseguré de que había bajado la estable, de las compatibilidades con mi sistema, no encontré mucha información por internet, así que nada me puse a bucear, le seguí el rastro, desde el controller.php pasé al model_php5.php luego al inflector.php al object.php ¿y donde terminé? pues en el class_registry.php.

Resulta que class_registry.php es la clase contenedora de los objectos que representan nuestro modelo. Estos se almacenan en esta clase en un array, ya sabeis clave=>valor. Hasta aquí todo bien. Pero en el controller.php en la linea 666 parece que el objecto que se estaba intentando cargar no existía, estaba vacío. Bien bien ya casi estaba. Solo nos quedaba comprobar como almacenábamos el objecto y como lo recuperábamos. Pero ya era tarde, mi cabeza ya no pensaba, así que decidí dejarlo para hoy, ERROR, mis sueños con el cake casi no me dejan dormir.

Esta mañana con la cabeza fresca lo he encontrado. Resulta que el objecto se estaba almacenando con una clave y se estaba recogiendo con otra diferente. Esto solo pasaba cuando tu modelo tenia varias palabras (ej: BiciCarreras). ¿Demasiado obvio verdad?, si seguro que no era esto, algo estaría haciendo yo mal. Pues NO.

El cake cuando recupera un objecto pasa la clave del mismo por este filtro $key = Inflector::underscore($key); que convierte la clave a minúsculas e incluye un "_" entre palabra y palabra, en nuestro caso nos quedaría (bici_carreras). Pues bien cuando lo almacenaba no pasaba la clave por este filtro y lo único que hacía era convertir la cadena a minúsculas $key = strtolower($key);, con lo que nos almacenaba el objecto con la clave (bicicarreras).

El bug está corregido para la beta 1.2 lo podéis comprobar en este changeset https://trac.cakephp.org/changeset/3983 pero no para la stable 1.1. ¿Curioso? no, tocapelotas.

4 March, 2008

CakePHP + Scaffolding

Logo CakePHPHace aproximadamente un mes que me había animado a conocer un poco mas a fondo cakephp, un framework MVC en y para php. Pero como tantas otras veces me había quedado a medias presionado por la carga de trabajo por aquel entonces. Ahora ha surgido de nuevo la oportunidad y parece que será la definitiva.

Una de las características mas cool (y lo dicen ellos en su manual "Cake's Scaffolding is Pretty Cool"), es lo que ellos llaman Scaffolding, un sistema mediante el cual tu simplemente defines un controlador que trabaja sobre un modelo y cake te crea toda la interfaz de gestión (crear, editar, eliminar elementos) de esa tabla.

Si utilizas una nomenclatura de tablas y campos clave estándar para cake, no necesitaras ni tan siquiera definir un modelo, simplemente será suficiente con crear por ejemplo este código:

  1. <?php
  2. class BiciController extends AppController
  3. {
  4.   var $scaffold;
  5.   //var $uses = array('Auto'); // Si quisieras utilizar un modelo y este tuviera un nombre diferente de Bici
  6. }
  7. ?>

en un fichero bicis_controller.php en la raiz de app/controllers.

Si utilizas tu propia nomenclatura o heredas un diseño de BD ya creado, tienes diferentes variables para configurarlo, en este caso necesitarás crear el BicisController anterior y además el modelo Bici:

  1. <?php
  2. class Bici extends AppModel
  3. {
  4.   var $name         = "Bici";
  5.   var $useTable  = "bicis"; // Aquí podríamos indicar que tabla está utilizando este modelo
  6.   var $primaryKey        = "idbici"; // Si la clave principal de nuestra tabla car es diferente de id
  7. ?>

y lo almacenamos como bici.php en app/models.

Seguro que estáis pensando que para este caso tan sencillo claro que está muy bien, pero, ¿y cuando tenemos un modelo de datos mas complejo con diferentes tipos de relaciones?. Pues también tenemos opciones. Cake soporta 4 tipos de relaciones entre tablas: hasOne, hasMany, belongsTo y hasAndBelongsToMany. Como ejemplo imaginemos que la Bici definida en el modelo anterior es de un solo color. Esta relación la definimos así en la clase modelo Bici:

  1. <?php
  2. class Bici extends AppModel
  3. {
  4.   var $name         = "Bici";
  5.  
  6.   var $belongsTo = array('Color' =&gt;
  7.     array('className'    =&gt; 'Color',
  8.     'conditions'   => '',
  9.     'order'        => '',
  10.     'foreignKey'   => 'color_id'
  11.   )
  12. );
  13. ?>

y debemos definir el modelo del Color:

  1. <?php
  2. class Color extends AppModel
  3. {
  4.   var $name         = "norma";
  5.   var $displayField = "titulo"; // El campo que se mostrará en el select que nos permitirá relacionar el car con el color
  6. }
  7. ?>

Para terminar decir que cakephp es mucho mas que scaffolding. Esta es una forma de crear una interfaz sencilla y de una forma muy rápida, pero cake nos permite crear nuestras propias interfaces, nuestra propia lógica de negocio, validaciones, etc.
Para mas información ya sabéis www.cakephp.org

27 February, 2008

Zend Studio for Eclipse

Logo Zend StudioHoy he bajado la versión de evaluación del Zend Studio for Eclipse, una versión del conocido Zend Studio pero basada en eclipse.

Hasta ahora vengo utilizando el eclipse con su famoso plugin phpeclipse pero se echan muchas cosas de menos, como en todos los editores php. Que si los enlaces directos a ciertas partes del código no siempre funcionan, que si no tenemos el mas básico de los debuguers, que si alguna herramienta básica de refactorización, en fin que yo simplemente lo utilizo para lo que es, un editor más que nos colorea el código y como mucho añadimos el plugin para trabajar con subversión y actualizamos el proyecto desde el propio eclipse.

Pero bueno las primeras impresiones de este editor son buenas, mucho mas ligero que el eclipse, un editor mas ágil, una herramienta de refactorización!!, phpdoc integrado, integración con el framework de Zend, phpunit integrado, un debuguer!!.

Pero he dejado para el final la peor parte, ese motivo por el que no lo utilizaré, su licencia y su precio: 299$ 1 año y 617$ 3 años.

Sigo pensando que uno de los puntos más débiles de php es un buen IDE por lo que de momento seguiré utilizando phpeclipse o cualquier otro editor que de color a mi código. El día que se libere algún otro que merezca la pena cambiaré, ¿alguien dijo vim?.

Powered by WordPress
Bajo licencia Creative Commons
Contacto sanroman.javier at gmail.com