November 14th, 2011 Category: Curso Zend Framework
31 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

September 12th, 2011 Category: Curso php5 Programacion Zend Framework
23 Comments »

Llego la hora de hacer algo util, hoy vamos a ver como configurar nuestra aplicacion para trabajar con una base de datos mysql, para eso vamos a usar Zend_Form para crear formularios y vamos a crear modelos para poder traer datos de nuestras tablas y poder escribir en ellas.

Si te perdiste el video anterior podes verlo aca

Es recomendable ver el video en 720p de resolucion y en pantalla completa.

Los que quieran descargarse el codigo fuente pueden hacerlo desde github en http://github.com/pablofmorales/News123

Capitulos Anteriores
Capitulo 1 < Configuracion y creacion del proyecto
Capitulo 2 < Estructura de directorios, MVC y layouts
Capitulo 3 < Objeto view, y contenido estatico

Proximo capitulo > Edicion, y Paginado.

Gracias Maestrosdelweb por darme un espacio en su cuenta de youtube

Seguir leyendo

March 18th, 2010 Category: Programacion Zend Framework
14 Comments »

Mi idea era subir un archivo dentro de un formulario, renombrar ese archivo con un id conseguido en esa misma operacion con el siguiente formato logo_{$id}.jpg . El problema es que cuando agregaba el setDestination del form me copiaba el archivo con su nombre original en la carpeta de destino. No conseguia renombrarlo.

Vi muchisimos ejemplos pero al parecer con la nueva version no andan ninguno, porque los que probe no me sirvieron de forma literal (es decir copy/paste ) .

Asi que tuve que ponerme a leer un poco :( . Despues de ver como funcionaba Zend_Form_Element_File. Trate de implementar la forma mas logica. La cual no me anduvo. Me acorde que cuando usas isValid de un Zend_Form, este ejecuta los filtros y las validaciones correspondientes. Pero encontre dentro de la documentacion la solucion a mi primer problema, el metodo setValueDisabled( true ) evita que se ejecute el filtro del elemento, asi puedo aplicar mi filtro para renombrar mi archivo despues de validarlo.

Mi segundo problema es que cuando implemente esto, no me guardaba el archivo en donde habia establecido. Para entender esto un poco Zend_Form_Element_File usa Zend_File_Tranfer que es el encargado de manipular el archivo. Lo que siguio fue traerme el adapter de Zend_File_Transfer de mi elemento, agregar los filtros y ejecutar el upload. Y listo tenia mi archivo subido ‘in the ZF way’.

Este es el formulario


class Application_Form_Company extends Zend_Form
{

    public function init()
    {

        $this->setAttrib('enctype', 'multipart/form-data');

        $this->addElement('text', 'name', array(
            'required'   => true,
            'validators' => array(
            ),
            'class' => 'sf'
        ));
        $this->addElement('file', 'logo', array(
            'class' => 'sf'
        ));
        $this->logo->addValidator( 'Extension', false, 'jpg,png,gif,jpeg' );
        $this->logo->addValidator( 'Size', false, '10024000' );
        $this->logo
            ->setDestination( APPLICATION_PATH . '/../public/empresas/imgs/' )
            ->setValueDisabled( true );

        $this->addElement('text', 'website', array(
            'required'   => true,
            'class' => 'sf'
        ));

        $this->addElement('text', 'telephone', array(
            'required'   => true,
            'class' => 'sf'
        ));

        $this->addElement('textarea', 'information', array(
            'required'   => true,
            'class' => 'sf'
        ));

        $this->setDecorators(
            array(
                array(
                    'ViewScript',
                    array( 'viewScript' => 'company/form.phtml' )
                )
            )
        );
    }
}

Asi quedo mi action

        ...
        $form = new Application_Form_Company();
        if ( $this->getRequest()->isPost() ) {
            $file = $form->logo;
            if( $form->isValid($this->getRequest()->getParams()) ) {
                $bind = $form->getValues();
                $company = new Application_Model_Company();

                if( $company->exists( $bind['name'] ) ) {
                    $form->name->addErrorMessage( "La empresa ya existe" );
                } else {
                    try {
                        $id = $company->save( $bind );
                    }catch( Exception $e ) {
                        $this->_helper->flashMessenger()
                            ->addMessage( 'Hubo un problema, revise los datos' );
                    }

                    // Traemos el adapter de Zend_File_Transfer
                    $upload = $form->logo->getTransferAdapter();

                    // Lo ideal es que el path lo trajeramos de un archivo de configuracion.
                    $upload->addFilter('Rename', array(
                        'target' => APPLICATION_PATH . '/../public/empresas/imgs/logo_'. $id .' .jpg',
                        'overwrite' => true
                    ));
                    var_dump( $upload->receive() );
                    ...
Seguir leyendo

December 17th, 2008 Category: blogzf Zend Framework
40 Comments »

Zend Form

Hoy vamos a ver como armar los formularios. Para eso vamos a usar la carpeta forms dentro de nuestras vistas, ahí vamos a crear una clase para cada formulario.

Muchas ponen los formularios en el controller y algún que otro loco en el modelo, y también en los helpers, nosotros vamos a crear una clase para que resuelva nuestro problema en la carpeta forms de la vista del modulo correspondiente.

Nuestra clase va a tener un solo método init() y va a extender de Zend_Form.

El ejemplo a continuación es el de login de usuarios, con 3 elementos, usuario, password, y el botón de submit.

setName('authentication');
        /**
         * Creamos un elemento de tipo Text
         * - Seteamos el texto que queremos que represente a este campo
         * - Agregamos un filtro, que hace que cuando enviamos el
         *   fomrulario ponga todo el valor del campo en minuscula
         * - Tambien especificamos que el campo es obligatorio.
         * - Y agregamos el validador para preguntar si el campo es un campo valido
         */
        $username = new Zend_Form_Element_Text('username');
        $username->setLabel('Email')
            ->addFilter('StringToLower')
            ->setRequired(true)
            ->addValidator('NotEmpty', true);
        /**
         * Creamos el elemento tipo password.
         * Aca vamos a generar el campo para la clave
         */
        $password = new Zend_Form_Element_Password('password');
        $password->setLabel('Clave')
            ->setRequired(true)
            ->addValidator('NotEmpty', true);
        /**
         * El boton para enviar el formulario
         */
        $submit = new Zend_Form_Element_Submit('submit');
        $submit->setLabel('Entrar');
        /**
         * Agregamos los elementos al formulario
         */
        $this->addElements(array($username , $password , $submit));
    }
}

Como se habrán dado cuenta nuestro archivo se va a llamar Authentication.php

Cada vez que se instancie y se imprima este objeto nos va a dibujar automaticamente nuestro formulario.

Ahora vamos a llamar a mostrar el formulario en nuestras paginas.

Vamos al controller


_request->isPost()) {
            $credentials = $this->_request->getPost();
            if ($form->isValid($credentials)) {
                $authAdapter = new Zend_Auth_Adapter_DbTable(
                    Zend_Db_Table::getDefaultAdapter(),
                        'users','username','password', 'MD5(?) AND status="ENABLED"');

                // Set the input credential values to authenticate against
                $authAdapter->setIdentity($credentials['username']);
                $authAdapter->setCredential($credentials['password']);
                $result = Zend_Auth::getInstance()->authenticate( $authAdapter );
                if ($result->isValid()) {
                    $this->_redirect('/admin/dashboard/');
                }
                $this->_flashMessenger->addError('usuario incorrecto');
                $form->populate($credentials);
            } else {
                $this->_flashMessenger->addError('Hay datos invalidos o vacios');
                $form->populate($credentials);
            }
        }
        $this->view->form = $form;
    }
}

