Portal AJAX con el CMS PHP CodeIgniter y ExtJS

Portal AJAX con el CMS PHP CodeIgniter y ExtJS

Recientemente he tenido que revisar un portal realizado con el gestor de contenidos ( CMS ) y framework PHP: CodeIgniter, como base y ExtJS como framework JavaScript para proporcionar los servicios de datos por medio del prototipo JSON. Dividiré el análisis en tres partes: Framework JavaScript, Base de datos y Aplicaciones PHP.

Framework JavaScript: Ext JS

Había encontrado algunos problemas, por ejemplo, si entramos en la web con un dominio sin las tres uves dobles, al estar configurado para el dominio con ellas, los ficheros fuente no eran bien referenciados y había errores por todas partes. Estos bugs se corrigieron fácilmente, pero hay que entender o bien por experiencia, por intuición o por inteligencia, de dónde vienen dichos problemas para poder solucionarlos.

El sistema a analizar tiene un directorio privado, sin embargo se ha de crear una lógica de roles de usuario y ficheros de acceso restringido o bien con PHP o bien con .htaccess para que ningún usuario no autorizado a una zona pueda acceder a la información privada que reside en regiones que no le pertenecen.

El primer error que encontré en el diseño de la aplicación no

estaba en la base de datos, ya que el diseño de entidad relación está correcto, dentro de lo que cabe , y he visto verdaderas barbaridades por ahí…como decía, el primer error es la propia interfaz de usuario, mirad este vídeo:

Comentarios:

Para empezar apenas hay espacio en la ventana al no poder quitarnos de encima los componentes que estorban para rellenar datos, hace falta añadir controles con los que ocultar las zonas laterales, como se hace con la zona inferior. Los botones de menú no se ocultan al pinchar sobre una opción y no se muestran mensajes de «cargando» ni información pertinente, de hecho si ocurre algún error este es ininteligible. El chat no funcionaba, aún así se está sincronizando contínuamente por lo que el ancho de banda que consume es considerable. Internamente no hay una verdadera lógica de programación para los roles de administrador representada en JavaScript, es decir, se mezclan los prototipos de todos los usuarios:usuario invitado, cliente, admin,etc. por lo que cualquier usuario que conociera las url o fuera un poco inteligente podría encontrar un mecanismo de operar con la base de datos de la web usando la ingeniería inversa y consultas en los scripts de JSON que además ya vienen en ficheros .js.

Más allá de mi opinión

Sobre si la decisión de usar Ext JS u otro framework JavaScript como JQuery la dejo a elección del programador porque realmente depende de cómo de cómodo te sientas escrbiendo las piezas del puzzle del portal, en este caso está bastante bien porque se utiliza Firebug para depurar PHP con una consola de estado de Ext JS. Aunque es un poco raro mezclar opensource con freesource, es una buena manera de construir un portal complejo, eso sí, siempre que tengamos claro qué es lo que queremos construir…

Un ejemplo de implementación

Veamos un ejemplo de cómo por medio de una vista del modelo MVC de CodeIgniter, construimos contenido JavaScript para alimentar una acción lanzada desde el portal, la bienvenida:
var Center = Ext.extend(Ext.util.Observable, {
constructor	: function(ui) {
this.ui = ui;
 
this.panel = new Ext.TabPanel({
	title		: 'Center',
        region		: 'center',
	activeTab	: 0,
	autoDestroy	: false,
	items: [
	{
	  title:'Bienvenido',
	  closable	: false,
	  bodyStyle	:'font-family:sans-serif;font-size:12px;',
	  html		:'[contenido]'
    }]
});
}
});

En [contenido] debemos colocar el contenido del componente, por ejemplo, un iframe o cualquier otro elemento html que queramos…

Por ejemplo, para añadir  una pestaña con lo que se debe mostrar de un cliente una opción es la siguiente:

