April 28th, 2013 Category: Curso Testing XP
2 Comments »

Volviendo un poco a generar videos, la idea es mostrar un poco como crear aplicaciones usando TDD en PHP.

Para esto vamos usar PHPUnit, y ningun framework especifico.

En el video vamos a ver el siguiente codigo

tests/CalculatorTest.php


require_once 'src/Calculator.php';

class CalculatorTest extends \PHPUnit_Framework_TestCase
{

    /**
     * @dataProvider diffProvider
     */
    public function test_Give_2_Real_Numbers_Should_Return_The_Difference_Between_Both($a, $b, $expectedResult)
    {

        $calculator = new Calculator();

        $result = $calculator->diff($a, $b);

        $this->assertEquals($expectedResult, $result);

    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function test_Given_A_String_Should_Throw_An_Exception()
    {
        $calculator = new Calculator();

        $calculator->diff(5, 'tres');
    }

    public function diffProvider()
    {
        return [
            [5, 3, 2],
            [10, 5, 5],
            [-5, 5, -10],
            [5, 4, 1],
        ];
    }
}

src/Calculator.php



class Calculator
{

    public function diff($numb1, $numb2)
    {
        if (is_string($numb1) || is_string($numb2)) {
            throw new \InvalidArgumentException('Is not a number');
        }
        return $numb1 - $numb2;
    }
}
Seguir leyendo

August 19th, 2012 Category: Curso Zend Framework
28 Comments »

Despues de mucho tiempo de hacernos esperar la verison 2 de Zend Framework esta por dar a luz, y si todavia no hay una version estable pero ya estamos por la Release candidate 4 (RC4).

Muchos cambios surgieron con esta nueva version, no solo estamos hablando de soportar PHP 5.3/5.4 y todos sus nuevos features, hay muchos cambios respecto al framework en general.

Se cambio toda la estructura, se hizo practicamente de cero. Tenemos otra estructura de carpetas, tenemos “Modulos” de verdad, tenemos Dependency Injection (DI) e Event Manager. Esta version va a llevar a PHP a otro nivel.

No se van a escuchar mas comentarios del tipo, ZF es lento, es pesado. Zend Framework con la introduccion de DI no solo depreco todos sus singleton dando vuelta por todas las librerias, sino que nos hizo un framework mas transparente.

Durante un tiempo deje de hacer videos de ZF y tampoco doy clases en Educacion It, esto se daba porque estaba esperando esta version. Los cambios son geniales, y confio en que ZF2 y Symfony 2 van a llevar a PHP al lugar que merece.

En este primer capitulo vamos a crear el bootstrap de nuestra aplicacion inicial. Como aclaro en el video, voy a tratar de hacer los videos mas cortos explicando conceptos simples, pero tratando, si mis otras obligaciones me lo permiten, subir videos mas seguidos.

Aca les dejo el primer capitulo.

Configuracion de un virtual host.
<VirtualHost *:80>
ServerName zf2.local
ServerAlias www.zf2.local
DocumentRoot /Users/pablo/Workspace/ZendSkeletonApplication/public
<Directory /Users/pablo/Workspace/ZendSkeletonApplication/public>
Options FollowSymlinks
AllowOverride All
Order allow,deny
Allow from all

</Directory>

SetEnv APPLICATION_ENV development

</VirtualHost>

 

 

Links
Codigo fuente de Zend Framework 2

Zend Skeleton Application

Seguir leyendo

August 16th, 2012 Category: Ambiente de Desarrollo linux Programacion
14 Comments »

Entiendase deploy como el proceso de subir nuestro codigo/db/cambios en general a determinado ambiente. En este caso vamos a hablar del deploy en produccion.

Hoy estaba escuchando que el comando rsync es terriblemente avanzado para el uso comun y que seria una buena alternativa usar FTP, o Dropbox (WTF?).

Voy a tratar de desmitificar esto.

Primero quiero hacer una aclaracion, es importante entender que si bien es correcto que usemos control de versiones para desarrollar no es correcto usar el control de versiones en el servidor.

En el control de versiones que mas le guste o les toque trabajar, ya sea git, svn, mercurial, etc. nosotros necesitamos guardar todo lo que realmente requiera de un versionado, esto tiene que entenderse como codigo no binario. Cuando hablamos de una imagen por ejemplo, la imagen puede sufrir variaciones porque un desarrollador decidio cambiarle el tamaño a las imagenes en portadas que tenemos en el slider, estas imagenes pueden ir variando constantemente pero no tenemos que analizar su codigo para ver como va variando en las dferentes versiones, no necesitamos hacer un code review tampoco, no tiene ningun sentido guardar en un versionado las imagenes, ademas tenemos el costo extra que las imagenes (generalmente), ocupan mucho espacio y a ese espacio, ese espacio se le tiene que sumar el archivo que usa el control de versiones para chequear si sufrio cambios y que cambios fueron. Lo cual estamos duplicando espacio sobre algo que no nos interesa llevar un versionado. Lo mismo pasa con los PDF, zip, .doc, etc.

Entonces solo vamos a versionar codigo, ese codigo puede contener por ejemplo, nuestros tests, archivos para hacer pruebas locales, archivos de ambiente, etc. No hace falta que el codigo de los tests este en produccion, nosotros no vamos a correr test unitario en produccion, ya se supone que fue probado en los distintos ambientes, por lo cual su espacio en el servidor es inecesario, lo mismo con los archivos de ambiente, para que necesito la configuracion de mi ambiente de desarrollo si estoy en produccion?. Para que necesito ocupar espacio en disco de los archivos que necesita git para validar si hay cambios, si no voy a hacer commit desde el server?, o no deberia.

Que pasa si mis imagenes las tengo que subir a un servidor de CDN y no al servidor donde esta el codigo? de que me sirve que el server del codigo tambien contenga las imagenes?

Todo muy lindo pero esto es engorroso hacerlo a mano, como hago todo el deploy en una linea de bash?

Muy simple con rsync.

Que hace este comando magico? Basicamente lee un directorio, y lo compara con otro directorio y establece que archivos se modificaron y cuales tiene que pisar. Una vez que los identifico los actualiza.

Su funcionalidad en contra de la creencia “popular” es muy simple.

Supongamos que localmente tenemos dos directorios con copias exactas de su conteinido, pero en uno de ellos decido editar un archivo o agregar uno nuevo. Pero quiero sincronizarlos.

Entonces voy a ejecutar lo siguiente

