martes, 26 de noviembre de 2013

Preparando datos para exportar a excel sobre CodeIgniter

En este artículo les voy a poner un ejemplo un poco más completo de cómo generar un excel con información existente en nuestra base de dato. Recomiendo leer primero el artículo “Importando y exportando excel sobre CodeIgniter”, donde presenté la biblioteca PHPExcel para importar y exportar ficheros de hojas de cálculo (excels).

En dicho artículo expliqué cómo instalar esta biblioteca, y cómo en mi caso creé una biblioteca que actúa como interfaz con la PHPExcel, con dos funciones “import” y “export”. En aquel entonces puse un ejemplo de código de exportar en el que solamente se ponía un valor en una celda. Modificando el código para hacerlo cíclicamente quedaría así (en $table vienen los datos sacados de la BD):

function export($table)
{
$objPHPExcel = new PHPExcel(); //creando un objeto excel
$objPHPExcel->getProperties()->setCreator("Yanoski")… //propiedades
$objPHPExcel->setActiveSheetIndex(0); //poniendo active hoja 1
$objPHPExcel->getActiveSheet()->setTitle("Hoja1"); //título de la hoja 1

//llenando celdas
$column = 0;
$row = 1;
foreach ($table as $record)
{
foreach ($record as $value)
{
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($column, $row, $value);
$column++;
}
$column = 0;
$row++;
}

//poniendo en negritas la fila de los títulos
$styleArray = array('font' => array('bold' => true));
$objPHPExcel->getActiveSheet()->getStyle('A1:Z1')-> applyFromArray($styleArray);

//poniendo columnas con tamaño auto según el contenido, asumiendo N como la última
for ($i = 'A'; $i<= 'N'; $i++)
$objPHPExcel->getActiveSheet()->getColumnDimension($i)->setAutoSize(true);

//código de exportar (ver artículo antes mencionado)
}

 


Como puedes ver todo se reduce a hacer un recorrido anidado al arreglo bidimensional $table, donde para cada fila ($record) accedo a cada valor de columna ($value) y lo inserto en la celda $column,$row, valores que voy incrementando convenientemente.

El uso desde un controlador sería sencillamente:

function export_data()   //en el controlador
{
$table = $this->my_model->get_table();
$this->load->library('excel_pdf_manager');
$this->excel_pdf_manager->export($table);
}

 


¿Dónde está el truco entonces? En el modelo. Es ahí donde realmente se formatea el arreglo bidimensional “$table” de forma que coincida con lo que quieras exportar. Los dos segmentos de código que puse arriba son genéricos para cualquier tabla de base de datos. Si quisieras exportar varias tablas de la BD llamarías la línea $table = $this->my_model->get_table() para cada modelo diferente.

Un ejemplo de conformación del arreglo $table sería como sigue, suponiendo una tabla de usuarios que contiene nombre, apellidos, correo electrónico y nombre de usuario, con su correspondiente modelo que llamaré “my_model” para que ajuste con el código anterior:

 

