Blog de Daniel Zegarra Rotating Header Image

PHP

Diseño de un administrador de reportes

Luego de dejar de postear por tanto tiempo queria volver publicando algo util, liberar algun proyecto o algo por el estilo, pero entre ver el siguiente capitulo de 24 y sanear un proyecto para ser publicado siempre salio ganando 24.

Lo siguiente no es tan interesante como lo que tenia planeado pero es de utilidad para quien necesita crear plantillas de reportes y esta a punto de empezar a indagar como hacerlo con PHP.

El requerimiento

Si por algun lado hay que empezar es por aqui. Se necesita lo siguiente:

  • Tener un catalogo de reportes
  • Elegir el formato en que quiero cada reporte (el mismo reporte pueda obtenerse en distintos formatos)
  • La cantidad de parametros que cada reporte necesita sea variable

El modelo de datos

El modelo de las tablas que necesitamos se limitan a lo siguiente.

Modelo de datos de un catalogo de reportes

Modelo de datos de un catalogo de reportes

Tenemos tres tablas. Una guarda el catalogo de reportes, la otra el catalogo de formatos de archivos y una tabla de relación que describe los formatos en que cada reporte se encuentra disponible.

Clases PHP

Acostumbro a trabajar consumiendo servicios. Me parece que es mas limpio si tengo bien separado la vista (en el cliente) de la lógica del negocio (en el servidor). Ademas, si no amarro la vista a los controladores puedo utilizar otros clientes (flash, java, etc) sin hacer cambios al código.

Como dije, trabajando como servicios tengo el servicio/clase llamado Sistema_Reporte que tiene los siguientes métodos:

  • Sistema_Reporte
    • run(codigo:string, formato:string, params:array)
      Ejecuta un reporte. recibe el código del reporte, el formato en que se requiere y los parámetros que necesita el reporte para hacer su trabajo.
    • getReporte(codigo:string)
      Entrega información disponible sobre un reporte (nombre, descripción, etc).
    • getFormats(codigo:string)
      Devuelve una matriz con los formatos que un reporte puede generar.
    • getParams(codigo:string)
      Entrega una matriz con los parámetros que recibe el reporte.
    • getParamValues(parametro:string)
      Algunos parametros son predefinidos (true, false, “si”, “no”) y otros serán IDs de un catalogo. Este método devuelve una matriz con los valores posibles que un parámetro puede tomar cuando estos no pertenecen a una tabla catalogo.
    • scan(ruta:string)
      Busca y registra los reportes encontrados en la ruta dada (relativa a la raíz del sistema).

Lo que este servicio hace es tan solo recibir la petición y direccionarlo al reporte especificado. Los reportes seran otras clases PHP que pueden estar ubicadas todas en un mismo directorio u ordenadas en otros directorios junto a otras clases de sus modulos, eso no importa ya que en nuestro modelo de datos estamos almacenando la ruta donde se encuentra el reporte. El metodo scan realizara una busqueda de reportes en el directorio especificado usando el siguiente algoritmo:

  • Abre el directorio y lista su contenido
  • Recorre el contenido tomando en cuenta solo los archivos con extension .php
  • Carga cada archivo php y revisa si la clase cargada es hija de Sistema_Reporte_Plantilla (todos los reportes deben heredar de esta clase para ser reconocidos como tal).
  • Si la clase cumple con los requisitos es registrada en la tabla de catálogos de reportes si es que aun no se encuentra allí.

En la clase Sistema_Reporte_Plantilla definimos los métodos que todo reporte debe tener:

  • Sistema_Reporte_Plantilla
    • getName()
      Entrega el nombre del reporte
    • getDescription()
      Entrega la descripcion del reporte
    • getFormats()
      Devuelve una matriz simple con los formatos que este reporte es capaz de generar (pdf, xml, csv)
    • getParams()
      Una matriz con los parametros que el reporte debe recibir
    • getParamValues(param)
      Devuelve una matriz con los valores posibles que un parámetro puede tomar cuando estos no pertenecen a una tabla catalogo.
    • run(format, params)
      Ejecuta el reporte.

Como ves, varios métodos del reporte son bastante similares a los del servicio. El servicio tan solo va a redireccionar la petición para que el usuario no tenga acceso directo a los reportes.

Descargar Modelo PHP para la administración de reportes
Descargar Modelo de datos para la administración de reportes

