January 12th, 2009 Category: blogzf Zend Framework
9 Comments »
Plugins.
En ZF podemos utilizar plugins. Estos plugins se van a ejecutar en determinado momento, como puede ser el Predispatch o el PostDispatch. En muchos proyectos con ZF se utiliza una capa superior para los controllers para obligar al sistema que ejecute siempre la capa superior donde en esta capa podemos tener varias funcionalidades comunes para todos los controllers.
Esto no es una mala decisión, de hecho en nuestro blog tenemos un controller genérico. Pero también podemos hacer uso de los plugins, estos además de servirnos posteriormente para extender la funcionalidades, como puede ser el agregado de un contador de visitas, o cualquier funcionalidad extra que queramos darle al sistema sin necesidad de tocar el código existente, solo extendiendo el que hay. Como es el caso de los plugins en WordPress, también podemos tener algunos plugins genéricos, para que procesen acciones genéricas, como puede ser el caso de configurar la vista, el layout, o la base de datos, el manejo de sesiones, etc.
En nuestro blog actualmente hay varios plugins, y cada uno bien separado su funcionalidad, hay un plugin extra especialmente para el admin, el cual maneja la seguridad (por ahora solo eso), pero también tenemos un plugin para instanciar la vista, y decirle de donde sacar el menú, y todo lo necesario para renderear la vista, además de un plugin para el manejo de layouts, otro plugin para la base de datos. Y además de esto una capa de abstracción superior en los controllers.
El uso de plugins en Zend Framework, es muy fácil y se cargan desde el bootstrap, cuando agregamos los controllers y antes de hacer dispatch, le decimos que plugins cargar.
$controller = Zend_Controller_Front::getInstance
->throwExceptions(true)
->registerPlugin( new Blogzf_Controller_Plugin_Config())
->registerPlugin( new Blogzf_Controller_Plugin_Layout())
->registerPlugin( new Blogzf_Controller_Plugin_View())
->registerPlugin( new Blogzf_Controller_Plugin_Backoffice())
->dispatch();
Como se puede apreciar en el código de nuestro bootstrap, cargamos 4 plugins. Estos plugins los ubicamos en la carpeta library/Blogzf/Controller/Plugin, esta ruta es para tener una hegemonía con la estructura de directorios de ZF.
Estos plugins son muy fácil de programar. Cada clase implementa una interfaz genérica que cada método corresponde a una instancia de ejecución de nuestra pagina. Tenemos un método para preDispatch, otro para el postdispatch, que cada vez que le toca ejecutarse a estos metodos se llama a los plugins, antes del controller. Nuestros plugins extienden de la clase padre Zend_Controller_Plugin_Abstract . Un plugin normal con dos metodos como son PreDispatch, PostDispatch, quedaría como el siguiente.
/**
* Plugin para administrar las vistas de nuestro sistema.
*
*/
class Blogzf_Controller_Plugin_View extends Zend_Controller_Plugin_Abstract
{
protected $_viewRenderer;
protected $_view;
public function preDispatch (Zend_Controller_Request_Abstract $request)
{
/**
* Esto es un singleton de la vista para que no lo reinicie
*/
$this->_viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$this->_viewRenderer->initView();
/**
* Traemo los datos del archivo de configuaracion
*/
$config = Zend_Registry::getInstance()->get( 'config_ini' );
$auth = Zend_Auth::getInstance();
$this->_view = $this->_viewRenderer->view;
/**
* Agregamos unas
*/
$this->_view->baseUrl = $request->getBaseUrl();
$this->_view->module = $request->getModuleName();
$this->_view->controller = $request->getControllerName();
$this->_view->action = $request->getActionName();
$this->_view->hasIdentity = false;
if ( $auth->hasIdentity() ) {
$this->_view->hasIdentity = true;
$this->_view->Identity = $auth->getIdentity();
}
/**
* Agregamos las rutas para las vistas
*/
$this->_view->addScriptPath('/application/blog/views');
$this->_view->addScriptPath('/application/admin/views');
/**
* Url basicas del sistema
*/
$this->_view->staticServer = $config->site->static->server;
$this->_view->appServer = $config->site->static->server;
/**
* Agrego el titulo de la pagina
*/
$this->_view->headTitle()->append( $config->site->title );
$this->_view->site = $config->site;
/**
* Agrego los css para esta pagina que siempre va a ser el mismo.
* /layout/nombre_layout/style.css esto es para poder agregar muchos layout. Y no dependan
* de la cantidad de css, si necesitamos separar en mas archivos. Podemos hacer un @import desde
* style.css
*
*/
if ( $request->module == 'admin' ) {
$layout = $config->site->layout->admin;
$this->_view->headScript()
->appendFile( $this->_view->staticServer . 'js/mootools/mootools-core.js' );
} else {
$layout = $config->site->layout->default;
}
$this->_view->headLink()
->appendStylesheet( $this->_view->staticServer . 'layout/'.$layout.'/styles.css' );
}
public function postDispatch (Zend_Controller_Request_Abstract $request)
{
if ($this->_view->module=='default') {
return;
}
if ($this->_view->layout()->isEnabled() ) {
$this->_view->layout()->sidebar = $this->_view->action( 'rightcontent', 'sidebar', $this->_view->module );
$this->_view->layout()->header = $this->_view->action( 'header', 'sidebar', $this->_view->module );
$this->_view->layout()->footer = $this->_view->action( 'footer', 'sidebar', $this->_view->module );
$this->_view->layout()->menutop = $this->_view->action( 'menutop','sidebar', $this->_view->module );
}
}
}
Si necesitamos que algun dato persista, podemos usar Zend_Registry
Como se daran cuenta, estos plugins son muy facil. No requieren mucho mas que esto.
Si van al codigo de blogzf van a encontrar el codigo de los otros 4 plugins.
December 19th, 2008 Category: blogzf
11 Comments »
Estos dias me
estuve debatiendo entre el uso o no de Zend_Dojo. Sinceramente siempre use Jquery, mootools y prototype, la verdad es que en un punto llegan a ser lo mismo, alguna aporta algo que la otra no, pero masomenos tienen el mismo fin, hacernos la vida mas facil, y este no fue el caso de Dojo, ultimamente estaba usando Zend_Dojo para un proyecto, y me costo bastante usarlo, y nunca llegue a aprovecharlo al maximo, termino escribiendo mucho codigo y no me gusta los resultados que obtengo y tampoco me acostumbro a su sintaxis, tan diferente a la facilidad de mootools. Debido a esto y a una charla con scrammatte decidi usar mootools y no complicarme la vida con estas cosas que no aportan gran cosa. Asi que a partir de ahora vamos a usar Mootools en el blog que estamos desarrollando con Zend Framework, y nos olvidamos de Zend Dojo.
Una de las principales razones que desisti de Dojo fue cuando scramatte me mostro Mochaui, enseguida me atrajo esa interfaz tan agradable y practica. Estos dias voy a tratar de adaptar mochaui al Backoffice del blog.
Y no solo van a ver a Mochaui, tambien vamos a empezar a trabajar con otros componentes mas de mootools, como son fvalidator, mootab, porque no mooflow, despues vamos a analizar cual conviene o no implementar, por ahora solo sepan que vamos a trabajar con Mootools.
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
=$this->form?>
Esto solo y nos deberia mostrar lo siguiente.
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.
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.
December 11th, 2008 Category: blogzf Open source Zend Framework
7 Comments »
Primero que nada quiero contarles que se unió scramatte al grupo de trabajo del Blog. Scramatte va a estar desarrollando junto conmigo todo el proyecto, todavía no hay una convocatoria abierta a participar del desarrollo pero los que tengas ganas pueden dejar su comentario.
Esta incorporación voluntaria es muy importante para el proyecto ya que Scramatte ya había empezado a desarrollar un blog con Zend Framework, y tiene bastante experiencia. Si hacen un update del proyecto van a notar grandes cambios. Y digo grandes, porque ya tenemos un Diseño de base de datos mas completo, acorde a las necesidades, y el sistema en el frontend ya adquirió mucha de las funcionalidades.
Por el lado del backoffice (backend/admin), tome prestado otro estilo, no va a ser el definitivo, pero necesitaba una estructura para trabajar. También incorpore el plugin de Zsamer para el manejo de errores. El login ya tomo un poco de forma, y solucionamos algunos problemas con las vistas.
En la parte anterior vimos el uso de módulos dentro de nuestros sistemas. Y anticipamos el ABML de módulos como el de usuario, para los abml vamos a usar los ejemplos de CRUD también del blog de Zsamer, que a mi gusto están muy bien hechos, y además ya podemos usar el manejador de errores.
Otro cambio importante, y es lo que voy a tratar de explicar hoy es la incorporación de 3 externals nuevos. Estos externals son los componentes que necesita Dojo. Voy a hacer lo posible por implementar de la mejor manera este componente, porque tal como me lo describió scramatte, es un monstruo. Lo mas fácil seria usar Mootools o Jquery, pero Zend_Dojo, me parece el mas completo. Por ahora solo vamos a usar Zend Dojo View Helpers.
Lo primero que tenemos que hacer es agregar estos 3 Dojo toolkit como externals, que es la manera correcta de hacerlo, en la carpeta webroot para que pueda ser accedida públicamente, lo ideal seria tener un branch propio donde tengamos el ultimo release de estas Dojo Toolkit en nuestros propios repositorio, pero por ahora no va a hacer falta, y vamos a agregar directamente los repositorios de dojo.
Una vez tengamos los dojo toolkits dentro de nuestro webroot tenemos que habilitar Zend_Dojo en nuestro sistema. La forma que por ahora vamos a usar en nuestro proyecto es poner el código dentro de nuestro plugin de View, y como por ahora solo vamos a usarlo en el Backoffice, vamos a habilitarlo ahí solamente. El código para habilitar Zend_Dojo es el siguiente.
_view->addHelperPath( 'Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper' );
/**
* Ahora habilitamos Zend_Dojo en nuestra vista
*/
Zend_Dojo::enableView( $this->_view );
/**
* Configuracion de Dojo
*/
$this->_view->dojo()->setDjConfigOption( 'parseOnLoad', false );
$this->_view->dojo()->setDjConfigOption( 'userPlainJson', true );
Zend_Dojo_View_Helper_Dojo::setUseDeclarative();
Ahora desde nuestro layout vamos a cargar la librería dojo, como dice el Manual de Zend Framework. Desde el header html de nuestro layout agregamos la siguientes lineas.
dojo()->isEnabled() ) {
$this->dojo()->setLocalPath('/js/dojo/dojo.js');
echo $this->dojo();
}
?>
Esto despues de <?= $this->headScript() ?>.
Con esto ya podemos usar los helpers de Zend_Dojo, y tenemos habilitado la libreria de Dojo. Se que es mas dificil que.
<script src="http://www.google.com/jsapi"></script> <script>google.load("mootools", "1.11");</script> Pero a la larga vamos a apreciar esto. La gran integracion de Dojo con Zend Framework es algo muy favorable, y agil. En proximas entregas vamos a tratar de darle un poco mas de onda a nuestro backoffice haciendo uso de estas librerias.