MisClientes = Ext.extend(Ext.Panel,{
    // Prototype Defaults
    propA: 1,
	title: 'Mis Clientes',
	closable	: true,
	iconCls: 'icon-mis-clientes-tab',
 
    initComponent: function(){
        // Called during component initialization
this.fields =[
{name:'cliente', type:'string'},
{name:'nombre', type:'string'},
{name:'email', type:'string'}
];
this.storeGrid = new Ext.data.Store({
 reader:new Ext.data.JsonReader({
  idProperty:'cliente',
  totalProperty:'totalCount',
  root:'rows',
  fields: this.fields
 }),
proxy:new Ext.data.HttpProxy(
 {url: BASE_URL +
  'asignarEntrenador/load_clientes_asig'}),
 baseParams:{entrenador:USER_LOGGED},
 remoteSort:true
});
//...etc.

De esta forma hemos encapsulado toda la información de un cliente junto con los widgets que lo representan ,en un único objeto, sin embargo todo el trabajo no acaba ahí, hay que escribir también los prototipos de respuesta para cada una de las acciones, que devolverán otros widgets, elementos de sincronización, alimentadores de datos o datastores, etc. A partir de aquí hay que sumergirse en el mundo del framework Ext JS, y…
Para terminar con el análisis de la sección del framework JavaScript, las plantillas que este utiliza se han guardado separadas del motor PHP (framework CodeIgniter), esto es buena idea porque se puede actualizar fácilmente y además podríamos crear un subdominio para aligerar la carga de la web de forma que realizara las peticiones de todo el contenido JS en paralelo desde el navegador.

Base de datos

Hablando de la base de datos, como había comentado antes, no está nada mal, aquí vemos el diagrama de entidad/relación, los usuarios son la tabla principal del sistema y alrededor de ella se construye todo el conjunto de entidades que abordan las necesidades del cliente, el administrador ,etc.

Correcciones a aplicar sobre la base de datos: se debe modificar el campo usuario de la tabla de usuarios para que sea único, algunos tipos de datos son demasiado grandes para la información que almacenan, hay que tener en cuenta que cuando el número de usuarios crece y con esto también los datos asociados, la sinergía de nuestro servidor de base de datos depende tanto del número de transacciones como del volumen de estas y si estamos usando un framework que realiza una petición de todos los datos de un usuario para mostrarlos con datos asociados por cada prototipo de entidad, el volumen de estos datos genera un considerable tamaño de ancho de banda que puede ralentizar la aplicación. Para esto se construyen consultas que se guardan como vistas y otras consultas avanzadas como las que se pueden realizar con PL/SQL.

En principio la base de datos no necesitaba más cambios, sólo quedaba analizar si estaba preparada para la expansión, es decir, si era escalable, para probarlo, me ví en la tesitura de añadir una tabla que almacenara información relacionada con archivos compartidos entre usuarios de distintos privilegios, y en este caso no tuve ningún problema con la base de datos sino con el siguiente punto ,ya que la lógica de programación no estaba terminada, no había diferenciación fuerte entre roles y aquí fué donde me llevé la gran sorpresa de toda la jerarquía.

Framework PHP : CodeIgniter

El lector seguramente ,como programador sabrá que los tipados fuertes (objetos) siempre son adecuados para embeber información de un usuario, de modo que con una simple lectura de una propiedad de la instancia de la clase usuario->tipo sabremos qué tipo de usuario es…claro, la cosa se complica al tener que replicar la información en un framework como Ext JS, sabemos que podemos encriptar la información pero finalmente,para acometer una acción delicada debemos realizar la comprobación del nivel de privilegios de un usuario por duplicado: en el framework JS y en el framework PHP.

Llegados al punto en que la jerarquía MVC se abría ante mí, todo parecía el paraíso, hay modelos,

class Usuarios extends Model {
    public function __construct()
    {
        parent::Model(); // Call the Model constructor
		$this->table_usuarios = 'usuarios';
		$this->table_usuarios_tipo = 'usuarios_tipo';
		$this->table_session = 'dasm_sessions';
		//$this->load->library('firephp');
    }
 
	//TODO: Comprobar que es un admin
	function crear(){
//etc.

qué es eso «TODO: Comprobar que es un admin»?…sigamos analizando, hay controladores…bien!

class User extends Controller {
 
    public function __construct()
    {
        parent::Controller();
		if (function_exists('force_ssl')) force_ssl();
		$this->load->library('session'); 
 //iniciar libreria de sesiones
		$this->load->library('firephp'); //FIREBUG
		$this->firephp->log("force shhl");
    }
	public function index(){
		$this->login();
	}
 
    public function login()
    {
        if ($this->my_usession->logged_in)
        {
	 $this->firephp->log("login");
//....

es un poco extraño, -me digo para mí- , ahora es todo coser y cantar, pero no…me parece que el programador se acaba de ventilar toda la jerarquía de roles…además, no hay vistas asociadas,ni controladores en los hooks de C.I., pánico…todas las acciones se realizan por real decreto de…llamadas incoherentes dentro de ficheros javascript?…ok, he muerto, ahora he de renacer a la realidad…¿cómo arreglaríais este desastre organizativo?,

Opción básica A: operar sobre la chapuza a sabiendas de que cada vez se enredará más y más el código

Opción B sólo para los valientes: intentar arreglar toda la jerarquía de clases, añadir los hooks, la lógica de roles y rezar para que no haya ninguna incoherencia…en peores batallas hemos estado

Opción C: la gran elegida por el público y aclamada por todos los directores de proyecto solidarios con la causa del programador medio : rehacer el sistema, esta vez BIEN HECHO.

Conclusiones: ¿Cómo no habría sido un fracaso este proyecto antes de llegar a mis manos?

  • Empezando por el diseño del wireframe completo: diseñar la interfaz de usuario aplicación
  • Analizando las tareas a realizar con diagramas de casos de uso donde se vean reflejadas las acciones de cada rol de usuario
  • Construyendo el diagrama de clases en UML o en papel, me da igual pero dibujar, pintad, y luego desarrollar, eso es lo primero, proyectar lo que queremos , si queremos un pato proyectaremos un fantástico sistema de patos y eso es lo que obtendremos, si no sabemos lo que queremos, lo más probable es que el patito feo odiado por toda la familia tampoco lo quiera pagar el cliente
Y quizás, usar otra tecnología…¿Google? :’D

Artículos relacionados:

  1. Jean Oropeza dice:

    Saludos amigo estoy necesitando los servicios de un programador. Necesito realizar un sistema de informacion sencillo en codeigniter. Ayuda por favor

  2. Delpho dice:

    Hola Soy ingeniero informatico y estoy incursionando en Code Igniter y ExtJS, quisiera encontrar ejercicios resueltos para tenerlos de referencia o una guía de ejercicios a desarrollar para coger habilidades
    Saludos

    • Juan Belón dice:

      Lo mejor que puedes hacer sería crear un proyecto real, haz una web en CI e EJS en una semana para tí, para un amigo, o para un cliente, aprende lo que necesites de tutoriales que hay en la red bastantes, al final es lo que tienes que hacer de cara a la realidad, construir lo que te piden y darle un precio

 

footer
jbelon © | sitemap.xml