 $ rsync -avz /home/pablo/directorioModificado/ /home/pablo/directorioSinModificar/

Simplemente escribimos el comando, tres simples parametros (letras), y el directorio modificado y el directorio a modificar.

Yo use rsync -avz, estas 3 letras significan diferentes opciones que yo quiero de rsync.

“a”, esta letra sirve para que rsync sincronice todo el arbol de directorios manteniendo las fechas de actualizacion, permisos, y link simbolicos (Gracias Rodrigo por la aclaracion)

“v”, verbose, muchos comandos en linux tienen la opcion verbose, que basicamente significa si va a mostrar el detalle en pantalla o no. Rsync sin esta opcion no nos va a mostrar el detalle de que archivos esta sincronizando.

“z”, esta opcion es muy importante cuando queremos hacer sincronizaciones remotas, como por ejemplo a nuestro servidor, esta opcion sirve para comprimir los datos que van a viajar por la red.

En el caso que quiseramos hacer lo mismo pero en una carpeta remota hacemos lo siguiente.

  $ rsync -avz /home/pablo/directorioModificado/ user@midominio.com:/home/pablo/directorioSinModificar/

Aca la conexion se va a dar a un servidor remoto, via ssh, por lo cual vamos a especificarle nuestro usuario de ssh (user), el dominio en el que nos vamos a conectar (dominio.com), y vamos agregar el dos puntos (:) y concatenarle la ruta a la carpeta correspondiente en el servidor.

En mi caso el codigo para deployar codigo en el servidor es el siquiente.

