Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2012
Programacin III
Introduccin
Abordaremos luego en este en nuevo nuevos captulo un primer que repaso la de
2012
los clase,
Action para
mtodos
provee
Programacin III
Repaso sobre Action Controllers Zend_Controller_Action Action es una clase abstracta utilizada para
2012
implementar
Controllers, cuando queremos construir aplicaciones web basadas en MVC y se utiliza en conjunto con el Front Controller.
crear mtodos que correspondern a varias acciones de nuestra aplicacin. Por ejemplo:
class FooController extends Zend_Controller_Action { public function barAction() { // hacer alguna lgica de negocio }
Programacin III
2012
En el ejemplo la clase FooController (controlador foo) define dos acciones, bar y baz. Por diseo, Zend_Controller_Action debe ser heredada a fin de crear un action controller (Aplicacin MVC). Como mnimo se necesita definir los mtodos Action que el controlador llamar en una determinada peticin. Tambin repitiendo podramos encontrarnos con el problema de que estamos
las mismas configuraciones o mtodos (tiles) en muchos de nuestros class) que para resolver dicha
controladores; si es as, es recomendable crear una clase base abstracta en comn (common base controller extienda redundancia. a Zend_Controller_Action
Programacin III
Iniciar el Objeto Action Controllers
Aun cuando es posible no Zend_Controller_Action::__construct sobrescribir el constructor es ejecuta algunas del
2012
action
controller
recomendado. importantes
tareas, tales como registrar el objeto Request y Response, as como tambin cualquier argumento de invocacin pasado por el Front Controller. En caso de que vayamos a sobrescribir el constructor hay que asegurar llamar a: parent::__construct($request, $response, $invokeArgs). La ms apropiada va para hacer una inicializacin es usar el mtodo init(), el cual es llamado como la ltima tarea en el constructor __construct(). Por ejemplo si quiero iniciar clases del modelo o una conexin a la base de datos:
class FooController extends Zend_Controller_Action { public function init() { $this->db = Zend_Db::factory('Pdo_Mysql', array( 'host' => 'myhost',
'username' => 'user', 'password' => 'XXXXXXX', 'dbname' )); } } => 'website'
Programacin III
Mtodos Pre- y Post-Dispatch
Zend_Controller_Action especifica dos mtodos que pueden ser sobrescritos
2012
para dar
preDispatch() es llamado justo antes de ejecutar el mtodo de la accin en cuestin postDispatch() como indica su nombre es llamado justo despus de ejecutar la accin en cuestin.
Estos mtodos pueden ser bastante tiles al momento de verificar una autenticacin o ACL antes de ejecutar la accin, en otras palabras trabajan, como interceptores de las acciones ("antes de hacer algo", "luego de hacer algo").
Programacin III
Mtodos Accessors
2012
Un nmero de objetos y variables son registradas en el objeto Action Controller y cada una de estas tienen sus mtodos getter y setter (tambin llamados mtodos accessor).
Request Object: getRequest() puede ser usado para obtener el objeto Request usado para llamar la accin con los parmetros de la peticin actual.
$this->getRequest()->getParam(id);
Response el
Object:
getResponse()
puede
ser
usado
para
obtener
objeto Response
Arguments: Router,
Dispatcher,
estos, usamos el mtodo getInvokeArg($key); alternativamente para obtener todos los parametros usamos el mtodo getInvokeArgs().
Request parameters: El objeto request agrega los parmetros del Request, tales como los parmetros $_GET o $_POST, o los parmetros especificados en la URL. Para obtener estos, usamos _getParam($key) o _getAllParams(). Tambin podemos agregar parametros al request mediante el metodo _setParam(); esto es til al momento de reenviar hacia una adicional accin _forward(). Para verificar si el parmetro del request existe o no usamos el til mtodo
hasParam($key).
Programacin III
Integracin con el Objeto Vista, Zend_View
2012
Zend_Controller_Action provee un flexible mecanismo para la integracin con el objeto view a travs de dos mtodos: initView() y render(); El primero view carga dentro y da el la valor al atributo $view, que corresponde e inicializa al el
objeto objeto
que implementa
Interface
Zend_View_Interface
correspondiente a actual accin en cuestin. El mtodo initView() inicializa el objeto de vista (view) dentro de la clase controladora Zend_Controller_Action. Implcitamente el mtodo render() llama a initView() a su vez para inicializar y recibir el objeto vista (sin embargo este puede ser inicializar en cualquier momento), por defecto este poblar a la propiedad $view de la clase controladora con el objeto Zend_View. En definitiva la funcionalidad del mtodo initView() es simplemente iniciar el objeto de vista para que lo podamos utilizar en el controlador, todo el proceso lo realiza en forma implcita o internamente, esto es transparente para el desarrollador. Las vistas/plantillas phtml asume que debe estar en el subdirectorio views/scripts/, y se asume que el sub-directorio views debe de contener las carpetas helpers y filters. Al determinar el nombre de la vista y su ubicacin (View Script Name y Path), el directorio views/scripts/ ser usado como el directorio principal (base path), dentro de este contendr a los subdirectorios nombrados segn cada unos de los controladores de nuestra aplicacin y estos a su vez contendrn a las vistas (view scripts) con extensin .phtml nombradas segn cada acciones (actions) del controlador (controller).
Programacin III
El mtodo render() tiene la siguiente estructura:
2012
string render(string $action = null, string $name = null, bool $noController = false);
El mtodo render() ejecuta propiamente dicho el cdigo de la vista. Si no se pasa ningn parmetro, esta asume que debe hacer render (ejecutar la vista) del controlador y accin de la peticin, en otras palabras [controller]/[action].phtml (donde .phtml es el valor del sufijo o extencin de el script de vista). Al pasar un valor en el parmetro $action del mtodo: render($action), este ejecutar el render de la vista (nombrada como el parmetro $action) en el subdirectorio [controller].
$this->view->render(listado);
Para sobrescribir usando el subdirectorio [controller], se debe pasar a true el valor de $noController. El ltimo parmetro nos dice que no tome en cuenta el directorio del controlador (noController) y nos sirve para ir a buscar la vista en la raz del directorio donde tenemos las vistas o bien en otro controlador. Es decir podramos de forma explcita especificar el directorio donde se encuentra la vista y de esta forma podemos reutilizar las distintas vistas entre los controladores (e incluso entre mdulos): Nos fijamos en el siguiente ejemplo donde tenemos dos controladores IndexController y UsuarioController, la idea aqu es reutilizar la vista del formulario del controlador Usuario en el de Index:
Programacin III
Accin formulario en IndexController:
public function formAction() { $this->render("usuario/form", null, true); }
2012
Nos fijamos que le estamos diciendo al render que no busque la vista en el controlador actual (no buscar en controlador index) sino que la busque en el controlador usuario. Finalmente, la vista es ejecutada ("rendereada") dentro del objeto Response, si deseamos ejecutar la vista (hacer render) hacia un especifico segmento en el objeto response debemos pasar el nombre del segmento como parmetro $name.
$this->view->render(listado, header_segmento);
Tanto como los nombres de los controladores y las acciones pueden contener caracteres delimitadores tales como Internamente, entonces una peticin bar/baz-bat el script foo-bar/baz-bat.phtml. hay que Si camelCasing, separar recordar del o el que tipo '.', y '-', /foo.bar/baz-bat har la en de o render() bien /fooen para normaliza estos hacia '-' cuando determina el nombre de la vista (view script name). /foo.bar/baz.bat, mtodo este resultar el render un '-'
accin
contiene
10
Programacin III
Ejemplos:
class MyController extends Zend_Controller_Action { public function fooAction() { // Hace el Render de my/foo.phtml $this->render();
2012
// Renders site.phtml hacia el segment 'page' de el objeto response // No se debe usar el sub-directorio 'my/' $this->render('site', 'page', true); }
11
Programacin III
public function bazBatAction() { // Renders my/baz-bat.phtml $this->render(); } }
2012
En este ltimo ejemplo podemos ver cmo al ejecutar el mtodo bazBatAction el sistema buscar una vista con el nombre baz-bat.phtml
12
Programacin III
Estructura Modular de Directorios
2012
La estructura de directorio modular permite separar nuestra aplicacin en diferentes mdulos, agregando un nivel ms a nuestro sistema, cada uno con su estructura MVC individual y re-usar estos a lo largo de nuestro sistema e incluso entre distintos proyectos. Cada mdulo es una sub-aplicacin independiente que tiene que tener la estructura la misma estructura de directorio MVC que vimos hasta ahora. Para ilustrar la nueva estructura de directorios con mdulos como "default" y "usuarios":
Proyecto-zf/ public/index.php application/ config/config.ini layouts/scripts/main.phtml modules/ default/ controllers/ IndexController.php FooController.php models/ views/ scripts/ index/ foo/ helpers/ filters/ usuarios/ controllers/ IndexController.php models/ views/ scripts/ index/ helpers/ filters/
13
Programacin III
2012
Observamos que dentro de cada modulo tenemos carpetas MVC (models, views, controllers), es decir, cada mdulo es un sub-aplicacin de nuestro gran sistema y tiene su estructura MVC interna con la misma estructura que el primer ejemplo "no modular" donde antes tenamos un subdirectorio que representaba el lugar donde guardar todos nuestros controllers, ahora tenemos un nivel mayor de abstraccin y de organizacin: el mdulo. Observemos las diferencias entre el Antes y el Despus:
Antes:
/proyecto/controller/action/par1/var1/par2/var2/
Ahora:
/proyecto/modulo/controller/action/par1/var1/par2/var2/ Lo que nos permite cambiar la estrategia de organizacin de nuestro proyecto:
Antes
/proyecto-zf/usuarios/ver/id/1
Ahora
/proyecto-zf/frontend/usuarios/ver/id/1 /proyecto-zf/admin/usuarios/ver/id/1
En el primer caso decidimos dividir nuestro sistema en dos mdulos, toda la la funcionalidad de "frontend" (zona pblica de nuestro sitio) y el "backend" (zona privada, que requiere autenticacin). En el segundo caso, decimos que en vez de "backend" tendremos un mdulo "admin" donde todas las operaciones de gestin debern estar ah, y esto podr reusarse entre sistemas (ya que la administracin de usuarios no cambiar y la mantendremos como un mdulo estndar).
14
Programacin III
2012
Cuando trabajamos con Mdulos en Zend Framework hay que especificar dentro del nombre de la clase controladora el NameSpace, que corresponde al nombre del modulo al cual pertenece, seguido de un guin bajo y el nombre del controlador:
Nombremodulo_NombrecontroladorController (NameSpace_NameController)
Para ilustrarlo en un ejemplo, tenemos una clase controladora Index dentro del modulo usuarios (nombre de archivo IndexController.php):
Nos fijamos que el nombre de la clase comienza con Usuarios, esta primera parte tiene que coincidir con el nombre de nuestro mdulo llamado "usuarios" (donde cada mdulo tiene su propio directorio dentro de la carpeta application/ de nuestro proyecto), luego el nombre de la clase se compone de un guin abajo _ seguido por el nombre del controlador IndexControler.
15
Programacin III
2012
IMPORTANTE: NO se agrega el prefijo namespacing en los controladores del mdulo default a menos que se configure en el application.ini con prefixDefaultModule=1 Hay que tener en cuenta que en el mdulo default, los controladores no necesitan un prefijo de nombre del modulo o namespacing, excepto que se configure la regla prefixDefaultModule=1 en el application.ini. As, en el ejemplo anterior, los controladores por defecto en el mdulo no es necesario un prefijo de 'Default_' - se trata simplemente con el nombre del controlador: IndexController, ErrorController 'y' FooController. No obstante el prefijo namespacing se utiliza en todos los otros mdulos.
anterior
ilustra
ejemplos
de
la
estructura
que
tienen el
que primer el
cuales
mantendr la el controlador
convencin que
que
segmento representar siempre al mdulo al cual debemos dirigirnos, el segundo segmento representar modulo accin y finalmente los parmetros de la peticin. deber contener (dentro del directorio controllers), luego es seguido por el nombre de la
16
Programacin III
En resumidas cuentas tomando el segundo ejemplo de url http://midominio.com/usuarios/index/ver/id/1 podemos decir que estamos
2012
accediendo mediante url al detalle del usuario 1, donde el mdulo es usuarios, el controlador es IndexController y la accin es verAction() y recibe por parmetro de peticin GET id=1.
Como pueden ver, crea un nuevo directorio llamado "modules" dentro del directorio application. Ah se crea el directorio para el mdulo "usuarios", "admin" y "default" con una estructura similar para el mdulo como hemos descrito anteriormente. Adems nos genera una nueva entrada de configuracin en el application.ini
17
Programacin III
creamos un mdulo default, se agrega lo siguiente en el .ini
2012
Hasta ahora crea solo directorios sin afectar la configuracin del sistema, pero, si
resources.frontController.params.prefixDefaultModule = "1" Ante ambas opciones, deshabilitarlo o no, preferimos mantener el criterio nico de que todo tenga un prefijo (esto lo podemos cambiar a justo del consumidor).
Sinnimos
Podemos definir nuestros valores booleanos de distintas formas: resources.frontController.params.prefixDefaultModule = "1" resources.frontController.params.prefixDefaultModule = 1 resources.frontController.params.prefixDefaultModule = true Con sta configuracin, que viene por defecto cuando trabajamos mdulos con Zend Tool, permite a las clases Controllers del mdulo Default agregar el prefijo del mdulo y funcionar de la misma forma: Default_IndexController y Default_ErrorController.
18
Programacin III
Configuracin bsica en un proyecto que usa mdulos
2012
Por defecto, cuando construimos nuestra aplicacin, esta no viene con mdulos, y la configuracin para encontrar los controllers es la siguiente
La sugerencia es que no usen un hbrido, si el proyecto es por defecto no-modular, trabajen siempre de esta forma, si es modular, saquen (borren) toda la estructura no-modular que cuelga de application (controllers, models, views) y de ahora en ms todo es un mdulo, hasta uno por defecto (default), as evitan problemas con la configuracin del sistema.
Cmo se vera nuestra estructura modular actual
Lo primer que habra que hacer es cambiar esta lnea por otra (en el application.ini): resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" ;resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" (esta linea la debemos comentar o la eliminar) Tambin tenemos las siguientes directivas para forzar el comportamiento por defecto o por si queremos cambiar el comportamiento por otro, cambiar el mdulo por defecto, cambiar las rutas, etc: resources.frontController.defaultModule = "default" resources.frontController.moduleControllerDirectoryName = "controllers" Y hay que dejar inicializado: resources.modules[] = "" Luego de crear los mdulos veremos la segunda parte de la configuracin (s, an falta para que todo funcione correctamente y detecte todos los componentes de forma automtica).
AUTOR: Fredy Cabrera Arias. Email: fredyc20@hotmail.com
19
Programacin III
Implementando Clases de Modelos en nuestros Mdulos en Zend
2012
Ahora vamos a implemenar y trabajar con Modelos en nuestro proyecto con estructura modular. El siguiente paso es crear una clase que herede Zend_Application_Module_Bootstrap en la raz de cada mdulo de nuestra aplicacin, esta clase nos permite tener un autoloader o cargador automtico de nuestras clases de modelo y ms adelante las clases de Formularios de Zend:
Una vez ms, el nombramiento es importante, el nombre de clase debe ser el {nombre del mdulo}_Bootstrap y debe extenderse Zend_Application_Module_Bootstrap. Se debe almacenar en un archivo llamado Bootstrap.php dentro de la raz del mdulo. Luego tenemos que aadir (o chequear que est) una lnea en application.ini para habilitar mdulos al final de la seccin [production] debajo de la regla moduleDirectory:
resources.modules[] = ""
De esta manera todas nuestras clases de modelo se cargaran automticamente mediante el Auto Loader de Zend, implcitamente (no lo vemos), sin necesidad de usar require_once ni dada por el estilo.
20
Programacin III
2012
Adems ser necesario nombrar nuestras clases de modelo que estn dentro de la carpeta models del mdulo de la siguiente forma: el nombre de clase debe ser el {nombre del mdulo}_Model_{nombre de la clase}
Entonces sobre el modulo usuarios segn imagen de arriba, nada nuevo y luego creamos la clase Bootstrap del mdulo usuarios para el Auto Loader de las clases del modelo:
El archivo lo nombramos como Bootstrap.php y lo guardamos dentro de la carpeta usuarios (raz del mdulo usuarios).
21
Programacin III
2012
Luego dentro de la carpeta models del mdulo usuarios, deberamos renombrar nuestras clases de modelo de la siguiente forma:
Y el DAO:
22
Programacin III
Lo que sucede internamente en la clase Bootstrap
Entrando ms en profundidad con la forma de trabajar con mdulos en Zend
2012
Por ejemplo, aunque no lo vemos, dentro de la clase Bootstrap, cuando trabajamos con mdulos en Zend Framework implcitamente y internamente maneja e invoca el Front Controller a travs de la clase Zend_Controller_Front en su forma modular implementado por el mtodo addModuleDirectory. Observando, nos damos cuenta de que Zend_Controller_Front agrega la raz del directorio modules el cual contendr todos los mdulos del sistema, mediante el mtodo addModuleDirectory. El mtodo addModuleDirectory() internamente implementa SPL DirectoryIterator y agrega los nombres directorio (dentro de la carpeta "modules") como mdulos o sub-sitios del sistema, lo que lo hace ms eficiente y menos lneas de cdigo por parte del cliente.
/** ETC ETC */ require_once 'Zend/Controller/Front.php'; $frontController = Zend_Controller_Front::getInstance(); $frontController->addModuleDirectory($rootPath . '/application/modules') ->throwExceptions(true)->dispatch();
23
Programacin III
2012
Nota: En el primer comando, 1 es el valor para "incluir el IndexAction" al crear el controlador. Nos crear el controlador PostController dentro del mdulo blog:
class Blog_PostController extends Zend_Controller_Action
Nos crear una accin registrarAction del controlador PostController dentro del mdulo blog:
cd C:\xampp\htdocs C:\xampp\htdocs>cd proyecto-zf C:\xampp\htdocs\proyecto-zf>zf create action registrar Post 1 blog
..\zf create action [action name] [controller name] 1 [module name] El nmero 1 es para crear un la vista de esta accin, si no asignamos el 1 no la crea. Para clases del modelo en un determinado mdulo:
zf create model Post -m blog
Nos crear una clase de modelo Post dentro del mdulo blog:
class Blog_Model_Post
24
Programacin III
oficial de Zend Framework: Zend Tool.
2012
Para ms informacin del uso de la lnea de comando de Zend Tool visitar el manual
En Resumen final
. Aunque pensemos "el proyecto ser pequeo y no crecer", generalmente ser todo lo contrario, sin contar que por cada que proyecto se que desarrollemos, por lo tanto
enfrentaremos constantemente
mdulos
repetirn,
pasaremos el resto de nuestros das programando mdulos de administracin de usuarios o reusaremos el mismo mdulo y disfrutaremos desarrollando solo nuevos e interesantes mdulos?
FIN.
25