Ahora, para implementar los formatos, debes implementar metodos como _runPDF(params) o _runXLS(params) y generar los respectivos documentos. Dale un vistazo al codigo en el metodo run() de Sistema_Reporte_Plantilla para mas información.

Trabajar con PHP y Flex en el mismo Framework

Usar PDT 2.0 y Flash Builder 4.1 en el mismo framework es algo muy simple de lograr ya que ambos son plugins de Eclipse.

Los pasos para instalar PDT como plugin en una instalación previa de Eclipse se pueden encontrar aquí.

Advertencia: Flash Builder esta basado sobre la versión 3.4 de Eclipse (alias Ganymede), por lo tanto, se debe usar la versión 2.0 de PDT preparada para esta versión.

Segun la wiki de eclipse, estos son los pasos a seguir:

  1. Ir al menu Help > Software Updates… > Available Software > Manage Sites…
  2. Usando el boton Add, agregar la direccion http://download.eclipse.org/technology/dltk/updates-dev/1.0M4-PDT-2.0/
  3. Nuevamente, agrega la direccion http://download.eclipse.org/tools/pdt/updates/2.0/
  4. Presiona el boton Manage Sites y habilita el sitio de actualización de Ganymede (http://download.eclipse.org/releases/ganymede/) si es que no se encuentra habilitado. Los sitios habilitados son los marcados con el check.

    Activando el sitio de actualización de Ganymede

    Activando el sitio de actualización de Ganymede

  5. Ahora debes seleccionar que paquetes vas a instalar. Selecciona los siguientes paquetes:
    En DLTK / Dynamic Languages Toolkit / Seleccionar Dynamic Languages Toolkit - Core Frameworks

    Seleccionando DLTK Core
    Seleccionando DLTK Core


  6. En PDT Update Site / PDT SDK 2.0.1 / Seleccionar PDT Runtine Feature
    Seleccionando PDT

    Seleccionando PDT

    Nota: En las imagenes no tengo seleccionado el paquete descrito porque yo ya lo tengo instalado.

  7. Hecho esto, dale un clic en el botón Install.
  8. Acepta la condiciones y espera a que termine la instalación. Cuando te pida reiniciar Eclipse lo haces.

Suerte en tu proyecto!

    Error del garbage collector en distribuciones Linux que tienen a Debian como base

    Hay un bug inquietante en la instalación por defecto de PHP sobre servidores Debian y distribuciones que parten de él (como Ubuntu). Aparentemente el error aparece de forma aleatoria y con el siguiente mensaje:

    session_start() [function.session-start]: ps_files_cleanup_dir: opendir(/var/lib/php5) failed: Permission denied (13)

    Si vuelves a ejecutar refrescar la página el error ya no aparece. Con el tiempo llega a ser desesperante :P
    Bueno, si tu te has encontrado mas de una vez con este insecto te explico porque este error se dispara y como solucionarlo.

    Las sesiones de php son datos asociados a un cliente que visita el servidor. Cuando un visitante se conecta por primera vez al servidor este le asigna un codigo para identificar al mismo cliente durante su visita. El cliente entrega este codigo en cada comunicacion de tal forma que el servidor pueda reconocer al visitante y a su vez asociar informacion adicional a este codigo sin que el cliente lo sepa. Para entenderlo mas facilmente, el servidor le asigna al visitante un casillero numerado y le entrega el numero de la llave para reconocerlo mas tarde.
    En servidores web de produccion, que pueden tener miles de visitantes en tan solo unos minutos, almacenar los codigos de sesion en memoria resulta una mala idea, por lo que almacena todos estos codigos en el disco duro (quedando los mas nuevos o mas utilizados en la RAM del servidor).
    Cuando un visitante deja de comunicarse con el servidor por un largo tiempo, el servidor entiende que ese visitante ya se ha retirado y procede a anular su sesion, pero la informacion asociada a esta aun queda en el disco duro. PHP esta configurado para depurar regularmente las sesiones inactivas y asi no llenar el disco duro de basura.
    El problema aparece aqui. En los servidores Debian las sesiones son almacenadas en un directorio con permisos restringidos y estas son depuradas por el cron del sistema. Entonces, cuando PHP intenta realizar la depuracion se produce un error debido a que PHP no tiene los permisos suficientes sobre el directorio de sesiones.

    La solucion es muy simple: Decirle a PHP que no depure las sesiones. Dejar que cron lo haga.
    Para esto abre y modifica la siguiente linea en el archivo de configuracion de PHP (php.ini). En Ubuntu lo puedes encontrar usualmente en /etc/php5/apache2/php.ini. (no olvides abrirlo con permiso de escritura).

    $config['gc_probability'] = 1;

    No recuerdo el numero de linea ahora. Debe estar ubicado en la seccion de parametros de configuracion de sesiones.
    Cambia el valor de gc_probability a 0 para que PHP nunca depure las sesiones olvidadas.

    Guardar los cambios, reinicias apache y listo.

    La solucion fue hallada gracias a este hilo de discusión:
    http://forum.kohanaframework.org/discussion/565/garbage-collector-error-with-sessions-on-debian/p1

    Depurar Code Igniter con Eclipse y Zend Debugger

    Sin hacer cambios a Code Igniter no se puede. Aun si enable_query_strings esta definido en FALSE Code Igniter leera las variables que PDT pasa usando GET para que Zend Debugger conecte correctamente a la consola. Es una tonteria que Eclipse no nos permita NO pasar estas variables via GET. La solucion mas rapida pero no permanente es abrir el sitio que deseamos depurar en un browser aparte luego de tener a Eclipse esperando la conexion del depurador, pero es una salida molesta.

    Lo que hice fue decirle a Code Igniter que ignore ciertas variables entregadas via GET aprovechando los Hooks para no tocar el codigo base de CI.

    Para usar este hook sigue estos pasos:

    1. Descarga este archivo y guardalo en tu escritorio.
    2. Descomprime el contenido del archivo en el directorio application de tu instalacion de CI. Si ya tienes registrado algun hook entonces no reemplaces el archivo config/hooks.php. Agrega el contenido del archivo descargado tu archivo hooks.php actual.
    3. Asegurate que enable_hooks es igual a TRUE en el archivo config.php ubicado en CIroot/application/config/.

    Luego de hacer esto, intenta depurar tu aplicacion. Deberia correr sin problemas y ya no mostrar el error de que no se encuentra el controlador.

    Nota: La intencion de este articulo es solo compartir un archivo fuente para utilizar Zend Debugger con CI. Para informacion de la instalacion de Zend Debugger o su uso con Eclipse PDT  puedes… googlear.

    Descargar ZendDebugger&CI Hook

    Nace Kopernik, un sistema académico

    Logo de Kopernik

    Kopernik es el nombre clave del proyecto personal al que he dedicado mi tiempo estos ultimos 4 meses. Se trata de un sistema academico online desarrollado usando Flex, PHP (Zend Framework) y MySQL para su uso en instituciones educativas.

    Logo de Kopernik

    Logo de Kopernik. La idea era que el sistema sea usado por escolares y por lo tanto, no debia ser tan serio.

    Aprovechando la experiencia que adquiri trabajando y estudiando en universidades decidi crear desde cero un sistema que se ajustara a los requerimientos especiales que cada institucion pudiera tener. Como recien estaba empezando pense que mejor seria comenzar con modulos para colegios pero… resulta que he olvide como funcionan!

    Cuando estaba en el colegio no pensaba en procesos y en maneras de como mejorarlos como lo hago ahora. Por eso es que los modulos que ya he creado almacenan datos como el valor en creditos de cada asignatura o que permiten a un alumno matricularse en asignaturas distintas que el resto de sus companeros. De hecho el proceso que los administradores deben realizar para matricular de un alumno esta pensado usando los requerimientos universitarios o de institutos.

    En los colegios todos los alumnos llevan lo mismo. Solo hay dos opciones:

    • No te matriculas un año o…
    • Estas matriculado y llevas todas las asignaturas de tu año (con algunas excepciones como no asistir al curso de religion por solicitud de los padres).

    Es algo en lo que hay que trabajar.

    Por el momento me quedan algunos modulos importantes por desarrollar, como el control de evaluaciones, asistencias y materiales de clase.

    A continuacion explico algunos detalles del software y al final puedes encontrar un enlace para que lo puedas ver en accion.

    Caracteristicas generales

    • Es modular, de tal forma que sea facil reutilizar los modulos comunes y adecuarlos a lo que necesite.
    • Permite el trabajo colaborativo (tiempo real).
    • Solo hace uso del puerto 80. No es necesario habilitar la salida puertos adicionales en una red controlada.
    • El cliente solo necesita tener Adobe Flash instalado.
    • No requiere de licencias adicionales.
    • Es multiplataforma. Corre en Windows, Mac, Linux y cualquier otro sistema operativo que tenga soporte para Adobe Flash (talvez Android?)
    • Es multitarea. Las aplicaciones y modulos son cargados dentro de contenedores visibles como ventanas. Por lo tanto, no es necesario salir de un modulo para entrar a otro. Puedes tener varios modulos abiertos al mismo tiempo compartiendo el escritorio visible o minimizar algunos de ellos para usarlos luego.
    • Al instalarlo en un servidor web con un IP publico es accesible desde cualquier parte del mundo.
    • Control de acceso, a modulos y acciones, por grupos de usuarios. Se define que grupos tienen acceso a que modulos y las operaciones que realizan estos.
    • El sistema cuenta con algunas herramientas como el administrador de tareas (clic secundario sobre el fondo) y un explorador de directorios (del servidor).
    Tres aplicaciones abiertas: el explorador de alumnos, el explorador de archivos y el administrador de tareas

    Tres aplicaciones abiertas: el explorador de alumnos, el explorador de archivos y el administrador de tareas

    Tecnologias usadas

    • Flex 4: Empece el proyecto con la version 3 pero las nuevas caracteristicas (en especial la capacidad de trabajar con archivos localmente y el skining) resultaron muy tentadoras y tuve que hacer la migracion ya casi a mitad del proyecto (y acepto que no fue una decision muy inteligente. Me retraso todo el calendario pero espero haya valido la pena).
    • Zend Framework: Elegi este framework por la empresa que hay detras (Zend creadora de PHP) y por que ya me encuentro familiarizado con el. Ademas podia usar el paquete Zend_Amf para conectar Flex con el servidor. Tuve que migrar desde AMFPHP por lo que perdi el explorador de servicios y el control de acceso en cada clase. Realmente fue una migracion dura porque las clases del sistema (no academicas) ya estaban empezadas y funcionaban perfecto con AMFPHP. La gran ventaja de usar Zend_Amf es que tienes a tu disposicion todo el framework de Zend y ademas es el unico soporte para AMF que tiene la venia de Adobe sin ser desarrollado por Adobe (y la version actual de AMFPHP se encontraba abandonada en una version beta).
    • PHP: Como es obvio, por ser un lenguaje fantastico y porque casi todo servidor Apache lo tiene instalado.
    • MySQL: Necesitaba una base de datos transaccional y confiable. Que mejor que MySQL usada en la mayoria de servicios de hosting.

    Requisitos

    • Del lado del cliente
      • Flash Player 10.0.0 o una version mayor.
    • Del lado del servidor
      • PHP 5.2
      • Apache
      • MySQL

    Acceso a la demo

    Antes de ingresar por favor, lee las siguientes instrucciones:

    • Los datos de acceso se encuentran pre-escritos en los campos de texto, solo es cuestion de logearse.
    • El usuario de prueba pertenece al grupo de administradores, por lo que tendras acceso sin restriccion sobre los modulos y acciones que puedan estos realizar. Ten cuidado de eliminar aplicaciones, volver a registrarlas te puede resultar complicado si no sabes donde se encuentran almacenadas.
    • La falta de acentos se debe a que uso en teclado en ingles. Lo corregire muy pronto. Las fallas ortograficas se deben a mi falta de atencion a las clases de lengua (junto con la eficiencia del corrector ortografico de Word). Cuando tenga tiempo aplicare las correcciones necesarias.
    • La primera vez que cada aplicacion es solicitada puede demorarse unos segundos en cargarse (dependiendo de tu velocidad de salida a Internet). La aplicacion queda almacenada en la cache de tu navegador y es cargada de alli en las solicitudes posteriores.
    • Y por ultimo, te recuerdo que esta es una version en desarrollo y por ello puede tener errores. Si encuentras alguno, por favor ayudame a corregirlo comentandolo en este post. Gracias.

    Eso es todo. La direccion de acceso es la siguiente: http://kopernik.danielzegarra.net/. Espero tus comentarios.