 $ rsync -avz ~/Workspace/paintball/ user@dondejugarpaintball.com:/var/www/paintball/

A esta linea yo voy a excluirle la carpeta imgs, .git, y tests. Entonces voy a usar el atributo exclude de rsync, este atributo va a sincronizar todos los archivos y carpetas, menos los que yo indique que se excluyan.

 $ rsync -avz ~/Workspace/paintball/ --exclude tests --exclude .git --exclude public/imgs user@dondejugarpaintball.com:/var/www/paintball/

Ahora recordar todo esto puede ser tedioso, y para eso tenemos los alias. vamos a nuestro archivo ~/.bashrc y agregamos un alias que reemplace toda la linea anterior por un simple sync-paintball

alias sync-paintball="rsync -avz ~/Workspace/paintball/ --exclude tests --exclude .git --exclude public/imgs user@dondejugarpaintball.com:/var/www/paintball/"

Cargamos el nuevo bashrc.

$ source ~/.bashrc

y ejecutamos

$ sync-paintball

Y listo, una vez que termina de sincronizar los archivos voy al sitio en produccion y ya tengo todo actualizado. Si falla algo, cosa que puede pasar, puedo solucionarlo desde mi ambiente local y volver a sincronizarlo, o en el caso que sea algo interno del servidor me conecto al mismo y lo resuelvo. Pero en el mayor de los caso no va a hacer falta.

Podriamos aplicar lo mismo para sincronizar las imagenes a nuestro servidor de CDN.

Recuerden que cada vez que abran una conexion ssh con rsync van a necesitar escribir el password de usuario en el servidor.

Seguir leyendo

April 28th, 2012 Category: Programacion Zend Framework
30 Comments »

Increiblemente he recibido muchas preguntas sobre como instalar Zend Framework en un hosting donde no tengo acceso al virtual host, y a la configuracion de apache en general.

Realmente esto es muy simple, ahora vamos a ver porque.

Zend Framework no requiere que el proyecto donde se use, sea con MVC lo sugiere pero no hace falta. Por lo que no veamos la estructura de carpetas de Zend Framework como algo estricto.

Las carpetas que Zend_Tool crea cuando inicia un proyecto son las siguientes.

application/
docs/
library/
public/
tests/

Siendo public/ el punto de entrada a nuestra aplicacion, si nosotros configuramos el virtual host en apache vamos a apuntar el documentRoot de la aplicacion a la carpeta public, esto es debido a que esta carpeta contiene dos archivos escenciales para el funionamiento de la aplicacion creada en Zend Framework, index.php y .htaccess. Estos archivos van a procesar todas las urls de nuestra aplicacion y la van a redirigir al controller necesario, o al arcvhivo estatico. Teniendo en cuenta esto. Vamos a analizar como es hoy un hosting comun y corriente.

Hace mucho que no uso un hosting como los de elserver.com, datattec.com, y todos esos server que ofrecen servicios de hosting compartidos, no voy a hablar ni bien ni mal, prefiero no desviar el tema, si pueden paguense un VPS no son tan caros.

Cuando activamos nuestra cuenta en el hosting, le asignamos un dominio por ejemplo mipaginazf.com, nos van a dar una cuenta de FTP y con esa cuenta nosotros vamos a entrar desde filezilla, o el cliente FTP que usen. Cuando nos logueamos con nuestros datos podemos ver un listado de directorios con diferentes propositos

cgi/
public_ftp/
public_html/
backup/

etc… esto dependene del proveedor pero pueden tener diferentes nombres, mas o menos carpetas.

Lo que tenemos que tener como importante es que todos nuestros archivos web “deberian” ir en la carpeta public_html para ser interpretados, esta carpeta va a ser el punto de entrada de nuestro dominio mipaginazf.com

Digo deberian, con comillas (“) porque en nuestro caso tenemos una carpeta pubic/ que es nuestro punto de entrada, donde tenemos todos los archivos estaticos de nuestro proyecto y nuestro index.php y .htaccess que determinan que controller ejecutar.

Teniendo en cuenta esto, podriamos tener en el root/ de nuestro FTP las siguientes carpetas

cgi/
public_ftp/
public_html/
backup/
application/
docs/
tests/
library/

etc.

Los archivos index.php y .htacces como todo el resto del contenido estatico solo necesitamos moverlo a la carpeta public_html

Y asi de facil es configurar un proyecto en un hosting.

Obviamente antes de contratar un hosting, pregunten que soporte archivos .htaccess, tenga rewrite activo, y la version de php sea mayor a 5.2.x

Seguir leyendo

December 29th, 2011 Category: Curso Zend Framework
89 Comments »

En los anteriores capitulos habiamos usado el video como metodo de aprendizaje, hoy habiendo cubierto la parte inicial y basica de Zend Framework, creo que estamos preparados para dejar el video atras, y continuar los capitulos leyendo un poco.

En este capitulo vamos a ver como crear un sistema de login en nuestro proyecto. Nosotros actualmente en nuestro portal de noticias tenemos una pantalla donde publicamos nuestras noticias. Pero actualmente esa pantalla es accesible por cualquier persona.

El objetivo de este capitulo es crear una pantalla de login, y restringir el acceso a la administracion de las noticias solo a las personas que tengan usuario y contraseña.

Lo primero que vamos a hacer es crear un nuevo controller, UsuarioController.php

El codigo de este controller inicialmente sera asi.


class UsuarioController extends Zend_Controller_Action
{
    