function get_table()   //en el modelo my_model
{
//datos a seleccionar
$this->db->select(users.ID, users.NAME, users.SURNAME, users.EMAIL, users.USERNAME');

//encabezados de las columnas
$headers = array('No', 'Nombre', 'Apellidos', 'Correo electrónico', 'Usuario');

$query = $this->db->get(' users ');
if ($query->num_rows > 0)
{
$table[] = $headers;
$i = 1;
foreach ($query->result() as $row)
{
$row->ID = $i;
$table [] = $row;
$i++;
}
return $table;
}
else
return null;
}

 


Aquí, dos cosas importantes: primero, hacer un select donde acomodas las columnas en el orden deseado y segundo, agregar una fila con los encabezados de las columnas que se pone como primera del arreglo “$table”, y es la fila que se pondrá en negritas.

Como detalle, para no mostrar los ID de los usuarios en el excel (que al final suele ser un autonumérico que actúa como llave de la tabla), he puesto en su lugar un número incremental que comienza en 1, así siempre saldrá en la primera columna del excel un ordinal, independientemente de cual sea el ID del usuario.

Hasta aquí cómo formatear los datos para exportarlos a un excel. En un próximo artículo mostraré el proceso inverso, de importar datos de un excel y verterlos en una tabla de la base de datos.

{ Leer Más }


viernes, 15 de noviembre de 2013

Como utilizar la plataforma WSO2, parte 1.

El objetivo de esta entrada es guiarlo a través del proceso del pensamiento para desarrollar una aplicación simple, en un primer momento usando PHP y MySQL y luego se explicara cómo usted puede rediseñar la arquitectura del sistema usando los productos de WSO2. Cómo y por qué ellos se usan. Se explica a alto nivel para que usted pueda seguirlo fácilmente. Luego de desarrollar la aplicación web sencilla, simularemos un cambio en los requisitos, que trae asociado ciertos problemas que usted tiene que considerar y cómo los productos de WSO2 proporcionan manera rica y fácil de resolver esos problemas [1].

Diseño de la aplicación

Antes de revisar la lista de productos de WSO2 y qué ellos pueden hacer, veamos algunos puntos sobre el diseño de la aplicación. Si usted es un diseñador web probablemente esté familiarizado con los Sistemas de Gestión de Contenido (CMS, por sus siglas en inglés: Content Management System) como por ejemplo: Wordpress/Drupal/Joomla… Si va a desarrollar un sitio web relativamente simple todo lo que usted tiene que hacer es crear un tema personalizado, poniendo el diseño, los logos y los colores correctos. Usted estará dedicando la mayoría de su tiempo en los aspectos de la interfaz visual de usuario y permitiendo que el CMS que usted está usando se encargue del proceso de adicionar/actualizar los contenidos del sitio de forma fácil.

Entonces hay sistemas en los cuales usted no quiere usar un Sistema de Gestión de Contenido. Este es el caso de las aplicaciones web simples, donde usar un CMS complica las cosas. Para esos casos, usted necesitaría que un lenguaje de programación simple del lado del servidor como PHP y un poco de HTML/CSS para darle completar la interfaz. La mayoría de aplicaciones web comienzan así. Usted comienza con un montón de páginas PHP y entonces cuando hay una necesidad de interactuar con la base de datos que usted escribe una clase "ligera" para la comunicación con la BD, luego instancia esa clase y lleva adelante las operaciones de acceso a datos. Entonces hay un rango entero de patrones en esta área que documenta las mejores prácticas en lo que se refiere a aplicaciones web en vías de desarrollo. MVC, FCP y otros. Entonces hay Frameworks que captan estas mejores prácticas y tratan de proveerle de abstracciones de alto nivel, como por ejemplo: CodeIgniter, CakePHP, ZendFramework, etc.

Así que si usted ha estado trabajando con este espacio durante algún tiempo, los servicios web podrían no tener sentido para usted. ¿Por qué necesita usted servicios web? Por ejemplo: ¿Por qué necesitaría usted algo exponga los datos de una base de datos como un servicio web? Usted diría que eso parece ridículo, cuando usted puede consultar la base de datos usando mysql_query().

“Para que necesito Servicios Web, yo puedo desarrollar una aplicación web mucho más simple usando PHP y MySQL!”

Usted probablemente definiría una arquitectura orientada a servicios Web cuando usted tiene que pensar acerca de la escalabilidad de su aplicación Web. Cuando eso ocurre usted necesita poder tratar partes diferentes del sistema independientemente, para lograr concentrarse en ciertos aspectos funcionales de la aplicación sin tener un impacto adverso en otras partes. Usted necesita diseñar su aplicación de forma que distribuya las funcionalidades en componentes diferentes. Luego usted necesita alguna forma de comunicarse con estos componentes distribuidos del sistema. Usar servicios Web es una de las soluciones a ese problema.

Veamos cómo dan vueltas los requisitos arriba en un proyecto típico del que usted podría tener para ocuparse. Primero podría ser una petición como, necesitamos tener una aplicación Web interna para proporcionarle a una experiencia agradable al usuario de todas nuestras funciones en el banco. Si usted es el encargado de esta tarea, necesitaría analizar detalladamente las funciones del banco y luego desarrollar una aplicación web que tenga todas estas funciones. Al principio podría ser que usted desarrolle un módulo simple como piloto, para ver si tiene éxito o no. Puede ser por ejemplo el módulo de cuentas de ahorros en el banco. Usted analizó los requisitos, uso una BD para transacciones y codifico el sitio usando PHP. Agradable, simple y funcional. Su aplicación piloto tiene una interfaz de usuario agradable, todos están felices y usted recibe la señal de seguir adelante para incluir más funciones. Como, el módulo de depósito fijo, el módulo de procesamiento de la tarjeta de crédito, módulo para tramitar prestamos, etcétera. Para este ejemplo si bien tomó un banco también se aplica a la amplia variedad de sistemas y las compañías.

“Pensar acerca de posibles extensiones a su aplicación, cuadro grande de como su aplicación será usada a largo plazo, cómo jugará junto con las cosas que usted ya tiene en su organización ahorrara gran cantidad de tiempo cuando usted se enfrente con tareas de integración en el futuro”

Desarrollando una aplicación sencilla.

Si usted ha pensado acerca de tener todos estos módulos inicialmente su trabajo es más fácil. En caso de que no usted necesita refactorizar el código y dividirlo en módulos. Usted codifica todo arriba, ajusta la BD, tiene secciones en la interfaz de usuario para todos los módulos y todo es progresivamente agradable. Puede ser que usted pone todos los módulos diferentes en una estructura como esta:

modules/
common/
fixed_deposit/
loans/
savings/
...

Además supongamos que tiene todas las funciones que son comunes para todos los módulos en la carpeta "commons". Ahora, si usted es realmente afortunado, la lista inicial de requisitos ya tenía el requisito de monitorear el sistema entero. Si usted es desafortunado el requisito de monitoreo surgirá cuando usted ha terminado con el sistema. Usted necesita de cierta forma poner en bitácora todas las operaciones que ocurren en el sistema y proveer una interfaz de usuario para monitorear, a la cual puedan acceder los administradores para ver cómo progresa el sistema, uso de datos, qué módulos están siendo utilizando, etcétera. Esto se convierte no sólo un asunto de nivel operacional, sino también en un asunto de la gerencia. Por ejemplo si la tasa de los depósitos fija está de baja, sería útil hacer un poco de mercadeo y ofertar negocios lucrativos para atraer más depósitos a plazo fijo. Usted no ha pensado acerca de monitoreo, ahora usted tiene que sumar código para poner en bitácora esta información en sus módulos. Luego cree una consola. Puede ser usted puede crear una "pestaña" separada para esta información en su interfaz de usuario que es visible sólo para los usuarios de tipo admin. Su aplicación podrá quedar algo así como lo siguiente.

clip_image002

Nuevos requisitos

Ojalá en este punto todas las personas fueron felices con las funcionalidades de la aplicación por los siguientes 10 años. Esto rara vez ocurre en la vida real. Lo que seguramente ocurriría es que cuando usted puso el sistema en operación toda clase de requisitos puede surgir. Veamos un ejemplo de estos:

· Necesitamos poder tener la interfaz de usuario para hacer monitoreo desde dispositivos iPad, todos las personas de operaciones deberían tener esta aplicación del iPad/iPhone para ver cómo funciona el sistema.

· Necesitamos tener un conjunto de reglas del negocio, que sean editables por los usuarios. Eso debe hacerse de forma simple, no editando código PHP, por ejemplo, cuando la tasa de interés se acorta.

· Necesitamos que la información de los depósitos fijos sea integrada para la aplicación nueva que construimos subcontratando a otra compañía.

· Necesitamos exponer un subconjunto de información acerca de los préstamos y los clientes para otros bancos para crear una lista negra de malos clientes.

· Necesitamos que una forma rápida se detecten transacciones fraudulentas en nuestras operaciones con tarjetas de crédito.

· Este sistema es genial, necesitamos integrarlo en los otros sistemas viejos que tenemos en nuestro banco. Tenemos algunos sistemas viejos que necesitamos para obtener datos y mostrarlos en este nuevo sitio Web.

· Vamos a usar un nuevo sistemas de procesamiento de cheques de otro banco, es por ello que necesitamos enviar todo nuestra información relacionada con los cheques al sistema, de forma segura a través de internet. Tenemos que asegurarnos que enviamos esta información en una forma fidedigna.

Análisis del problema

Si usted se pone a pensar, en un principio el sistema que usted desarrolló era simple, así que usaba PHP y una base de datos, pero ahora ha cambiado mucho y que ahora han surgido otras preocupaciones. Si por ejemplo, el módulo de cuentas de ahorro es usado en exceso y genera una gran cantidad de tráfico en el sistema, éste no sólo afecta ese módulo sino también al sistema entero. Si el sistema entero está apagado entonces ese es un impacto grande en el negocio. Eso no es lo que usted quiere. La aplicación PHP que consideramos inicialmente es monolítica. Entonces debería dividir esta aplicación en varias. Una opción para hacer esta división es usar XML-RPC para hacer llamadas de procedimiento remoto. Cuando usted divide su aplicación en varios pedazos y usa un montón de máquinas para alojarlos, allí surgen preocupaciones adicionales. Por ejemplo la seguridad. Usted no puede hablar entre los módulos con mensajes simples del texto porque la información que usted enviará de acá para allá es sensible. Estará relacionado con información del cliente, cuentas, información de la tarjeta de crédito etcétera. Así es que usted tiene que enviar las funciones que usted será el anfitrión de otras máquinas a través de HTTPs. Si usted necesita encriptación de datos, usted tiene que implementar en todos los componentes diferentes teniendo un gran número de duplicación de código. Usted tiene que mantener y sean cuidadoso con todo este código y probar cada componente. Luego usted tiene que volver a pensar acerca de monitorear la información. De la misma forma debe repensar el conjunto de reglas del negocio. Ahora usted se ha separado todo, entonces qué haría con ese módulo de cuentas de ahorros que atrajo una gran cantidad de tráfico? Usted puede tener un montón de servidores Apache corriendo el módulo de la cuenta de ahorros y hace un balanceador de carga entre esos. Si usted ha usado sesiones PHP, y si sus funciones confían en estado que ha almacenado en la sesión actual, entonces usted tiene que permitir copia de sesión entre los nodos o cambiar su código para hacerlos sin estado. Luego, cuando usted tiene todos estos cambios, usted tiene que probarlo correctamente para evitar incongruencias y lograr la exactitud funcional. Son un montón de cosas para considerar para una aplicación simple PHP.

Ahora usted entiende el problema y las complicaciones que todos los requisitos /factores adicionales introducirán, en la próxima entrada les explicaremos como usar plataforma WSO2 para resolver esta situación.

{ Leer Más }


IconIconIcon