Está en: » Artículos »

HMVC – Sistema modular en codeIgniter

HMVC – Sistema modular en codeIgniter

codeIgniter

HMVC es un «plugin» que nos permite programar módulos bajo el framework php codeigniter.

En un principio, la librería nos permite tener para cada módulo los controladores, modelos, vistas y librerías que necesitemos. Es una librería realmente potente ya que incluso nos permite cargar la salida de una función de un controlador en otro controlador.

Página y archivo de descarga:
https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc

Instalación:

Nota: Este método es válido para la versión 1.x de codeIgniter. Para las versiones 2.x utilizar el método explicado en la página del proyecto.

Copiamos todos los archivos (Controller.php, Modules.php y MY_Router.php) en la ruta application/libraries.

Una vez copiados dichos archivos, creamos una carpeta llamada modules dentro de application y en su interior crearemos los módulos necesarios. Cada módulo deberá tener varias carpetas: config, controllers, models, libraries y views.

Lógicamente, dentro de controllers, meteremos los controladores, así como en las respectivas carpetas.

Funcionamiento básico:

Si el nombre y clase del controlador tiene el mismo nombre que la carpeta del módulo, este se llamará automáticamente cuando accedamos sólo especificando el nombre del módulo (ej: http://miaplicacion/modulo ó http://miaplicacion/modulo/funcion). En caso contrario, para acceder a dicho controlador lo haríamos así: http://miaplicacion/modulo/clase/funcion

La carpeta config sólo nos servirá (de momento) para:

  • autoload.php: funcionamiento como el de codeigniter. Nos servirá para cargar automáticamente las librerías, modelos… necesarios para el módulo.
  • routes.php: funcionamiento como el de codeigniter. Nos servirá para hacer la configuración de rutas y redirecciones para dicho módulo.

Cuando llamamos a una librería, modelo o vista, por defecto se busca dentro de la carpeta del módulo y si no se encuentra las busca en application y si tampoco las encuenta busca ya en último lugar en system.

Métodos básicos de funcionamiento:

El funcionamiento de cada módulo es como si fuese una aplicación diferente para cada uno.

Podemos recojer la salida del controlador/vista de otro módulo y guardarla o mostrarla según nos convenga (sólo para la versión php5). Sería como llamar a una vista pasándole como tercer parámetro TRUE.

$retorno = modules::run('modulo/controlador/funcion/', $parametro1, $parametro2, $parametro...);

Podemos cargar también un controlador como si fuese una librería:

$this->load->module('modulo/controlador', $parametro1, $parametro2, $parametro...);
$retorno = $this->controlador->funcion();

Aunque lo carguemos como una librería, el controlador cargado seguirá llamando a sus modelos, vistas y demás como si fuese independiente.

Para modelos, vistas y librerías, el funcionamiento es tal cual a codeigniter y podemos acceder a otros módulos anteponiendo el nombre del módulo al archivo:

$this->load->model('modulo/modelo_model');

En la página de la librería podemos encontrar algunos módulos ya desarrollados como una galería fotográfica, captcha, etc…

Comentarios

  1. julian dice:

    Hola, muy interesante. Podrías comentarme a ver si esto de usar módulos sirve por ejemplo en el caso donde tengo un cuadro de login, y quiero que ese cuadro aparezca en el sidebar de una página? O por ejemplo si quisiera tener un cuadro de Carrito de Compra y hacerlo aparecer siempre en determinada posición de las páginas? Estoy vbien rumeado o no?

    • Tu ejemplo y pregunta me ha dejado un poco descolocado.
      No sé exáctamente si entiendo tu pregunta así que intentaré resumir un poco para qué sería esto.
      Para empezar, es php, lo cual es un lenguaje de programación de servidor.
      CodeIgniter es un framework para php y poco tiene que ver con formularios de HTML.

      Dicho esto, HMVC es una librería que nos aporta la funcionalidad de la programación modular en el framework codeIgniter (programación php en el lado del servidor).

      Esta librería nos permite hacer partes independientes de una aplicación, de forma que al unirlas, nos queda la aplicación funcional.

      Por ejemplo, un módulo podría ser una galería fotográfica.
      Imaginemos que tenemos un módulo de galería fotográfica que se llama galeria. Al entrar a http://miaplicacion.com/galeria estaríamos accediendo a la programación de dicho módulo. Osease, una función de ese módulo se ejecutaría y por ejemplo, leería las fotografías guardadas en una base de datos, comprobaría si están guardadas en el servidor y las maquetaría en html para enviárselo al navegador y que este las muestre.

      Espero haberte aclarado el dilema…
      Saludos

  2. Mariano dice:

    Miguel muchas gracias por compartir, el artículo está muy bueno. Lo encontré en el momento justo ya que planeo migrar mi aplicación para comenzar a utilizar una estructura modularizada.
    Saludos!

  3. Perico dice:

    Muy interesante la informacion

  4. Jashk dice:

    Excelente tutorial, ya me había iniciado en el manejo de la extensión, pero tenia algunos problema con la llamada a módulos.

  5. DooBie dice:

    Hola, hace unos dias que leí tu artículo y me puse ha probar «esto» de los modulos.
    Al principio se me antojo muy sencillo y rapido de ir ampliando una aplicación, pero me he encontrado con un problema que no doy con la solución.

    Tengo creados varios modulos, con controladores y vistas, pero sin ningun modulo específico para esos modulos. Ahora, queria crear un model para un modulo en concreto, y me dije ‘Pues lo pongo en la carpeta application/modules/moduloxxx/model/modulo_model.php’ y lo cargo como siempre ‘$this->load->model(‘Modulo_model’)’ Pero me salta siempre el error de No encuentra el fichero.
    En cambio, si lo muevo al directorio ‘application/models’ SI me lo carga sin problemas.

    Alguna idea?

    Muchas gracias, y buen articulo, por si no lo habia dicho 🙂

  6. Nicho dice:

    Interesante, pero hay algo que me gustaría que alguien me ayudara. ¿cómo puedo hacer para integrar otros scripts en code igniter?, por ejemplo, yo uso http://mibew.org/ como sistema de ayuda en linea. ¿cómo se integran ese tipo de aplicaciones CI? Sin CI sólo se instalan en una carpeta, pero no entiendo como hacer esto en CI ¿alguien sabe como?

    • Puedes hacerlo de muchas maneras. La más fácil y sencilla es seguir haciéndolo tal y como lo haces hasta ahora. Osease, lo metes en una carpeta y punto.

      Alguna que otra vez que he usado algún sistema integrado más grande y complejo que un simple script, en vez de meterlo con codeigniter, para evitar problemas hice un subdominio donde lo instalé y andando. Esto ya es decisión de cada uno.

      El integrarlo de una mejor forma suele conllevar un trabajo extra. Por ejemplo, lo podríamos integrar como un módulo con esta librería, pero habría que destripar gran parte del programa para implementar las vistas modelos y controladores en sus respectivos sitios, algo que no sería muy viable. Se podría hacer más liviano metiéndolo todo como si fuesen librerías de ese módulo y creando un controlador básico que reciba parámetros y se los pase, pero sería algo más «chapucero».

      En definitiva, te recomiendo que sigas usándolos como si no tuvieses codeIgniter cuando se trata de proyectos algo más grandes de unas simples librerías y que están en constante cambio/desarrollo.

      Saludos…

  7. Carlos dice:

    Miguel te felicito por el excelente tutorial todo está expuesto de forma muy clara.
    Tengo una consulta, tal vez alguien pueda ayudarme…

    Intento utilizar codeigniter con una base de datos en un servidor SQL Server y no logro hacer la conexión utilizando el driver de la siguiente manera:

    $db[‘default’][‘dbdriver’] = «mssql»;

    Alguien puede ayudarme con esto?

    • @Carlos ¿Has instalado la extensión de MSSQL de php en tu servidor? En openSuse viene a llamarse php5-mssql
      También tienes que establecer la opción de autenticación mediante usuario y contraseña en el servidor MSSQL. No sé si se puede establecer por permisos de máquina, pero yo no tuve problema con user/psw.

      Te recomiendo también estas 2 líneas para establecer la codificación con la misma (que fue uno de los peores puntos de trabajar con MSSQL).

      $db['default']['char_set'] = "ISO-8859-1";
      $db['default']['dbcollat'] = "Latin1_general_CI_AI";
      

      Saludos y suerte

  8. Carlos dice:

    Miguel antes que nada muchas gracias por tu rápida respuesta, no tuve tiempo de ponerme con este tema hasta hoy.
    No he instalado la extensión que comentas de MSSQL aún, estoy trabajando sobre un servidor LAMPP de modo que no estoy del todo seguro que pueda instalar una extensión como esa sin instalar un apache por ejemplo.
    Conoces alguna manera de instalar esa extensión sobre un server LAMPP?
    Una vez mas gracias por tu aporte. Saludos.

    • No hay que reinstalar apache. Como te indico en el comentario anterior, es una extensión de php.
      No entiendo lo que me quieres decir con LAMPP. ¿Es algún paquete todo en uno? Porque si es una instalación manual sobre un GNU/Linux, lo más normal es que tengas algún repositorio disponible para instalar dicha extensión de php.

      Saludos…

  9. webpass dice:

    Hola Miguel, vos sabes que fui al wiki para descargar el Modulo y me encuentro que lo han sacado de ahi. Sigo el link del nuevo repositorio y cuando intento descargar lo ultimo encuentro que no solo hay un controller, Mudules y My_Routes sino que hay caonfig, y otras tantas librerias mas.
    Es necesario poner todo?
    Es mas en config MX_Config extiende de CI_Config.. yo no tengo CI_Config, solo config.
    Me das una mano… gracias

  10. Eduardo dice:

    Hola Miguel, creo tener la misma pregunta que Julian.
    Yo con esto puedo tener corriendo un modulo por ejemplo en el sidebar?
    Yo quiero que en mi barra siempre se muestre el formulario de login de Tank_auth siempre en cuando no se haya iniciado una session y en caso contrario mostrar el nombre del usuario.

    • Como ya comenté, el sistema modular lo que nos permite es separar por módulos la aplicación. Por ejemplo, podemos tener un módulo de usuarios, otro de noticias, otro de blog, etc…
      Cada módulo tiene sus controladores, vistas, modelos, librerías… Es como si cada módulo fuese un codeigniter independiente (aunque se pueda acceder a determinadas partes de otro módulo).

      Para lo que me dices, sólo necesitarías comprobar con un if si ha iniciado sesión y poner el contenido necesario en cada caso. Como recomendación, haz una vista para cuando ha iniciado sesión y otra para cuando no lo ha hecho. Con la comprobación del if ya cargas una u otra vista y así lo tienes más organizado.

      Un saludo

  11. Willy dice:

    Hola Miguel muy bueno el articulo, felicidades , queria preguntarte como hacer para que cada aplicacion sea realmente independiente, o sea quiero asignarle un dominio diferente a cada aplicacion y desde la principal administrarlas. si podes orientarme en este mi proyecto te lo agradesco viejo gracias

    • Como siempre, hay varias maneras de hacerlo.

      Una manera que se me ocurre que puedes hacer un controlador (fuera de los módulos, en CI nativo) de forma que recoja todas las peticiones y el sea el que cargue el módulo adecuado acorde al nombre de dominio. Esto presenta el problema de que ya no funcionan las rutas de codeigniter como tal, sino que tendremos que implementarlas en este controlador.
      Este método tendría lógica si se usase para todos los sitios el mismo código cambiando sólo pequeñas partes (imágenes, estilos o lo que sea).

      Otra forma sería haciéndo redirecciones a nivel de htaccess.

      Hay muchas formas y cada una tiene sus ventajas e inconvenientes.

      Si van a ser aplicaciones totalmente independientes que no compartan cierto código contínuamente, te recomiendo que saques la carpeta application, coloques el resto en algún lugar accesible y para cada dominio, estableces un hosting normal y colocas la carpeta application junto con el archivo index.php (cambiando las rutas por las correctas, claro está). De esta forma tienes centralizado todo el core y cada aplicación independiente (bastante útil para actualizaciones de seguridad y demás).

  12. Willy dice:

    Miguel, gracias por tu respuesta, y estudiare tus sugerencias.
    segui asi suerte.

  13. albert dice:

    Hola Miguel,
    gran explicación, te felicito fenónemo. Quisiera proponer una pregunta, a ver que opinan. Estoy desarrollando un pequeño CMS (la idea sería parecerse en funcionalidad a PyroCMS o Ionize). Tengo una base de datos con ítems, secciones y contenido (la típica estructura, creo). El problema viene al tener un menú y clicar en el, que se tienen que mostrar las diferentes secciones del item (podrian ser secciones tipo texto, fotos, mapa, etc, que seria el atributo descripcion de la tabla contenido donde se guardaria el texto, la ruta de la foto o las coordenadas del mapa, para entendernos y situaros). Así pues tengo que seleccionar todas las secciones de ese ítem y mostrar su contenido (en el controlador sección, coger las secciones del item, redireccionar a otro controlador (contenido), para mostrar los contenidos de esas secciones). La pregunta es, que opciones hay para hacer esto? con un redirect es suficiente? Es chapuza? Seria conveniente proponerme desarrollar la aplicación con módulos para poder utilizar lo que explicas en tu post?
    Espero tu respuesta des de la voz de la experiencia y el buen uso de CI.
    Felicitaciones otra vez, un saludo.

    • Sinceramente, no terminé de comprender para qué necesitas hacer las redirecciones.
      Puedes trabajar sobre un controlador que haga todo el trabajo con una funcón que reciba como parámetro el id del item y retorne todo el resultado.
      O puedes tener una función específica en cada controlador de cada sección la cual retorne estos datos.
      Hay muchas formas, pero la adecuadava en función de las necesidades del proyecto en sí ya que cada una tiene sus ventajas/inconvenientes.

      La separación en módulos es más organizativo y estructural que otra cosa. Yo lo recomiendo siempre que se pretenda hacer un sitio con un cierto flujo de datos y secciones.

      Por cierto, gracias por los alagos pero no soy más que otro «programador» que aporta algo de conocimiento a la fuente de donde obtuvo tan grandioso material…

      Saludos

      • Albert dice:

        Ya lo solucioné, tenías razón.
        El problema que tenía es que tenía un array de secciones y que cada seccion tenía que mostrar su contenido, y pensaba que tenía que redireccionar a otro controlador una vez tenía los datos, pero al final en el controlador he recibido los datos del modelo y le he llamado otra funcion para mostrar el contenido (pensaba que no se podía, soy novatillo! ).
        Si no te molesta y te parece bien te iré preguntando cosillas de CI porque me van saliendo dudas que no se como resolver o no se si las resuelvo bien; si no quieres que las ponga en este post dime si puedo enviartelas al mail o donde quieras.
        Los alagos son normales cuando se aporta información precisa y clara. Creo que es la primera vez que escribo en un foro, normalmente buscaba lo que necesitaba y no comentaba nada!

  14. albert dice:

    Hola Miguel,
    si en un formulario no recibo las variables post, es problema del htaccess? Que código de htaccess se tiene que poner para recibirlas?
    Yo ahora tengo esto:
    AddDefaultCharset UTF-8
    RewriteEngine on
    RewriteCond $1 !^(index\.php|img|js|css)
    RewriteRule ^(.*)$ index.php/$1 [L]
    Gracias!

  15. Camila dice:

    Hola Miguel,
    No se si el tema todavía lo estés revisando, de todas maneras dejare mi pregunta.
    En realidad estoy algo desesperada, ya que hace como 1 mes que estoy entrando en el mundo de codeigniter. hiendo al grano, intento conectarme a sql server (Carlos lo mencionó anteriormente), estoy trabajando con wamp y seguí estos pasos: http://forum.ragezone.com/f724/get-wamp-work-mssql-673301/
    mmm.. en database

    $db['sql_server']['hostname'] = 'localhost/SQLEXPRESS';
    $db['sql_server']['username'] = 'sa';
    $db['sql_server']['password'] = '123';
    $db['sql_server']['database'] = 'db_sqlserver';
    $db['sql_server']['dbdriver'] = 'mssql';
    $db['sql_server']['dbprefix'] = '';
    $db['sql_server']['pconnect'] = TRUE;
    $db['sql_server']['db_debug'] = TRUE;
    $db['sql_server']['cache_on'] = FALSE;
    $db['sql_server']['cachedir'] = '';
    $db['sql_server']['char_set'] = 'utf8';
    $db['sql_server']['dbcollat'] = 'utf8_general_ci';
    $db['sql_server']['swap_pre'] = '';
    $db['sql_server']['autoinit'] = TRUE;
    $db['sql_server']['stricton'] = FALSE;

    y no funciona..>.< el error que me da es:

    Ocurrió un error con la base de datos

    No se ha podido conectar al servidor de base de datos usando la configuración suministrada.

    Filename: C:\wamp\www\login\system\database\DB_driver.php

    Line Number: 124

    y los datos están bien…se te ocurre que me faltará?

    • Tienes que revisar más a fondo los logs que te da el problema y a parte, preguntar en foros más especializados o al creador del artículo que seguiste.
      Por lo demás, no te debería influir HMVC en tu conexión con la base de datos.

  16. Camila dice:

    Miguel, gracias por responder…pero finalmente pude arreglar mi problema, leyendo varios post (no recuerdo cual) salio por ahi, que:

    $db['sql_server']['hostname'] = 'localhost/SQLEXPRESS';

    Se debía colocar:

    $db['sql_server']['hostname'] = 'nombreEquipo/SQLEXPRESS';

    Ahi pude conectar..:), te agradezco de todas manera tu respuesta:)

  17. ABRKOF dice:

    Hola a todos… kiero saber si me pueden ayudar con un pekeñito sistema ke estoy desarrollando en condeigniter… la cuestion eske ya tengo el sistema para hacer la fase de pruebas… login… acceso a formularios con sus cruds… pero digamos al cerrar sesion y le doy atras… la pagina donde yo estaba anterior mente keda registrada y me muestra todos sus datos… eso en seguridad esta muy malo… puesto ke si estoy haciendo una transaccion monetaria o dejo algo no se… cualkier dato expuesto al usuario pues seria muy perjudicial para el otro usuario… ya ke el nuevo usuario veria todo lo ke el otro hizo… eso es lo ke kiero ke desaparezca… la verdad en php puro… osea haciendolo todo a pie pues es mas facil… pero con la utilizacion de este framework no se como se haria… lo ke kiero eske no aloje las poginas luego cerrada la sesion… ke no las muestre despues luego de cerrada la sesion…
    es mi proyecto en la U y pues estoy en fecha limite… noxe como hacer jijiji… si tienen alguna idea se los agradeceria mucho… solo he logrado hacer ke si no esta logeado pues ke no tenga acceso… por lo demas no se como hacer lo ke les expongo

  18. Pablo dice:

    Como incorporar tank auth en HMVC??

  19. Jess dice:

    Qué tal excelente post . Una duda estoy implentando un hook para verificar que tenga los permisos para acceder a cada módulo mi duda es donde coloco el hook en la raíz o en en módulo? Lo intente poner en una carpeta hooks dentro del módulo , pero no me funciona . Me funciona para la raíz pero algunos módulos no requieren el hook

Deje su comentario

Previsualización de comentario
  1. Anónimo dice:





Pings para esta entrada