    public function init()
    {
        
    }

    public function loginAction()
    {
        $form = new Application_Form_Login();

        if( $this->getRequest()->isPost() ){
            
            if( $form->isValid( $this->_getAllParams() )) {
                
                // Do something
            }
        }

        $this->view->form = $form;
    }


}

Para este controller vamos a tener que crear una vista asi que creamos la carpeta en views/scripts/usuario y agregamos el archivo login.phtml, donde vamos a imprimir el formulario y mostrar un mensaje, el archivo quedaria asi

<div>
    <h2>Ingresar al sistema</h2>
    <?php echo $this->form ; ?>
</div>

Tambien vamos a necesitar un formulario para poder ingresar usuario y contraseña.

Creamos el archivo en forms/Login.php

Este formulario va a tener un input para el usuario otro para el contraseña, y el boton de submit, el formulario Login.php nos quedaria asi.


class Application_Form_Login extends Zend_Form 
{

    public function init() 
    {

        $this->addElement(
            'text', 'username', array(
                'label' => 'Usuario:',
                'required' => true
            )
        );

        $this->addElement(
            'password', 'password', array(
                'label' => 'Contraseña:',
                'required' => true
            )
        );

        $this->addElement(
                'submit', 'Ingresar', array()
        );
    }

}

Hasta ahora no vimos nada nuevo, es mas o menos el mismo mecanismo que usamos para crear un nuevo post. Si entramos en la url de nuestro proyecto /usuario/login vamos a ver el formulario de login como aparece en la siguiente imagen.

Ahora que tenemos el codigo vamos a crear una tabla donde se van a guardar todos los usuarios que van a tener permisos al panel de administracion de nuestro proyecto. El sql para crear la tabla es el siguiente.

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(40) NOT NULL,
  `password` char(40) NOT NULL,
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
);

INSERT INTO `users` (`username`, `password`) VALUES
    ('pablo', '7c4a8d09ca3762af61e59520943dc26494f8941b');

Nuestra tabla de usuario es bastante sencilla, por ahora vamos a cumplir con los requerimientos minimos. El hash extraño que se ve es la contraseña “123456″ encriptada con la funcion sha1()

Ahora que ya tenemos un usuario (pablo) y una contraseña (123456), nos falta agregar la logica para que se valide si el usuario existe o no.

Zend Framework nos brinda el componente Zend_Auth el cual a partir de sus Adapters, nos permite validar un usuario y loguearlo en el sistema. La forma de usarlo es bastante simple, Zend Auth entiende identidad y credencial, donde la identidad es el nombre de usuario o mail que vamos a usar para identificar a un usuario dentro del sistema, y la credencia es la contraseña.

