Tabla de contenidos
gvHIDRA, a parte de proporcionar un core (igep) en el que se encuentran todas las funcionalidades extensibles del framework, proporciona una estructura inicial de proyecto. Para empezar cualquier aplicación con la herramienta, debemos bajar la plantilla inicial de proyecto correspondiente a la versión con la que vamos a trabajar. Esta plantilla se encuentra en el paquete de la propia versión en la ubicación doc/plantilla-gvHidra.zip. Antes de descomprimir hay que advertir que los ficheros están codificados en ISO-8859-1 o ISO-8859-15, por lo que hay que tener precaución con usar algún editor que respete estas codificaciones. Otro detalle a tener en cuenta es que la plantilla contiene ejemplos que deben ser borrados.
Una vez descomprimida encontramos una estructura básica de aplicación a partir de la cual construiremos nuestra aplicación. De esta estructura destacamos:
gvHidraConfig.inc.xml: donde añadir las conexiones a bases de datos, código de la aplicación y versión,...
actions/principal/AppMainWindow.php: donde añadiremos las listas y ventanas de selección particulares, log, ...
mensajes.php: donde añadir mensajes particulares de la aplicación.
include/menuModulos.xml: define el menu principal de la aplicación. Hay que modificarlo con las acciones propias de la aplicación. También podemos usar ciertas opciones predefinidas.
include/menuAdministracion.xml: definimos opciones de la 2ª columna de la pantalla principal. Siguen las mismas normas que en menuModulos.xml.
include/menuHerramientas.xml: definimos opciones de la 3ª columna de la pantalla principal. Siguen las mismas normas que en menuModulos.xml.
include/include.php: donde, conforme vayamos creando clases de negocio las iremos incluyendo. Los includes de ficheros "action/*" se pueden borrar.
include/mappings.php: en la función ComponentesMap, excepto la llamada al constructor del padre, todo se puede borrar.
templates_c: directorio de compilación de plantillas. El usuario web tiene que tener permisos de escritura.
A esta estructura tenemos que añadirle el core del framework correspondiente (directorio igep) que también se distribuye con la versión de gvHIDRA.
La configuración básica de una aplicación gvHIDRA se concentra en los ficheros de configuración gvHidraConfig.xml. En este apartado explicaremos tanto la distribución de estos ficheros entre la arquitectura del framework como las posibilidades que ofrece. Finalmente, veremos un ejemplo de un fichero tal y como se utiliza en una aplicación.
Aunque en algunos apartados se detalla mucha información, lo realmente importante es entender el concepto general y la configuración mínima que tenemos que realizar para crear una aplicación (fichero a nivel de aplicación).
La configuración básica de una aplicación gvHIDRA se concentra en los ficheros de configuración gvHidraConfig.xml. Estos ficheros de configuración (todos con el nombre mencionado) aparecerán en tres capas, una a nivel del framework (igep), otra a nivel de custom (personalización de la organización) y finalmente, a nivel de aplicación. Por ejemplo, supongamos una aplicación realizada con gvHidra que se denomine "factur" y se encuentra dentro de la organización "tecnimap" los ficheros de configuración se ubicarán en las estructura de directorios como sigue:
factur/igep/gvHidraConfig.inc.xml
factur/igep/custom/tecnimap/gvHidraConfig.inc.xml
factur/gvHidraConfig.inc.xml
La semántica de los ficheros XML vendrá determinada a través de la DTD embebida en ellos, para que a los encargados de editar y mantener esos ficheros (programadores y responsables de la aplicación correspondiente) les sea sencillo saber si los mismos están correctamente confeccionados. La finalidad de que existan distintos ficheros de configuración, es establecer una especialización jerárquica, que permita personalizar opciones de gvHidra a distintos niveles.
Nivel de framework (en el ejemplo anterior, fichero factur/igep/gvHidraConfig.inc.xml): En este fichero se establecerán configuraciones generales del framework y OBLIGATORIAMENTE se establecerá el directorio de customización (customDirName).
Nivel de organización (personalización o custom, en el ejemplo anterior es el fichero factur/igep/custom/tecnimap/gvHidraConfig.inc.xml): Es un fichero que incluirá elementos propios de la organización (DSNs de BDs, acciones particulares de validación, ...), además en este fichero podrá redefinirse cualquier valor establecido en el fichero a nivel de Framework.
Nivel de aplicación (en el ejemplo anterior, fichero factur/gvHidraConfig.inc.xml): Utilizado para incluir configuración específica de una aplicación (DSNs, versión...), como último en el nivel jerárquico, a través de él se podrá redefinir cualquier valor establecido en el fichero a nivel de organización y de framework.
Es decir, en última instancia, las opciones que prevalecen son las que aparecen en el fichero de configuración de la aplicación. Posteriormente y a través del objeto global (el singleton ConfigFramework) podremos leer y sobrescribir dinámicamente dichas opciones.
A continuación vamos a detallar cada una de las opciones disponibles para la confección de los ficheros. Muchas de ellas no se deberán modificar al iniciar una aplicación, pero convien que las conozcamos:
applicationName: De carácter obligatorio, establece el nombre (código) de la aplicación. La asignación normal será en la ubicación correspondiente a la aplicación.
appVersion: Versión de la aplicación. La asignación normal será en la ubicación correspondiente al nivel de aplicación.
customTitle: En la barra superior de color azul, a la izquierda de la fecha y hora, se ha reservado un pequeño espacio para poder incluir un texto personalizado. La asignación se realiza a través de este parámetro.
customDirName: Establece el nombre del directorio de customización. En dicho directorio aparecen modificaciones o extensiones que van a ser comunes a una organización. Por ejemplo, las extensiones del Framework propias de la CIT (ventanas de selección, listas predefinidas, DSNs de consulta a BDs internas...) se ubicarán dentro de un directorio "cit.gva.es". La asignación de este valor será en el fichero a nivel de framework o de la aplicación, no pudiéndose hacer a nivel de la organización ni de forma dinámica usando el objeto global.
temporalDir: Permite indicar una carpeta para la creación de algunos temporales relacionados con la seguridad (fichero de sesión, ...). La asignación de este valor será sólo en el fichero a nivel de la aplicación, no pudiéndose hacer a nivel de framework ni de la organización ni de forma dinámica usando el objeto global.
templatesCompilationDir: Establece el directorio que utilizará Smarty para compilar las TPL. Si se está desarrollando algún plugin del framework, es interesante cambiar la configuración para que cada "usuario" tenga su carpeta y no haya un efecto caché mientras se desarrolla.
reloadMappings: Indica si se quiere recargar el fichero de mappings en cada petición. Por defecto está habilitado, aunque habria que deshabilitarlo para entornos donde el fichero de mappings no se modifica. Este parámetro se puede definir a cualquier nivel.
smartyCompileCheck: Indica si smarty tiene que comprobar si se ha modificado alguna plantilla y en caso afirmativo recargarla. Se puede definir en cualquiera de los tres xml, aunque no de forma dinámica.
logSettings: Establece el nivel de detalle de los registros de auditoría.
queryMode: Modo de interrogar las BDs, vease los filtros de búsqueda.
DSNZone: Encerrada en esta etiqueta aparecerá toda la información relativa a las fuentes de datos. La etiqueta podrá aparecer en las tres ubicaciones, por ejemplo: a nivel de framework para establecer la configuración del DSN del log, a nivel de organización para incluir DSNs propios de la organización (listas y ventanas de selección propias, validaciones...) y finalmente, a nivel de aplicación, donde situaremos la información de conexión propia.
dbDSN: Agrupa los parámetros de conexión a un SGBD relacional. Las etiquetas están inspiradas en PEAR:MDB2.
dbHost: Host o IP donde se encuentra el servicio. En el caso de conexiónes a Oracle mediante OCI (cuando sgbd vale oracle, oci, oci8) se utilizará para establecer la entrada en tnsnames. Para los otros casos de oracle (thin y oracle-thin) debemos especificar dbHost, dbPort y dbDatabase.
dbPort: Puerto donde escucha el SGBD.
dbDatabase: Base de datos a la que nos conectamos.
dbUser: Usuario.
dbPassword: Contraseña.
wsDSN: La fuente de datos es un servicio web.
uriWSDL: URI donde puede localizarse el fichero WSDL que define el servicio web SOAP.
wsUser: Usuario
wsPassword: Contraseña
Después de esta abalancha de parámetros, para comprender mejor su utilización vamos a ver un ejemplo real de un fichero a nivel de aplicación:
<gvHidraConfig> ··· <applicationName>factur</applicationName> <appVersion>1.0.0</appVersion> <!-- si es a nivel de organizacion, puede estar definido en el del custom--> <logSettings status='LOG_ALL' dnsRef='gvh_dsn_log' /> <DSNZone> <dbDSN id='gvh_dsn_log' sgbd='postgres'> <dbHost>cualquiera.coput.gva.es</dbHost> <dbPort>5432</dbPort> <dbDatabase>saturno</dbDatabase> <dbUser>logUser</dbUser> <dbPassword>melogeo</dbPassword> </dbDSN> <dbDSN id='ora-tns' sgbd='oracle'> <dbHost>tns-entry</dbHost> <dbUser>usuario</dbUser> <dbPassword>pwd</dbPassword> </dbDSN> <dbDSN id='ora-thin' sgbd='oracle-thin'> <dbHost>bd.coput.gva.es</dbHost> <dbPort>1521</dbPort> <dbDatabase>sid</dbDatabase> <dbUser>usuario</dbUser> <dbPassword>pwd</dbPassword> </dbDSN> <wsDSN id='g_ws'> <wsUser>wsuser</wsUser> <wsPassword>wspwd</wsPassword> </wsDSN> </DSNZone> ··· </gvHidraConfig>
Como nota, debemos saber que podemos acceder con la clase ConfigFramework a los metodos get/set para acceder/modificar estas propiedades. Ejemplo:
$conf = ConfigFramework::getConfig(); $cod_apli = $conf->getApplicationName(); $conf->setCustomTitle('Tu título');
Hay que tener en cuenta que, dependiendo del entorno en el que estemos trabajando, puede que nos interese habilitar/deshabilitar ciertos parámetros de configuración. Típicamente, nos encontramos con el caso de entornos de producción, en estos casos interesa:
smartyCompileCheck: en producción es interesante tener este valor a false para optimizar el rendimiento de nuestras aplicaciones. Con ellos aprovecharemos la cache del Smarty.
reloadMappings: en producción es interesante tener este valor a false para evitar que recarge el catálogo de acciones en cada ejecución. Esto aumentará la velocidad de nuestras aplicaciones.
Esta clase es propia de cada proyecto, y se crea para inicializar caracteristicas generales de la aplicación. Como se ha explicado en los puntos anteriores, supone entre otras cosas, la carga dinámica de parámetros de configuración. Este fichero no es obligatorio; aunque en la práctica podemos decir que en el 100% de los casos es necesario.
Es importante tener en cuenta que, por su definición, sólo se ejecutará la primera vez que entremos en la aplicación. A continuación describimos algunas de las funcionalidades que nos permite hacer.
Básicamente, la carga dinámica. Si no definimos esta clase, los valores de configuración seran los definidos en los ficheros gvHidraConfig.inc.xml. Sin embargo, cuando necesitamos fijar alguno de estos parámetros en funcion de situaciones más complejas (información propia al usuario, al estado de la aplicación, al entorno de ejecución, ...), podemos usar los 'setters' de los parámetros para cambiar la configuración. Por ejemplo:
$conf = ConfigFramework::getConfig(); // aumentar nivel de log en desarrollo if ($estoyEnDesarrollo()) { // Cuando estamos en desarrollo registramos todos los movimientos $conf->setLogStatus(LOG_ALL); } // mostrar cierta informacion solo para perfil informaticos if (IgepSession::dameRol()=='R_INFORMATICOS') $conf->setCustomTitle('perfil-admin');
Cuando queremos hacer algo al empezar o terminar la aplicacion, la definición de esta clase nos permite acceder a estas acciones específicas. Vease el ejemplo en el punto "Código de la lógica de negocio". Para ello hay que añadir al mappings.php las siguientes líneas:
//Accion que se ejecuta al abrir la aplicacion $this->_AddMapping('abrirAplicacion', 'AppMainWindow'); $this->_AddForward('abrirAplicacion', 'gvHidraOpenApp', 'index.php?view=igep/views/aplicacion.php'); $this->_AddForward('abrirAplicacion', 'gvHidraCloseApp', 'index.php?view=igep/views/gvHidraCloseApp.php'); //Accion que se ejecuta al cerrar $this->_AddMapping('cerrarAplicacion', 'AppMainWindow'); $this->_AddForward('cerrarAplicacion', 'gvHidraCloseApp', 'index.php?view=igep/views/gvHidraCloseApp.php');
Para poder añadir listas (gvHidraList) o ventanas de seleccion (gvHidraSelecctionWindow) a nuestras aplicaciones necesitamos definirlas en el constructor de esta clase. Hay más información al respecto en el apartado de las listas
Si se usan informaciones globales que no se tienen disponibles a través del patrón singleton, podemos usar los métodos guardaVariableGlobal y dameVariableGlobal de IgepSession para manejarlas. El constructor de AppMainWindow es el sitio natural donde inicializar los valores, para luego poder recuperarlos en cualquier parte de la aplicación.
En este apartado vamos a citar algunas de las recomendaciones que, aunque no son de obligado cumplimiento, si que nos pueden ser de gran utilidad ya que vienen recogidas de la experiencia de los desarrolladores.
gvHIDRA utiliza una serie de proyectos por debajo para implementar la arquitectura MVC y representar la vista. Concretamente phrame y a smarty. Estos dos proyectos tienen una serie de parámetros de configuración que interesa tener en cuenta a la hora de trabajar en una aplicación. Lógicamente no es lo mismo estar en un entorno de desarrollo que en un entorno de explotación, por ello conviene tener en cuenta cuando estamos en uno u otro para realizar la configuración adecuada.
Todo ello se resume en estas dos propiedades del fichero gvHidraConf.xml a nivel de aplicación:
reloadMappings: esta propiedad que admite valores boolenos(true|false), indica si el framework debe recargar el mapeo de acciones en cada iteracción. Esto es conveniente en desarrollo, aunque ralentiza la ejecución. En explotación esta propiedad debe estar a false.
smartyCompileCheck: esta propiedad que admite valores boolenos(true|false), indica si regeneramos la plantilla (tpl) en cada interacción. En fase de desarrollo, como cambiamos constantemente la pantalla, es conveniente que esté a true. En explotación esta propiedad debe estar a false para mejorar el rendimiento.
El framework está en la codificación ISO-8859-1 (Latin1), por lo que el IDE que utilicemos para programar, debemos configurarlo en esta codificación. Con ello evitaremos problemas con caracteres especiales. En el caso de las conexiones a BBDD, si utilizamos Oracle, debemos de definir la variable de entorno NLS_LANG=Spanish_Spain.WE8ISO8859P. En el resto no es necesario hacer nada.
Es una buena práctica, crear carpetas dentro de los directorios actions, views y plantillas con los nombres de los módulos de la aplicación. Con esta sencilla separación física de los ficheros, será más sencillo localizar la información de un caso de uso concreto. Un ejemplo de módulos podría ser:
Mantenimiento expedientes
Tablas maestras
Listados
...
Aunque no es obligatorio, siempre conviene tener una guía para horientar a nuestros usuarios en el uso de las aplicaciones. Esta opción, abre una ventana emergente donde se explica el funcionamiento general de los distintos elementos de las aplicaciones realizadas con gvHIDRA. Se recomienda colocar en el menú de herramientas o de administración.
<opcion titulo="Manual Guía de Estilo" descripcion="Manual de introducción a Guía de Estilo" url="igep/doc/manualIGEP/indice/indice.html" imagen="menu/24.gif" />
También hay disponible una guía rápida:
<opcion titulo="Guía Rápida" descripcion="Guía rápida uso de aplicaciones" url="igep/custom/cit.gva.es/doc/guiaRapida/guiaRapidaUsoAplicacionesCIT.pdf" abrirVentana='true' imagen="menu/24.gif" />
De forma automática, el framework ofrece la posibilidad de crear un menu Acerca de que muestra el acrónimo y el nombre de la aplicación así como sus versiones. Para mostrarlo debemos añadir la siguente opción de menú:
<opcion titulo="Acerca de..." url="about" imagen="menu/24.gif" />
Al pulsar sobre esta opción el usario se encontrará con una pantalla similar a esta:
Es una de las utilidades del framework básicas. Con el siguiente código se abre una ventana emergente para consultar la información generada por la aplicación. Se recomienda colocar en el menú de herramientas, y con control de acceso para que no esté accesible a usuarios.
<opcion titulo="Log Aplicación" descripcion="Log Aplicación" url="igep/_debugger.php" abrirVentana="true" imagen="menu/mensajes.gif"> <controlAcceso> ... </controlAcceso> </opcion>
Más adelante explicaremos en profundidad el log del framework y sus posibilidades a modo de depuración y auditoría.
Además del propio debugger de la aplicación interesa instalarse alguna herramienta que nos permita ver el frame oculto del código HTML generado. Esto se debe a que, internamente, gvHIDRA trabaja con un frame que no es visible por el usuario, lo cual le permite, por ejemplo, realizar acciones sin recargar la página. Por todo ello, para la depuración, es fundamental instalar una herramienta que nos permita ver el contenido de dicho frame; en el caso de errores críticos, puede que sólo aparezcan en él.
Nosotros utilizamos el complemento de firefox HTML Validator, pero existen otras posibilidades. Aquí tenéis una imagen del plugin.
El framework tiene un sistema de persistencia de las clases manejadoras que permite, de forma transparente para el programador, mantener "viva" la instancia de una clase hasta que se cierre la ventana. Esto significa que, cuando se cierra una ventana y cuando se cierra la aplicación (a través de los iconos indicados), se borrarán de la sesión los datos de dicha clase. Es importante tener esto en cuenta porque si tenemos un error en el constructor, deberemos borrar la sesión antes de volver a ejecutar, ya que el constructor sólo se ejecuta la primera vez que entras a la ventana.
Se trata de una utilidad. Abre una ventana emergente donde podemos obtener el hash de una cadena (usados en servidores de web services). Se recomienda colocar en el menú de herramientas, y con control de acceso para que no esté accesible a usuarios.
<opcion titulo="Proteger datos usando hash" descripcion="Proteger datos usando hash" url="igep/include/igep_utils/protectdata.php" abrirVentana="true" imagen="menu/seguridad.gif"> <controlAcceso> ... </controlAcceso> </opcion>