En nuestro indexAction vemos que lo primero que se hace es instanciar la clase forms_Authentication que creamos anteriormente. Seguidamente tenemos una linea que pregunta si hay datos enviados via post, en nuestro caso esta condicion va a ser falsa porque todavia no enviamos ningun formulario. Asi que vamos a explicar lo que hacemos en caso de que no se haya enviado el formulario aun.

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

Aca estamos pasando a la vista nuestro objeto Form. Para dibujar nuestro formulario desde el controller esto es lo unico que tenemos que hacer.

Ahora pasemos a la vista. Y veamos como queda de complejo nuestro index/index.phtml

form?>

Esto solo y nos deberia mostrar lo siguiente.

login

Ahora que ya tenemos nuestro formulario vamos a completar datos y enviarlo. Completamos con cualquier dato. Pero para probar vamos a completar el usuario y no la clave. Para aprender a usar los Validators.

Si hacemos esto nos deberia aparecer el formulario resaltando el problema por el cual no proceso el formulario.

login-error

Y como hicimos esto?

Muy facil, cuando creamos el formulario, no especificamos a donde queremos que envie los datos, entonces los envia a si mismo.

Esto quiere decir que enviamos un post a indexAction, ahora el condicional if ($this->_request->isPost()) nos va a dar verdadero.

Lo siguiente que preguntamos es si los datos de nuestro formulario son validos, en el caso que lo sean vamos a seguir con el logueo de usuario. En caso contrario vamos a volver a mostrar el formulario con los datos que envio el usuario, y agregano los errores correspondientes, esto lo hacemos llamando al metodo populate de Zend_Form, que solo se encarga de completar los datos que vinieron por post en el elemento correspondiente, y los errores. Lamentablemente los errores estan en ingles, y por ahora vamos a dejarlo asi. Tambien agregamos un error con el flashHelper de Zsamer.

Ahora probemos completar todos los datos, si corresponden a los de la base de datos te va a loguear, y redireccionar a tu dashboard.

Zend Auth.

Una de las cosas que mas me sorprendio cuando empeze con Zend Framework, fue la cantidad de tutoriales sobre este componente. La verdad que no tiene mucha mistica, pero el uso que le damos en blogzf es bastante basico y comun,

Primero instanciamos la clase Zend_Auth_Adapter_DbTable, y le pasamos los datos de nuestra tabla donde guardamos los datos de los usuarios, seteamos la columna donde esta el identificador, y la columna donde esta la clave (credencial).

Ya con la instancia seteamos los datos que vinieron con el formulario.

Y si Zend_Auth::getInstance()->authenticate( $authAdapter )->isValid() nos da true, estamos logueados.

Facil?, si es Zend.

Ahora necesitamos preguntar en cada modulo que lo requiera si el usuario ya esta logueado, en caso que no lo este vamos a redireccionarlo a la pantalla de login. En nuestro sistema lo vamos a hacer desde el plugin de Blogzf_Controller_Plugin_Backoffice.


$auth = Zend_Auth::getInstance();
if ( $request->module == 'admin' ) {
    if( !$auth->hasIdentity() && $request->controller != 'index' ) {
        header('Location: /admin/');
    } elseif ( $auth->hasIdentity()  && $request->controller == 'index' ) {
        header('Location: /admin/dashboard/');
    }
}

Con esto es suficiente.

Seguir leyendo