Nosotros vamos a usar Zend_Db_Adapter_DbTable el cual se encarga de validar el usuario y contraseña en nuestra base de datos.

El codigo cuando usemos Zend_Auth deberia ser el siguiente.

$authAdapter = new Zend_Auth_Adapter_DbTable();

$authAdapter
    ->setTableName('users')
    ->setIdentityColumn('username')
    ->setCredentialColumn('password');

$authAdapter
    ->setIdentity('pablo')
    ->setCredential(sha1('123456'));

$auth = Zend_Auth::getInstance();

$result = $auth->authenticate($authAdapter);
                
if(  $result->isValid() ){
    echo "Estamos Logueado!";
}else{
    echo "Datos incorrecto";
}

Ahora este codigo vamos a adaptarlo a nuestro controller. Nos quedaria asi

class UsuarioController extends Zend_Controller_Action
{
    
    public function init()
    {
        
    }

    public function loginAction()
    {
        $form = new Application_Form_Login();

        if( $this->getRequest()->isPost() ){
            
            if( $form->isValid( $this->_getAllParams() )) {
                
                $authAdapter = new Zend_Auth_Adapter_DbTable();
                $authAdapter
                    ->setTableName('users')
                    ->setIdentityColumn('username')
                    ->setCredentialColumn('password');

                $authAdapter
                    ->setIdentity($form->getValue('username'))
                    ->setCredential(sha1($form->getValue('password')));

                $auth = Zend_Auth::getInstance();

                
                $result = $auth->authenticate($authAdapter);
                
                if(  $result->isValid() ){
                    return $this->_redirect('/posts/listar');
                }else{
                    $form->username->addErrorMessage('Datos Incorrectos');
                }
            }
        }
        $this->view->form = $form;
    }


}

Con este codigo cada vez que nos identifiquemos correctamente nos va a redirigir a /posts/listar donde vamos a mostrar todas las noticias.

Ahora los que nos faltaria agregar es que en cada lugar donde nosotros queramos restringir el acceso, agregar el chequeo si el usuario esta logueado o no, sino esta logueado vamos a redireccionarlo a la pantalla de login.

En cada action que querramos validar esto vamos a agregar el siguiente codigo.

$auth = Zend_Auth::getInstance();
if (! $auth->hasIdentity()) {
    return $this->_redirect('/usuarios/login');
}

Notese que en el caso de PostsController, tenemos metodos que son de acceso publico y acceso privado, si llegado el caso tenemos un Controller donde necesitamos que todos los metodos sean de alcance privado, las lineas de arriba podemos escribirlas en el metodo init() de nuestro controller, ese metodo init se va a llamar antes de ejecutar un action de ese controller, y de esta forma evitamos repetir codigo.

Hay otras practicas para mejorar esto pero eso podemos verlo mas adelante.

Ahora que restringimos el acceso, vamos a necesitar la posiblidad de desloguearnos del sistema, para eso vamos agregar un link en nuestro layout.phtml en la parte del menu, que nos redireccione a /usuarios/logout y este es el codigo de nuestro action para desloguarnos.

public function logoutAction()
{
    Zend_Auth::getInstance()->clearIdentity();
    return $this->_redirect('/usuario/login');
}

Bastante simple, no :D , asi es todo con Zend Framework.

Ahora, vamos a dejarlo mas bonito a todo esto, y vamos validar en la vista si el usuario esta logueado, voy a mostrar un link a logout, si esta deslogueado voy a mostrar un link a la pantalla de login. El codigo a agregar en nuestro layout seria el siguiente.

<?php
$auth = Zend_Auth::getInstance();
if ( $auth->hasIdentity()) :
?>
    <li>Usuario:<?php echo $auth->getIdentity() ?></li>
    <li><a href="/usuario/logout">Logout</a>
<?php else: ?>
    <li><a href="/usuario/login/">Login</a>
<?php endif;?>

Y con esto ya somos capaces de agregar un sistema de login en nuestros proyectos usando Zend Framework.

Ver todos los capitulos del curso

Seguir leyendo

December 19th, 2011 Category: eventos
1 Comment »

Este tiempo desde que subo los videos tengo un feedback de la gente que sigue este blog muy grande. Por este quiero probar de juntarnos virtualmente con google plus, hacer un hangout , y poder compartir experiencia, y los que tengan ganas pueden usarlo para sacarse las dudas que tengan.

 

Es bastante informal, no va a ver lista de invitados ni nada de eso, a las 21hs Hora Argentina,  abro el hangout invito a los que esten online en ese momento, y dejo abierto para que lo llenen los que quieran participar, personalmente creo que esta bueno para que planteen algun tema para los proximos videos, o como les decia antes sacarse alguna duda.

 

Los espero, el martes 19 de diciembre a las 21hs Argentina, en google plus.
Agreguenme asi los tengo a mano.

 

https://plus.google.com/113488230260400531922

 

 

 

Seguir leyendo

November 22nd, 2011 Category: Ambiente de Desarrollo cloud Open source Programacion
3 Comments »

Hay una serie de herramientas que son necesarias en cualquier ambiente de desarrollo, en esta serie de post, vamos a ver como crear un ambiente semi ideal para el desarrollo en equipos de desarrollo.Como primer topico vamos a hablar sobre la documentacion.

Seguramente les paso muchas veces que tuvieron que heredar algun desarrollo ya empezado, y tenian que perder mucho tiempo leyendo codigo y usando la aplicacion para entender como funcionaba y sin embargo siempre encontraban algo nuevo. Que genial seria poder leer la documentacion de como esta diseñado un software y poder entender, alcance, features, bugs, puntos de entrada, tecnlogias usadas, etc. Lamentablemente esto casi nunca pasa, y tenemos que hacerlo de la forma dificil y lenta. Pero nosotros podemos cambiar eso, e implementar politicas de documentacion para nuestros proyectos.

En estos sistemas podemos agregar documentos, screenshot, imagenes, especificaciones de instalacion, configuracion, librerias a usar, detalle de servidores, listado de grupos de desarrollo (en el caso que sean varios grupos), etc. Todo lo que puede servir para que una persona nueva en el grupo o alguien que herede nuestro codigo pueda entender como funciona leyendo la documentacion del desarrollo.

Como formato ideal de documentacion para este tipo de cosas, me parece que gana el estilo wiki. No solo tenemos wikimedia, sino que tambien contamos con Trac, Confluence, PbWorks, y muchos mas. Pero obviamente si les resulta comodo usar google docs, o archivos con formato Word o Excel tambien es valido, pero por experiencia siempre terminamos teniendo carpetas inecesarias con un monton de archivos que no sabemos de que hablan, y capaz que ya perdieron vigencia.

Aca les voy a contar de algunos proyectos interesantes que pueden usar para sus proyectos.

Mediawiki.

El mismo codigo que se usa para la wikipedia esta disponible para que nosotros podamos instalarlo internamente en nuestro servidor con nuestros documentos privados, funciona de la misma forma que la wikipedia y se puede descargar de http://www.mediawiki.org/wiki/Download/es, dentro de nuestro ambiente lo podemos configurar como una pagina comun y corriente.

Mediawiki es un producto open source. Y no hay que pagar por usarlo

Confluence

Esta es otra alternativa a mediawiki que se presume mas completa y facil de integrar con otras herramientas como Jira.
http://www.atlassian.com/software/confluence/overview

Lamentablemente este servicio es pago. Pueden usar los servidores de atlassian.com o pueden usarlos dentro de su ambiente. Cualquiera de las dos es viable, el producto es muy bueno a pesar de su precio.

Trac


Durante mucho tiempo use Trac, no solo por la wiki, tambien por su integracion con el repositorio de svn, la verdad es que hoy no me resulta comodo, hay muchas alternativas, y esta paso a ser de mis ultimas elecciones. Trac esta desarrollado en python, y tiene plugin para integrarlo con git y creo que tambien con mercurial y bazaar. Es open source y gratuita.
PBWorks
Uno de mis favoritos, es un servicio online, de documentacion de proyectos colaborativo, anda muy bien. La version gratuita es muy completa. Se puede pagar por algunos features especiales.
http://pbworks.com/

Basecamp

Es uno de los mas famosos, y brinda una solucion un poco mas amplica, no recuerdo si tiene wiki, pero si soporta compartir documentos, e integra muchas funcionalidades. Es un servicio pago mensualmente
http://basecamphq.com
Github
Sin dudas mi primer eleccion, tanto para proyecto privados pagando el fee mensual, como para proyectos opensource, no solo integra git en tus proyectos, sino que ademas brinda la posibilidad de crear wiki, ticket, comentar parte de codigos, hacer comentarios de una review, trabajar con la cantidad de colaboradores que quieras, seguro, facil. Tiene bugtrucker. Git no seria lo que es hoy sin este servicio espectacular que crece dia a dia, PHP, el Kernel de Linux, Zend Framework entre otros decidieron pasarse a github para sus proyectos. Hoy yo tengo casi todos mis proyectos en github y funciona excelente. Como wiki cuando la documentacion crece quizas sea mejor decision pensar en mediawiki, o pbworks.https://github.com

 

 

Red Mine

Me olvidaba  de una de las mejores alternativas opensource, RedMine. Desarrollado en Ruby on Rails, es una excelente alternativa a Jira + Confluence, un producto super completo y libre.

http://www.redmine.org/

 

Conclusion

Hay otras soluciones, pagas y gratuitas para documentar nuestros desarrollos. Estas son con las que trabaje, en el proximo articulo vamos a tratar de elegir que software de control de versiones usar, y cual elegir entre tantas opciones nuevas.

No solo es importante configurar un ambiente sino tambien usarlo. Si implementamos algun sistema para documentar y no lo usamos no tiene sentido, es una buena costumbre documentar el codigo, y es algo vital para el futuro inmediato.

Seguir leyendo

November 14th, 2011 Category: Curso Zend Framework
45 Comments »

En el video de hoy voy a mostrarles como hacer un join con otras tablas, en nuestro caso tenemos la tabla posts, y la tabla categories, vamos a tratar de crear posts que tengan una categoria asociada y mostrar los post a partir de la categoria por la que filtramos.

Para esto vamos a usar un Join para mostrar los nombres de las categorias a las que esta asociada una noticia, y un helper de la vista para mostrar el listado de categorias dentro de nuestro layout.

Aca les dejo el video

Como material extra pueden leer Zend_Db_Select aca van encontrar todo lo referente a armar querys con Zend Framework

Ver todos los capitulos del curso

Seguir leyendo

November 3rd, 2011 Category: php5 Programacion
No Comments »

Data Transfer Object

Como nos dice nuestro maestro Martin Fowler, este patron se utiliza para reducir el numero de lladas a un objeto pasando como parametro un objeto que contenga todos los datos necesarios.

Estoy haciendo un mini proyecto, que pronto subire a github para compartir con ustedes (una vez que termine la documentacion :( ), en el cual necesito recibir una cantidad de datos, y para evitar que me pasen muchos parametros, opte por recibir un json, con todos los datos. Ahora el problema es que en ese json la persona que usa el servicio puede mandar parametros de mas, o de menos.

Ahora, para que esto sea algo ordenado, cree un Data Transfer Object, con las propiedades que necesito recibir en el json que me envian como parametro.

El servicio que recibe el json, va a instanciar este Data Transfer Object, y despues vamos a pasarle al modelo al metodo save el objeto completo.

Un paso previo deberia ser validar que los datos que recibo via Json sean correctos una vez que lo paso al DTO.

Supongamos que nuestra funcion encola mails a enviar.

Nuestro DTO sera el siguiente


class Application_Model_Mail_DTO 
{
    public $from;
    public $to;
    public $cc;
    public $bcc;
    public $subject;
    public $replyTo;
    public $htmlBody;
    public $textBody;
    public $templateParams;
    public $htmlTemplate;
    public $textTemplate;    
}

El metodo que recibe el JSON, seria el sigueinte.

...
public function enqueue($data)
{
    $data = Zend_Json::decode($data);
    $dto = new Application_Model_Mail_DTO();
    $dto->from = $data[‘from’];
    $dto->to = $data[‘to’];
    // … asi sucesivamente hasta cargar todas las propiedades
    $model = new Application_Model_Mail();
    $model->save( $dto );
}        

Ok, esto es bastante tedioso y termina generando un codigo muy largo para algo que podemos resolver en pocas lineas usando SPL.

Las SPL son librerias de PHP compuestas de algunas interfaces y clases, para resolver algunos problemas como el que tenemos en este caso.

Para este caso yo voy a usar ArrayIterator que convierte mi objeto ( DTO ), y lo convierte en iterable. Ademas me va a proporcionar de un metodo vital en este proceso.

Ahora voy a extender mi DTO de ArrayIterator. Y ademas voy a agrgar un hack en el __construct, para que cuando reciba un array, solo guarde los valores que existen como propiedad dentro de mi DTO. La clase quedaria asi.

class Application_Model_Mail_VO extends ArrayIterator
{
    public $from;
    public $to;
    public $cc;
    public $bcc;
    public $subject;
    public $replyTo;
    public $htmlBody;
    public $textBody;
    public $templateParams;
    public $htmlTemplate;
    public $textTemplate;

    public function __construct( $array ) 
    {
        foreach($array as $key=> $value ) {
            if(property_exists('Application_Model_Mail_VO' , $key )) {
                $this->{$key} = $value;
            }
        }
    }
}

Una vez agregado esto, ahora vamos a ver como quedaria nuestro metodo queue con esta modificacion.

...
public function enqueue($data)
{
    $data = Zend_Json::decode($data);
    $vo = new Application_Model_Mail_DTO( $data );
    $model = new Application_Model_Mail();
    $model->save( $dto );
}

Se daran cuenta que quedo mucho mas simplificado el codigo y mientras mas simple mas facil de leer.

Ahora como quedaria nuestro modelo, que recibe este DTO y lo guarda, en mi ejemplo yo uso MongoDb para no tener que mostrarle el schemea de la Base de Datos, y los metodos inserts de MySql.


class Application_Model_Mails
{
    private $_collection;

    // Insancio la clase Mongo que contiene la conexion, y le digo cual es la coleccion donde voy a guardar los datos. 
    public function __construct()
    {
        $db = new Mongo();
        $this->_collection = $db->mailer->spooler;
    }

    public function save( Application_Model_Mail_DTO $properties )
    {
        return $this->_collection->insert( $properties->getArrayCopy()  );
    }
}

Como se ve en el ejemplo, validamos que el parametro que recibe save(), sea una instancia de Application_Model_Mail_DTO, si esto es asi vamos a insertar los parametros que devuelve el metodo getArrayCopy(), que es parte de ArrayIterator, el cual devuelve un array con las propiedades de nuestro Application_Model_Mail_DTO.

Un paso previo, y que no contemple en este ejemplo es validar que los datos que se reciben esten completos y sean validos, tengan en cuenta siempre validar y filtrar los datos que se reciben.

Seguir leyendo

October 23rd, 2011 Category: Curso Uncategorized Zend Framework
18 Comments »

Se hizo esperar este ultimo capitulo, la verdad es que tuve algunos problemas con los codecs, y poco tiempo para resolver este problemita.

Lo prometido es deuda y hoy les voy a mostrar como crear un sitio multidioma.

Como primera medida me baje las banderitas desde iconfinder y las agregue en el top bar de la aplicacion.

Aca les dejo el video para que vean lo simple que es crear un sitio multiidioma con Zend Framework.

Ver todos los capitulos del curso

Seguir leyendo