scieee AI-readable full text Open interactive document viewer

Intranet para la explotación de productos software

Belda Moscardó, Enrique

Full text

Intranet para la explotación de productos software Proyecto Final de Carrera Presentado por: Enrique Belda Moscardó Dirigido por: Tutor de la empresa : Carlos Fernández Martínez Tutor UPV : Eva Vallada Regalado 24/03/2011 Índice 1 Introducción ..................................................................................................................................... 5 2 Estudio de un CMS ......................................................................................................................... 7 2.1 Análisis de CMS ................................................................................................................ 8 2.2 Estudio en detalle de CMS ................................................................................................ 9 3 Joomla ........................................................................................................................................... 17 3.1 Estructura ...................................................................................................................... 17 3.2 Instalación ...................................................................................................................... 22 4 Desarrollo ....................................................................................................................................... 23 4.1 Los Requisitos ................................................................................................................. 23 4.1.1 Requisitos del back-end .................................................................................... 23 4.1.2 Requisitos del front-end ................................................................................... 24 4.2 Análisis ............................................................................................................................ 25 4.3 El diseño .......................................................................................................................... 27 4.4 La implementación .......................................................................................................... 28 4.5 Codificación ................................................................................................................... 31 4.5.1 Back-end ........................................................................................................... 32 4.5.2 Front-end .......................................................................................................... 43 4.5.3 Módulos ............................................................................................................ 47 5 Casos de uso ................................................................................................................................... 51 5.1 Dar de alta un producto ................................................................................................... 51 5.2 Dar de alta una versión .................................................................................................... 52 5.3 Dar de alta un cliente ....................................................................................................... 54 5.4 Dar de alta una licencia ................................................................................................... 54 6 Conclusiones .................................................................................................................................. 55 7 Bibliografía .................................................................................................................................... 57 8 Anexos ............................................................................................................................................ 60 Anexo 1: .../views/productos/tmpl/default.php ............................................................................. 60 Anexo 2: .../views/producto/tmpl/form.php .................................................................................. 61 Anexo 3: .../components/com_soa/controller.php ......................................................................... 63 Anexo 4: .../components/com_soa/helper.php .............................................................................. 65 Índice de figuras Figura 1. Interfaz administrativa Typo3 ............................................................................................. 10 Figura 2. Interfaz administrativa WordPress ...................................................................................... 11 Figura 3. Interfaz administrativa Drupal ............................................................................................ 13 Figura 4. Interfaz administrativa de Joomla....................................................................................... 14 Figura 5. Previsualización de una plantilla. ....................................................................................... 18 Figura 6. Gestor de extensiones, sección componentes. .................................................................... 19 Figura 7. Gestor de módulos. ............................................................................................................. 20 Figura 8. Gestor de plugins ................................................................................................................ 21 Figura 9. Modelo relacional de las tablas añadidas a la base de datos original ................................. 27 Figura 10. Componente SOA. Jerarquía de archivos y carpetas en el paquete de instalación. ......... 31 Figura 11. Código fuente del fichero .../administrator/com_soa/soa.php ......................................... 33 Figura 12. Codigo fuente del fichero .../controllers/producto.php ..................................................... 35 Figura 13. Modelo productos. Fichero .../models/productos.php ...................................................... 36 Figura 14. Modelo producto. Fichero .../models/producto.php ......................................................... 37 Figura 15. Jerarquía de carpetas y archivos de la vista ...................................................................... 39 Figura 16. Vista productos. Fichero .../views/productos/view.html.php. ........................................... 40 Figura 17. Vista producto. Fichero .../views/producto/view.html.php ............................................... 41 Figura 18. Módulo logo_soa. Fichero …/modules/mod_logo_soa.................................................... 48 Figura 19. Módulo menu_soa. Fichero …/modules/mod_menu_soa. ............................................... 49 Figura 20.Módulo publi_soa.Fichero …/modules/mod_publi_soa/mod_publi_soa.php ................... 50 Figura 21. Interfaz alta producto. ....................................................................................................... 52 Figura 22. Interfaz alta versión. ......................................................................................................... 53 Índice de Tablas Tabla 1. Características de los CMS .................................................................................................. 15 5 1 Introducción Desde que empezó a comercializarse el software como producto informático, las empresas siempre han buscado la forma de poder ofrecer un buen soporte técnico a sus clientes, ya que la facilidad para aprender a utilizar un producto, así como la rapidez a la hora de resolver problemas derivados de su uso, a menudo han marcado el éxito o fracaso del producto en sí. En anteriores décadas era frecuente que la única ayuda que dispusiera un usuario era un simple manual de uso y una línea telefónica para casos más concretos. Con el tiempo, el desarrollo de Internet y el incremento de usuarios con acceso a la red de redes ha facilitado el modo en el que las empresas desarrolladoras de software ofrecen soporte para sus productos, en forma de actualizaciones para resolver fallos en la programación, foros donde los usuarios expertos o desarrolladores ayudan a los usuarios iniciados, vídeos con casos de uso, chats, etc... Actualmente muchas de las empresas dedicadas a la venta y/o explotación de productos software disponen de una página web en la que ponen a disposición de sus clientes una serie de elementos diversos para poder prestarles ayuda de forma personalizada, estamos hablando del concepto de Intranet. Una Intranet es una red de computadores utilizada en una organización de carácter privado que a través de Internet pone a disposición de los usuarios una serie de servicios y recursos informáticos. Dependiendo del propósito de la Intranet y el tamaño de la organización el número de computadores puede variar de un sólo servidor a cientos de computadores y/o servidores. La disponibilidad de los recursos depende del tipo de usuario, al que se le concederán una serie de privilegios dependiendo de la función que deba desempeñar dicho usuario en la Intranet. El acceso a los recursos suele estar jerarquizado y organizado en grupos, existiendo un grupo de usuarios cuyos privilegios le dan permiso de acceso a todos los recursos, limitándose estos privilegios según se descienden niveles de la jerarquía. Para poder acceder a la Intranet los usuarios tienen que estar registrados y deben identificarse mediante un nombre de usuario y una contraseña. El presente Proyecto Final de Carrera (PFC) se realiza en el marco de prácticas en empresa. La empresa en cuestión es el Instituto Tecnológico de Informática (ITI), en adelante la empresa, que tiene su sede en la Universidad Politécnica de Valencia. Uno de los grupos de investigación la empresa, más concretamente, el grupo de Sistemas de Optimización Aplicada (SOA) tiene en explotación una serie de productos en un conjunto importante de clientes. La creciente cantidad de clientes conlleva un importante trabajo en lo que respecta al mantenimiento del producto y de los clientes. Por ello, dicho departamento plantea la creación de una Intranet en la que centralizar diversos aspectos como los documentos de ayuda, soporte técnico, preguntas frecuentes, actualizaciones, etc... Esta centralización de servicios tendrá que tener en cuenta la diversidad de licencias y contratos que tenga cada uno de los clientes. 6 El objetivo de este PFC se centra en el desarrollo de una Intranet haciendo uso de un Content Management System (CMS) para dar soporte a un conjunto de clientes que tengan contratados unos productos software. El soporte se prestará de diversas maneras y siempre teniendo en cuenta la diversidad de usuarios. La Intranet estará centralizada en un servidor y los clientes serán usuarios que deben agruparse en función de los productos que tengan contratados. Un CMS es una herramienta software que facilita el desarrollo de una página web proporcionando una interfaz para administrar los recursos, lo que puede ser una gran ayuda a la hora de desarrollar una Intranet. La estructura que vamos a seguir es la siguiente. En la Sección 2 se realizará un estudio de los CMS existentes actualmente. En la Sección 3 se presentará en detalle el CMS elegido para poder desarrollar la Intranet. Proseguiremos con la Sección 4 en el que presentaremos los requisitos que requiere la Intranet así como las distintas modificaciones que tendrán que llevarse a cabo sobre el CMS. En la Sección 5 se presentan unos casos de uso de la Intranet. Por último, en la Sección se comentan las conclusiones. 7 2 Estudio de un CMS Un CMS es un sistema de gestión de contenidos, esto es una herramienta que sirve para la creación y administración de contenidos generalmente de páginas web. La función principal es separar el diseño de los contenidos que generalmente son administrados a través de una o varias bases de datos alojadas en el mismo servidor del CMS. Esto se hace a través de una interfaz administrativa también llamada back-end mediante la cual un usuario con privilegios de administrador gestiona los contenidos que serán mostrados en el sitio web o front-end. En la última década han surgido una gran cantidad de CMS. Las características varían mucho de uno a otro y algunos son más adecuados para ciertas funciones. Podemos distinguir algunos tipos de CMS según ciertas características:  Según el lenguaje de programación empleado: Existen dos tipos de lenguajes de programación orientados a Internet: los que se ejecutan en el servidor que aloja la página y los que son interpretados por el navegador y se ejecutan en el cliente que la visita. Los CMS deben usar ambos lenguajes para adquirir una funcionalidad completa. Del lado del servidor destacamos como lenguajes más usados en los CMS Java, PHP, ASP.NET y Python entre otros. Del lado del cliente destacamos HTML, JavaScript y AJAX.  Según la propiedad del código fuente: Los CMS, así como cualquier producto software pueden publicarse mediante una licencia privativa o una licencia libre. Las licencias libres permiten que nuevos desarrolladores modifiquen el código fuente original de la aplicación con la idea de mejorar o ampliar el producto. Entre este tipo de licencias destaca principalmente la licencia GPL (General Public License)[1]. Las licencias privativas por su parte se caracterizan por no entregar el código fuente junto con la aplicación y por tanto sólo permite modificaciones al código original por parte de su autor. Su función principalmente es mantener la dependencia del cliente con el desarrollador.  Según el tipo de uso o funcionalidades: Los CMS también podemos agruparlos en función de la finalidad con la que fue diseñado. Entre ellos los usos mas comunes son:  Plataformas generales: Sin un fin específico, pensados para facilitar la construcción de cualquier tipo de página web.  Blogs: pensados para páginas personales.  Foros: pensados para compartir opiniones.  Wikis: pensados para el desarrollo colaborativo.  E-learning: plataforma para contenidos de enseñanza on-line.  E-commerce: plataforma de gestión de usuarios, catálogo, compras y pagos.  Publicaciones digitales: pensados para periódicos.  Difusión de contenido multimedia. 8 2.1 Análisis de CMS La empresa tiene la intención de poner en marcha una Intranet y para ello será necesario un CMS que pueda dar permiso de acceso a los recursos de la Intranet de forma individual. También, se espera del CMS que sea flexible y se pueda aumentar su funcionalidad mediante la instalación de extensiones. Todo esto debe poder hacerse de forma fácil e intuitiva. Por tanto será necesario hacer un análisis de los distintos CMS disponibles para ver cuales reúnen las siguientes características:  Código abierto Esto es importante, los CMS de código abierto tienen la posibilidad de desarrollar extensiones personalizadas que cumplan aquellas funciones que el propio CMS no aporta. Estas extensiones bien pueden ser desarrolladas por la comunidad de usuarios y/o desarrolladores del CMS o bien podemos desarrollarlas nosotros mismos si no hay alguna extensión ya hecha que satisfaga nuestros requisitos. Además, la mayoría son a coste cero con lo que se ahorra en el coste anual de las licencias.  Comunidad de usuarios Una amplia comunidad de usuarios es de suma importancia para un CMS de código abierto. Gracias a disponer de una comunidad con miles de desarrolladores algunos CMS son mejorados constantemente, se publican nuevas versiones cada pocos meses y además los usuarios crean sus propias extensiones que luego ponen a disposición del resto y el CMS gana mucha flexibilidad y funcionalidad. En nuestro CMS va a ser necesario instalar algunas extensiones y se espera programar lo mínimo posible, así que es conveniente que el CMS goce de popularidad y de una amplia comunidad de usuarios que nos brinden una buena gama de extensiones. También se requiere que haya amplia documentación sobre el código del CMS y sobre como desarrollar nuevas extensiones, esto puede ser crucial en un momento dado si no se encuentran extensiones que nos aporten toda la funcionalidad que deseamos. Administración de usuarios Es necesario que el CMS pueda dar de alta nuevos usuarios y almacenar la información básica sobre ellos. También sería deseable que se puedan crear grupos a los que vincular los usuarios que compartan ciertas características. Control de acceso Puesto que la Intranet debe personalizar los contenidos según el usuario que se conecte es necesario que el CMS permita un control de acceso granulado, es decir, que los permisos deben poder concederse a los usuarios sobre un conjunto de recursos o sobre recursos individuales según el grupo al que pertenezca cada usuario. 9  Amigable Es necesario que el CMS sea fácil de aprender a usar y que disponga de una buena documentación para que el administrador aprenda con rapidez las tareas que debe desempeñar para el correcto funcionamiento de la página. Es necesario por tanto analizar su usabilidad web[2].  Publicidad Además de dar servicios a los clientes para los productos que tienen contratados se plantea la posibilidad de captar nuevos clientes a través de la Intranet. Para este cometido sería interesante que el CMS diera facilidades para mostrar en la web publicidad sobre los nuevos productos que se publiquen.  Facilidad de instalación Sería interesante que el CMS se pueda instalar de manera fácil e intuitiva a través de una interfaz de usuario. Algunos CMS pueden instalarse a través del navegador siguiendo una serie de pasos bien explicados. Debemos encontrar un CMS cuya instalación y configuración no cuesten demasiado tiempo. 2.2 Estudio en detalle de CMS Después de analizar las características importantes que debe tener un CMS para desarrollar una Intranet se ha hecho una búsqueda a través de la web para encontrar los CMS que mejor se ajustan. Tras la búsqueda hemos seleccionado para el PFC cuatro CMS que podrían servir para el desarrollo de la Intranet. A continuación pasamos a explicar brevemente las principales características de cada uno de ellos destacando los aspectos positivos y negativos.  Typo3 El proyecto empezó a desarrollarse en Dinamarca por Kasper Skårhøj. Tras varios años de trabajo aparecen tres versiones prototipo en 1998, pero no es hasta el año 2000 cuando aparece una primera versión para evaluación de Typo3, dándose a conocer por primera vez al mundo del software libre. Con la colaboración de una creciente comunidad de usuarios y desarrolladores en 2002 aparece la primera versión estable del producto. Es una herramienta de gestión de contenido muy completa. Permite desarrollar completamente un sitio web de contenidos, con todas las consecuencias que conlleva: estructura multinivel, motor de búsquedas, gestión de autoría y publicación de contenidos, mecanismo de uso de plantillas para la maquetación de páginas, etc. Typo3 es también un portal. Administra, en particular, la personalización de las páginas según la identidad de los usuarios, es decir sabe integrar una selección de contenidos en una misma página, según los derechos del usuario identificado. 16 Despúes de analizar los CMS detenidamente finalmente hemos decidido usar Joomla por ser el CMS que mejor se ajusta a los requisitos. Entre los aspectos positivos que han determinado la decisión de usar Joomla destacamos los siquientes:  Es un CMS de código abierto con licencia GPL y programado en PHP. De esta manera podremos llevar a cabo todas aquellas adaptaciones que sean necesarias para poder ajustar el CMS a las necesidades de la empresa . Esto es un aspecto que cumplen los cuatro CMS analizados pero debemos destacarlo por ser muy importante.  La existencia de una gran comunidad de usuarios y desarrolladores nos permitirá resolver aquellas cuestiones que se nos planteen además de poder mantener la aplicación en el futuro. En este aspecto sólo es superado por WordPress aunque debemos recordar que el grado de participación de los usuarios de Joomla es mucho mas alto.  En el aspecto de la parte administrativa es sin duda el más destacado y la facilidad para aprender el uso del sistema es un aspecto crucial en el CMS.  En cuanto al control de acceso se puede decir que es la principal debilidad de Joomla con respecto a los demás CMS, sin embargo los desarrolladores de Joomla publican nuevas versiones cada poco tiempo. La versión 1.6 se encuentra en fase de desarrollo y se espera una versión estable pronto con un control de acceso granulado muy mejorado.  Una razón de peso que debemos añadir es que la empresa ya tiene experiencia con este CMS y lo ha sugerido como posible opción. 17 3 Joomla En este apartado vamos a describir brevemente como funciona Joomla, las funcionalidades de que consta el paquete de instalación básico, qué podemos aprovechar y también se comentarán aquellas funcionalidades que es necesario implementar porque no ofrece Joomla. Joomla funciona sobre una base de datos MySQL y un servidor HTTP, usualmente Apache, está escrito en PHP y es de código abierto. Esto significa que podemos programar aquellas funcionalidades que sean necesarias y Joomla no aporta. Además para este cometido Joomla pone a disposición de los desarrolladores el conjunto de librerías, clases y funciones, conjunto usualmente llamado framework[3], que se han usado para programar el CMS. Podemos encontrar la API(Aplication Programm Interface)[4] de dicho framework en http://api.joomla.org/li_Joomla-Framework.html. Para organizar los contenidos disponemos de una parte administrativa también llamada back-end y para mostrarlos a los usuarios está la parte del sitio web o front-end. Para organizar la presentación, tanto en el back-end como en el front-end, disponemos de cuatro tipos de programas que en Joomla se llaman extensiones, algunas ya incluidas en el paquete básico de instalación. Los tipos de extensiones que pueden añadir son plantillas, componentes, módulos,plugins . 3.1 Estructura  La plantilla: La plantilla es la estructura de la página, la función que desempeña es básicamente dividir la página web en distintas zonas mediante una hoja de estilo en cascada[5], un archivo con extensión CSS(Cascading style sheet). En las distintas zonas en las que se divide la plantilla se visualizarán los distintos módulos y componentes que habilitemos desde el back-end. La plantilla suele estar escrita en HTML con sentencias en PHP para cargar los módulos y/o componentes. También puede incluir algún script en JavaScript. Se usan plantillas distintas para el front-end y para el back-end. El paquete básico de instalación cuenta con algunas plantillas para el front-end y una sola para el back-end, pero se pueden encontrar una infinidad tanto gratuitas como de pago por Internet. Se ubican en el directorio “.../joomla/templates/” (las del front-end) y en “.../joomla/administrator/templates/” (las del back-end). En la Figura 5 podemos ver el gestor de plantillas y la previsualización de una plantilla. Las partes que vemos en rojo son las posibles zonas donde pueden mostrarse los módulos. La zona central, donde pone “Bienvenidos a la portada” es donde se mostraría el componente. 18 Figura 5. Previsualización de una plantilla.  Los componentes: Los componentes son programas que la plantilla se encarga de ubicar en la zona central de la página, son por tanto la parte más importante de ésta. Un componente puede existir sólo en el back-end, sólo en el front-end o en ambos sitios. En el back-end suelen usarse como herramientas para gestionar los datos de los que se encargue dicho componente.En el front-end para presentarlos en la zona central de la página. Para hacer uso de un componente hay que escribir en la barra de dirección del navegador: “url_del_dominio”/index.php?option=com_“componente” en el front-end y “url_del_dominio”/administrator/index.php?option=com_“componente” en el back-end. La ubicación de los archivos y carpetas de los componentes es “.../joomla/components/” (los componentes del front-end) y “.../joomla/administrator/components/” (los del back-end). En la Figura 6 mostramos la sección de componentes del gestor de extensiones. En la imagen podemos ver el menú componentes desplegado, que nos muestra una serie de enlaces a los componentes que tenemos instalados. Detrás del menú podemos ver una lista de componentes con sus atributos más relevantes. En esta lista algunos componentes tienen como autor “Joomla! Project”, lo que significa que el componente estaba incluido en el paquete de instalación. De los componentes incluidos en este paquete algunos se ven con un tono de color más claro, significa que forman parte del núcleo de Joomla y no pueden ser desinstalados. El resto pueden ser desinstalados desde este panel, tanto los que formaban parte del paquete de instalación como los que fueron añadidos posteriormente. 19 Figura 6. Gestor de extensiones, sección componentes.  Los módulos: Los módulos son programas que pueden mostrarse en diversos sitios de la página, dependiendo de como esté diseñada la plantilla y como se configure. Por lo general pueden ubicarse en cualquier sitio de la página excepto en la parte central que se reserva para los componentes. Suelen ser programas sencillos encargadas de mostrar enlaces, publicidad, o mostrar algunos datos que no ocupen mucho espacio. Se pueden configurar para que se muestren siempre o se muestren en función del estado de la página. La ubicación de los archivos y carpetas de los módulos es “.../joomla/modules/” (los del front-end) y en “.../joomla/administrator/modules/” (los del back-end). En la Figura 7 podemos ver las instancias de los módulos del front-end, de un módulo instalado podemos crear varias instancias y situarlas en distintos sitios de la plantilla. En la columna “Posición” se indica donde debe mostrarse el módulo y en la columna “habilitado” podemos indicar si queremos que el módulo se muestre o no. 20 Figura 7. Gestor de módulos.  Los plugins: Los plugins son extensiones que realizan dentro de Joomla una amplia variedad de funciones relacionadas fundamentalmente con la autenticación de usuarios, el funcionamiento del buscador interno o con la edición de contenidos. Un ejemplo es el editor Wysiwyg TinyMCE con el que podemos editar contenidos desde un entorno más amigable. También el plugin Pagebreak que nos permite paginar los artículos. En la serie 1.0 de Joomla los plugins se denominaban mambots. En la versión 1.5 han cambiado de nombre al evolucionar también la forma en que se integran en el sistema y han pasado a incluirse entre lo que denominamos extensiones, junto con los módulos y los componentes. La ubicación de los archivos y carpetas de los plugins es “.../joomla/plugins/” y la forma de usarlos varía mucho de un plugin a otro. En la Figura 8 podemos observar el gestor de plugins donde se muestra un conjunto de plugins instalados. Desde este gestor es posible habilitarlos o deshabilitarlos. Para desinstalarlos habría que ir al gestor de extensiones. 21 Figura 8. Gestor de plugins 22 3.2 Instalación Para la instalación de Joomla se requiere primero instalar un servido http que soporte PHP y una base de datos MySql. Esta instalación se hace usualmente bajo un sistema operativo Linux, y se ha denominado al paquete completo necesario para su instalación tecnología LAMP(Linux, Apache, MySql, PHP). Este tipo de tecnología se usa en muchos CMS. Lo primero que hay que hacer para instalar el paquete de Joomla es descargarlo, podemos encontrar una versión en español en http://joomlaspanish.org/ . Una vez obtenido el paquete hay que descomprimirlo en el directorio raíz del servidor http, aunque podemos crear alguna carpeta en dicho directorio y usar dicha carpeta como directorio raíz de Joomla. Una vez hemos descomprimido el paquete, debemos acceder a través del navegador al script de instalación que se situa en la carpeta que hemos fijado como directorio raíz de Joomla. Para ello solo hace falta introducir en la barra de direcciones del navegador la dirección http://url_instalacion/install.php. Es un proceso relativamente sencillo, semi-automático y gráfico, en el que, tras cumplir con unos requisitos mínimos, solo hay que seguir unos pocos pasos y cumplimentar algunos detalles desde sus respectivos campos. Es decir, la mayor parte del trabajo lo hace el instalador sí mismo. Una vez termina la intalación hay que borrar la carpeta installation y todo su contenido para concluir el proceso. Una vez finalizado, para acceder a la parte administrativa hay que acceder a la dirección http://url_instalacion/administrator/, y para la parte del usuario http://url_instalacion/. Puede verse una guía detalla del proceso de instalación en http://comunidadjoomla.org/component/content/article/147-manual-de-instalacionpara-joomla-15x.html?start=8 . 23 4 Desarrollo 4.1 Los Requisitos Los requisitos de una Intranet básicamente son que cada usuario vea una página distinta personalizada según su tipo y estado. En nuestro caso, para acceder a la Intranet hay que estar previamente registrado, no permitiremos la entrada a usuarios invitados. Estos usuarios serán por lo general clientes de la empresa dueña del sitio y tendrán acceso a distintos servicios en función de los productos ofrecidos por la empresa que tengan contratados. Estos servicios principalmente son:  Acceso a descargar el producto contratado.  Acceso a información acerca de las licencias de los productos contratados.  Acceso a una ayuda del producto navegable escrita en HTML y con vídeos.  Acceso a información y/o descarga de las nuevas versiones de los productos.  Acceso a foros públicos y/o privados sobre los productos con la idea de dar soporte técnico, detectar errores y mejorar los productos.  Publicidad acerca de nuevas versiones así como de otros productos que pudieran interesar al cliente. Para poder ofrecer estos servicios será necesario mantener información acerca de los productos, versiones, clientes, usuarios y licencias. El mantenimiento de esta información es una tarea administrativa y por tanto debe poder realizarse desde el back-end. 4.1.1 Requisitos del back-end  Los clientes pueden ser particulares o pueden ser de una empresa, además necesitaremos mantener información de contacto con nuestros clientes, ya sean particulares o de empresa. También debemos saber las cuentas de usuario asignada a cada cliente que podrían ser una o varias.  Los productos pueden tener varias versiones, las cuales serán accesibles si se tiene una licencia vigente para dicho producto. De cada producto se desea mantener un artículo de presentación, un logotipo, un foro privado y una ayuda navegable que puede incluir vídeos.  De cada versión debemos saber: de qué producto es la versión, nombre de la versión, tipo de versión (desarrollo, estable, de prueba, etc..), fecha de la publicación, archivo de descarga, número de descargas efectuadas, si está cerrada o abierta a modificaciones, si continúa su mantenimiento o no, si ha sido lanzada recientemente 24 y si es de libre distribución o de pago.  De las licencias deberemos saber: de que cliente y para qué producto es la licencia, numero de licencia para identificarla, tipo de licencia (lite, extended, etc...), fecha de inicio de vigencia, fecha que se ordenó la compra, fecha de pago, cantidad pagada, número de equipos que permite y número de renovaciones.  De las empresas que sean clientes debemos conocer el nombre, una persona de contacto, el cif, una dirección física de la empresa, una dirección de correo y a ser posible un número de fax.  También se requiere la posibilidad de hacer copias de respaldo tanto del conjunto de archivos y carpetas como de la base de datos del sitio.  Otro requisito es que podamos acceder a los archivos y carpetas del servidor a través de la interfaz administrativa de Joomla, ya que no tenemos acceso directo al servidor ni acceso mediante protocolos de comunicación típicos como FTP o SSH. 4.1.2 Requisitos del front-end En la parte pública de nuestro sitio web, es decir, el front-end, vamos a tener los siguientes requerimientos:  Una vez el usuario se haya validado se le debe cargar una página en la que tenga un menú personalizado acorde a lo que tenga contratado. Si tiene un sólo producto, se le carga el único menú que tendrá.  En caso de tener más de un producto, esta primera pantalla puede ser un menú selector del producto donde aparezcan los logos de cada producto en grande de tal manera que cuando pinche sobre uno se cargue ya la página acorde al producto. La posibilidad de cambiar de un producto a otro en cualquier momento también debe estar contemplada. Para esto podemos usar un ComboBox situado en la parte superior.  Cuando ya está seleccionado el producto debe cargarse un menú en la parte izquierda dando soporte al producto, aquí deben verse los enlaces para los manuales de ayuda, el foro, la zona de descargas y un enlace para volver a la presentación del producto.  También pondremos en la parte izquierda un pequeño apartado con publicidad en el que mostraremos enlaces a las versiones nuevas de los productos contratados por el cliente, así como enlaces a versiones de prueba de productos que puedan ser de interés. En esta parte debe mostrarse la interfaz de acceso para iniciar o finalizar sesión.  La zona de descargas de un producto debe ser una lista con las versiones disponibles 25 y un enlace para su descarga, que nos enviará a un nuevo apartado con la descripción de la versión y el enlace a la descarga del archivo. 32 La parte del sitio tendrá la función de mostrar los datos guardados en función de los servicios que demande el cliente en cada momento, estos datos se mostrarán en la zona central de la página que es donde la plantilla muestra la salida de los componentes. Lo primero que debe verse nada más acceder a la Intranet será una presentación donde se mostrarán los logos de los distintos productos contratados por el cliente y los parámetros de la licencia. Los logos serán también un enlace a la presentación del producto en concreto. También será este componente el encargado de mostrar la ayuda. Cuando se seleccione el enlace correspondiente, el componente buscará la ayuda de la versión del producto y la mostrará en la zona central de la página. Por último, también tendrá la función de gestionar las descargas de los productos mostrando las distintas versiones de cada producto y los detalles de cada versión una vez se seleccione, para finalmente mostrar un enlace a la descarga del archivo. El componente también se encargará de evitar que usuarios no autorizados tengan acceso a estas descargas. 4.5 Codificación A continuación pasamos a explicar la estructura del código de nuestro componente principal así como de los módulos. Vamos a profundizar un poco más y vamos a explicar las clases principales que se usan dentro de nuestro componente y su código. Podemos ver la jerarquía de archivos y carpetas en la siguiente figura. Figura 10. Componente SOA. Jerarquía de archivos y carpetas en el paquete de instalación. 33 En la parte superior de la jerarquía tenemos la carpeta admin, que contiene la parte administrativa del componente, la carpeta site, que contiene la parte del front-end, y el archivo install.xml que es un script de instalación en lenguaje XML que usa la aplicación de Joomla para instalar extensiones. Tras la ejecución de dicho script lo que vemos dentro de la carpeta admin se ubicará en .../joomla/administrator/components/com_soa/ y lo que vemos en la carpeta site se situará en .../joomla/components/com_soa/. A partir de este punto nombraremos las carpetas como si ya se hubieran instalado. El componente principal, que hemos llamado soa se compone de dos partes bien diferenciadas de código. En primer lugar explicaremos el código de la parte administrativa o back-end. 4.5.1 Back-end Esta parte sigue el patrón de diseño MVC (Modelo-Vista-Controlador). Este patrón es típico en los componentes desarrollados para Joomla y permite diferenciar la lógica de los datos y de la presentación.  El modelo se encarga de establecer la estructura de los datos y de conectar con la base de datos para obtener los datos o para guardarlos. El modelo contiene los datos que utilizaremos en la aplicación que puede coincidir o no con lo que se almacena en la base de datos. Por ejemplo en la base de datos podemos guardar una tabla con un campo que sea la id de otra tabla (clave ajena) y en el modelo añadir campos adicionales de dicha tabla. El modelo hace servir una clase JTable que representa de forma fiel el objeto en la base de datos, esta clase se utilizará para guardar cambios en los objetos o crear objetos nuevos.  La vista presenta los datos obtenidos en el modelo, permite seleccionar objetos, que en nuestro caso serán productos, versiones, etc... para editarlos (cambiar sus atributos), guardarlos o borrarlos. Para los objetos que manejamos tendremos dos vistas: La vista “objetos” que muestra todos los objetos registrados y permite seleccionarlos para borrarlos o editarlos mediante los botones de la barra de tareas que indican estas funciones. También mostraremos en esta vista un botón para crear un objeto nuevo. La vista “objeto”. Cuando seleccionamos un objeto para editarlo o creamos uno nuevo, se muestra una vista que presenta los atributos del objeto para modificarlos. En la barra se mostrarán los botones de cancelar o guardar.  El controlador se encarga de la lógica, es decir coordina la vista y la gestión de los datos ejecutando las tareas que tiene registradas. En nuestro caso solo haremos uso de las tareas editar() y borrar() en la vista “objetos” y guardar() y cancelar() en la vista “objeto”. Cuando pulsamos un botón de la barra de herramientas en alguna de las vistas anteriores, se llama al controlador y se ejecuta la tarea indicada por el 34 botón. El controlador establece la vista que se mostrará tras ejecutar la tarea indicada y permite realizar las funciones necesarias antes de llamar al modelo para obtener o guardar los datos. En la parte administrativa tendremos cinco controladores, uno por cada tabla, y un sexto controlador del que heredan todos. Este controlador no se usa y sirve como plantilla para crear los demás controladores. Una vez conocido el patrón de diseño podemos pasar a profundizar un poco más en el código. Dentro de la carpeta admin podemos ver cinco archivos y cinco carpetas. Ahora explicaremos su contenido uno a uno comenzando por los archivos:  controller.php: Es el controlador principal, tenemos un controlador por cada tabla, que heredan de este controlador. Es el que se ejecutaría si no llamamos a ninguno de los sub-controladores, en nuestro caso no se ejecuta nunca, por lo que podemos considerarlo una clase abstracta.  index.html: Este archivo es un HTML vacío y su función es evitar el acceso a la carpeta desde la web por parte de un usuario. Este archivo debe estar presente en casi todas las carpetas de Joomla.  install.sql: Tras ejecutar el script de instalación se ejecuta este script sql que crea las tablas necesarias para el uso de nuestro componente, también existe un unistall.sql que se ejecuta tras la desinstalación y su cometido es borrar dichas tablas.  soa.php: Es el archivo principal del componente, su función es encontrar el controlador que debe usarse y mandarlo a ejecutar la tarea asignada. Figura 11. Código fuente del fichero .../administrator/com_soa/soa.php <?php // No direct access defined( '_JEXEC' ) or die( 'Restricted access' ); // Require the base controller require_once( JPATH_COMPONENT.DS.'controller.php' ); // Require specific controller if requested if($controller = JRequest::getWord('controller')) { $path = JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php'; if (file_exists($path)) { require_once $path; } else { $controller = ''; } } // Create the controller $classname = 'SoasController'.$controller; $controller = new $classname( ); // Perform the Request task $controller->execute( JRequest::getVar( 'task' ) ); // Redirect if set by the controller $controller->redirect(); 35 En la Figura 11 podemos ver el código para obtener el nombre del controlador de la variable de entorno controller.Busca dentro de la carpeta controllers de nuestro componente un archivo con ese nombre, si lo encuentra crea un controlador de ese tipo, sino, crea un controlador del tipo SoasController, el cual es el controlador por defecto que está definido en el archivo controller.php que hemos comentado antes. A continuación manda al controlador creado ejecutar la tarea que lee de la variable de entorno task. El controlador producto Ahora vamos a adentrarnos en las carpetas del componente empezando por la carpeta controllers que contiene los cinco controladores. Estos controladores son muy similares entre sí, a excepción del controlador de la clase producto, que se le ha añadido unas líneas de código para que cuando creamos un producto nuevo se cree una carpeta con el nombre de dicho producto dentro de la carpeta Productos, y otra carpeta en su interior de nombre Ayuda donde colocaremos los ficheros con la ayuda en HTML. En la Figura 12 mostramos el código fuente del fichero que se encarga de controlar los objetos producto. El archivo contiene una clase class SoasControllerProducto la cual hereda de la case SoasController, la cual hereda a su vez de la clase JController que forma parte del framework de Joomla. Esta clase trabaja con un objeto producto y puede realizar las funciones de eliminar, guardar o editar el objeto. Para editar el objeto se mostrará la vista producto, desde donde se podrán editar sus atributos. En la función save() se delegará en el modelo para guardar el objeto. Además se han añadido algunas líneas de código que se encargarán de crear una carpeta con el nombre del producto en .../administrator/com_soa/Productos/ y otra carpeta con el nombre Ayuda en su interior si se trata de un objeto producto nuevo, o de renombrar la carpeta existente si se ha renombrado un objeto producto. 36 Figura 12. Codigo fuente del fichero .../controllers/producto.php <?php // No direct access defined( '_JEXEC' ) or die( 'Restricted access' ); class SoasControllerProducto extends SoasController { function __construct() { parent::__construct(); // Register Extra tasks $this->registerTask( 'add' , 'edit' ); } function edit() { JRequest::setVar( 'view', 'producto' ); JRequest::setVar( 'layout', 'form' ); JRequest::setVar('hidemainmenu', 1); parent::display(); } function save() { $model = $this->getModel('producto'); if ($model->store($post)) { //creamos la carpeta propia del producto y sus subcarpetas $origen = JPATH_BASE.DS.'components'.DS.'com_soa'.DS.'Productos'.DS; $file = 'index.html'; $basedir=JPATH_BASE.DS.'components'.DS.'com_soa'.DS.'Productos'.DS; $dir = $basedir.$model->_data[nombre]; $dir_viejo = $basedir.$model->_data[nombre_viejo]; if (!file_exists($dir) ){ if($dir_viejo!=$dir && $model->_data[nombre_viejo]!=null){ $yea = rename ($dir_viejo, $dir); $creado = 'Producto y carpetas renombrados ' .$model->_data[nombre_viejo].' '.$dir; } else{ mkdir($dir); copy($origen . $file, $dir.DS.$file); $dir = $dir.DS.'Ayuda'; mkdir($dir); copy($origen . $file, $dir.DS.$file); $creado = 'Creadas carpetas del producto,'; } } $msg = JText::_( $creado.' Producto guardado' ); } else { $msg = JText::_( 'Error guardando producto' ); } // Check the table in so it can be edited.... we are done with it anyway $link = 'index.php?option=com_soa'; $this->setRedirect($link, $msg); } function remove() { $model = $this->getModel('producto'); if(!$model->delete()) { $msg = JText::_( 'Error: uno o mas productos no han sido borrados' ); } else { $msg = JText::_( 'Producto(s) borrado(s), Se han dejado las carpetas' ); } $this->setRedirect( 'index.php?option=com_soa', $msg ); } function cancel() { $msg = JText::_( 'Operacion Cancelada' ); $this->setRedirect( 'index.php?option=com_soa', $msg ); } } 37 Los modelos producto y productos A continuación vamos a explicar los modelos: Existen dos modelos por cada tabla. Los modelos contienen los datos que se representarán en las vistas. Como tenemos dos vistas tendremos dos modelos y estos tendrán el mismo nombre que la vista correspondiente. Uno de los modelos contiene los datos relevantes de todos los objetos de una tabla y el otro modelo contiene todos los datos de un objeto, siendo una fiel representación del objeto en la base de datos. En concreto estudiaremos los modelos producto y productos que son muy similares al resto de modelos. Cada uno se encuentra en un fichero PHP dentro de la carpeta models. A continuación vemos el código fuente del modelo productos. Figura 13. Modelo productos. Fichero .../models/productos.php Los modelos son clases que heredan de la clase JModel del framework de Joomla. Este modelo se encarga de obtener una lista con todos los objetos producto de la base de datos. Para ello hace una consulta a la base de datos añadiendo además atributos de las tablas content y fb_categories. Los objetos de esta lista se mostrarán en la vista productos. En la siguiente figura vemos el código correspondiente al modelo producto. <?php // No direct access defined( '_JEXEC' ) or die( 'Restricted access' ); jimport( 'joomla.application.component.model' ); class SoasModelProductos extends JModel { var $_data; function _buildQuery() { $query = ' SELECT P.*, C.title as presentacion, F.name as nombre_foro' . ' FROM #__0Productos P' . ' LEFT JOIN #__content C ON P.articulo = C.id ' . ' LEFT JOIN #__fb_categories F ON P.foro = F.id' ; return $query; } function getData() { if (empty( $this->_data )) { $query = $this->_buildQuery(); $this->_data = $this->_getList( $query ); } return $this->_data; } } 38 Figura 14. Modelo producto. Fichero .../models/producto.php <?php // No direct access defined( '_JEXEC' ) or die( 'Restricted access' ); jimport('joomla.application.component.model'); class SoasModelProducto extends JModel { function __construct() { parent::__construct(); $array = JRequest::getVar('cid', 0, '', 'array'); $this->setId((int)$array[0]); } function setId($id) { $this->_id = $id; $this->_data = null; } function &getData() { // Load the data if (empty( $this->_data )) { $query = ' SELECT * FROM #__0Productos '. ' WHERE id = '.$this->_id; $this->_db->setQuery( $query ); $this->_data = $this->_db->loadObject(); } if (!$this->_data) { $this->_data = new stdClass(); $this->_data->id = 0; $this->_data->nombre = null; $this->_data->articulo = null; $this->_data->logo = null; $this->_data->foro = null; $this->_data->extra = null; } return $this->_data; } function store() { $row =& $this->getTable(); $this->_data = JRequest::get( 'post', JREQUEST_ALLOWHTML ); if (!$row->bind($this->_data)) { $this->setError($this->_db->getErrorMsg()); return false; } if (!$row->check()) { $this->setError($this->_db->getErrorMsg()); return false; } if (!$row->store()) { $this->setError( $this->_db->getErrorMsg() ); return false; } return true; } function delete() { $cids = JRequest::getVar( 'cid', array(0), 'post', 'array' ); $row =& $this->getTable(); if (count( $cids )) { foreach($cids as $cid) { if (!$row->delete( $cid )) { $this->setError( $this->_db->getErrorMsg() ); return false; } } } return true; } } 39 Este modelo trabaja con un objeto producto almacenado en la base de datos y contiene los datos que veremos en la vista producto cuando queramos editar o crear un nuevo objeto. Cuando desde la vista productos se muestra una lista de los productos almacenados en la base de datos, podemos crear uno nuevo o seleccionar uno de la lista para editarlo o varios objetos para borrarlos. Estas tareas las lleva a cabo el controlador pero delegando la tarea al modelo producto. Para editar un objeto, el controlador llamará a la vista producto, la cual mostrará los atributos del objeto en campos editables. Para ello obtendrá los datos del objeto a través del modelo pasándole su id. El propio modelo se encargará de hacer una consulta a la base de datos y obtener el objeto íntegro a través de su id haciendo uso de la función &getData(). Si en lugar de editar tratamos de crear un objeto nuevo el proceso es el mismo, pero el id del objeto sería 0, y los campos editables se presentarían con un valor por defecto. Para entender bien como funciona el modelo producto es conveniente conocer la clase TableProducto. Esta clase hereda de la clase JTable del framework de Joomla y su función es ser una clase persistente a través de la cual guardaremos y borraremos los objetos de la base de datos. Una vez editado los campos, si se pulsa el botón guardar la ejecución vuelve al controlador, el cual invocará la función store(). Esta función obtiene los campos editados en la vista producto en forma de variables, después obtiene una instancia de la clase TableProducto. La tarea de almacenar el objeto en la base de datos se realiza a través del objeto TableProducto el cual se encarga de la conexión con la base de datos y de ejecutar las sentencias correspondientes en SQL. Desde la vista productos también es posible seleccionar uno o varios objetos para borrarlos. Cuando se pulsa el botón borrar, la ejecución vuelve de nuevo al controlador, el cual delega la tarea al modelo invocando la función delete(). Esta función obtendrá una lista con el id de cada objeto seleccionado y una instancia del objeto TableProducto al que delegará la tarea final de borrar el objeto. Por último mediante un bucle for llamará repetidamente a la función delete( $cid ) de la clase TableProducto donde la variable $cid contiene el id del producto que se debe borrar. La vista producto y productos Ahora vamos a explicar la parte de la vista que es la más extensa y complicada del componente. De cada tabla de nuestro componente tendremos dos vistas, igual que con los modelos. Una de las vistas es la encargada de mostrar en forma de tabla una lista con los objetos almacenados, añadiendo si es preciso algún atributo a los objetos. La otra vista muestra los atributos de un objeto determinado en forma de campos editables, pudiendo crear nuevos objetos o editar objetos existentes. Cada vista se compone de dos ficheros, en uno obtenemos los datos que queremos mostrar haciendo uso del modelo para esta tarea. El segundo fichero es una plantilla que se 40 encarga de organizar la presentación del los datos previamente obtenidos. En la siguiente imagen puede verse la jerarquía de archivos y carpetas que componen la vista. Figura 15. Jerarquía de carpetas y archivos de la vista A continuación vamos a analizar las dos vistas correspondientes a los productos. Comenzamos explorando la carpeta .../com_soa/view/productos/ que contiene la vista productos. En esta vista mostramos los atributos relevantes de los objetos producto en forma de tabla con algunos atributos añadidos. El fichero que se encarga de obtener los datos tiene de nombre view.html.php y se sitúa en la carpeta .../views/productos/. En la siguiente imagen podemos ver su código. 41 Figura 16. Vista productos. Fichero .../views/productos/view.html.php. La vista es en realidad una clase heredada de la clase JView de Joomla. En esta clase reescribimos la función display(). Aquí se llama a la clase JToolBarHelper de Joomla para indicar los botones que deben verse. Después se obtiene la lista de objetos que deben mostrarse con la ayuda del modelo productos. Esta lista es transformada en una variable de clase de nombre items que será accesible desde el otro fichero, el encargado de organizar la presentación de los datos. Por último se llama a la función display() de la clase heredada que se encargará de mostrar los datos haciendo uso del código del otro fichero de la vista. El segundo fichero se encuentra en la carpeta .../views/productos/tmpl/ y lleva por nombre default.php. Este fichero está escrito en su mayor parte en HTML, aunque hace uso de sentencias en PHP para acceder a los datos que se han obtenido mediante el código del fichero anterior. En realidad no es más que una plantilla para presentar los datos obtenidos (más detalles se pueden ver en el Anexo1: Fichero .../views/productos/tmpl/default.php. Página 60) Hasta aquí la primera parte de la vista, la vista “productos”, que mostraba la lista de objetos contenidos en la base de datos con sus atributos añadidos de otras tablas. Ahora vamos a explicar la vista producto, que es la vista que vemos al modificar o crear un producto. Esta vista se encuentra en .../views/producto/ y al igual que la anterior tenemos una clase JView en un archivo llamado view.html.php y una plantilla. Analizamos ahora el fichero .../views/producto/view.html.php que es muy similar al que vimos en la carpeta /views/productos/. Podemos ver su código en la siguiente figura. <?php // No direct access defined( '_JEXEC' ) or die( 'Restricted access' ); jimport( 'joomla.application.component.view' ); class SoasViewProductos extends JView { function display($tpl = null) { JToolBarHelper::title( JText::_( 'Intranet SOA: Productos' ), 'generic.png' ); JToolBarHelper::deleteList(); JToolBarHelper::editListX(); JToolBarHelper::addNewX(); // Get data from the model $items = & $this->get( 'Data'); $this->assignRef('items', $items); parent::display($tpl); } } 48  Version: Esta clase es similar a la clase anterior. Se utiliza para construir un objeto version a partir de su id o teniendo ya sus datos. Además proporciona un método para obtener la url del fichero descargable de la versión.  function Version($id, $data): Es el constructor de la clase. Si la variable $data no está vacía construye un objeto Versión con los atributos de esa variable, en caso contrario utiliza la variable $id para obtener el objeto de la base de datos.  function enlace(): Esta función devuelve la ruta completa del fichero de descarga de la versión . El resto de funciones que hay en el helper son funciones de apoyo para el controlador, con la excepción de una función que restringe el acceso a los foros a los usuarios no permitidos.  function Comprobar_acceso_foro($idforo): Esta función toma como parámetro el id de un foro del que se desea determinar si el usuario debe tener acceso o no. Si el foro es privado, solo estará permitido el acceso a los usuarios que tengan licencia de uso del producto que se trata en el foro. Los foros descendientes de este también serán privados. La función hace una consulta a la base de datos para comprobar si el foro es privado y si lo es, comprueba si el usuario tiene acceso. Para poder hacer esta comprobación ha sido necesario modificar un fichero del componente kunena_forum. En concreto en el fichero .../joomla/components/com_kunena/Class.kunena.php se ha añadido tras la linea 944: --require_once(JApplicationHelper::getPath( 'helper' , 'com_soa' ));-- y la linea originalmente 950 se ha sustituido por: -- ($row->pub_access == -1 and comprobar_acceso_foro($row->id) == true) or -- Es importante tener en cuenta que este fichero y estas lineas corresponden a la versión 1.5.12, ya que podrían cambiar en versiones diferentes (más detalles se pueden ver en el Anexo 4: .../components/com_soa/helper.php. Página 65) 4.5.3 Módulos Los módulos son extensiones cuya finalidad es mostrar datos en las zonas periféricas de la página. Para el desarrollo de la Intranet hemos implementado tres módulos, todos para el front-end. Se ubican en carpetas dentro de .../joomla/modules/ y ahora procedemos a su explicación.  mod_logo_soa: Aquí hemos programado un ComboBox para cambiar el producto actual de trabajo y también mostramos el logotipo y lo principales parámetros de la licencia. Consta de un solo fichero llamado mod_logo_soa.php ubicado en .../joomla/modules/mod_logo_soa. 49 A continuación mostramos su código. Figura 18. Módulo logo_soa. Fichero …/modules/mod_logo_soa El módulo obtiene, con la ayuda del helper del componente com_soa, una lista con los productos del cliente, y leyendo la variables de entorno producto obtiene el producto actual, si hay uno. Después crea una tabla en html con tres celdas. En la <?php // no direct access defined( '_JEXEC' ) or die( 'Restricted access' ); require_once(JApplicationHelper::getPath( 'helper' , 'com_soa' )); $lista_p = listasSoa::getInstance(); $lproductos = $lista_p->getProductos(); $prodId = JRequest::getVar('prod'); if($prodId == null) $prodId = JRequest::getVar('producto'); echo '<TABLE CELLPADDING=5 CELLSPACING=5 >'; echo '<div style="padding-left: 1px" >'; echo '<tr>'; echo '<td ><form action="index.php?option=com_soa&task=cambio" method="POST"> <select name="cambiar" onchange="this.form.submit()">'; echo '<option value="0" selected>'.productos.'</option>'; foreach($lproductos as $producto){ if($prodId == $producto->datos->id){ echo '<option value="'.$producto->datos->articulo.'" selected>'.$producto->datos- >nombre.'</option>'; } else echo '<option value="'.$producto->datos->articulo.'">'.$producto->datos->nombre.'</option>'; } echo '</select></td> </form>'; echo '</tr>'; if($prodId!=null){ $producto = new Producto($prodId,''); $licencia = $producto->getLicencia(); echo '<tr>'; echo '<td>'; $producto->show_logo(); echo '</div>'; echo '<div style="padding-left: 25px">'; echo '<td>'; echo '<BR>'.$producto->datos->nombre.'<BR>'; echo 'Licencia: '.$licencia->Tipo.'<BR>'; echo 'Expira: '; if($licencia->FechaFin != '0000-00-00') echo $licencia->FechaFin.'<BR><BR>'; else echo 'Nunca<BR><BR>'; echo '</td>'; echo '</tr>'; echo '</div>'; } echo '</TABLE>'; ?> 50 parte superior muestra el ComboBox con la lista de productos y si hay un producto actual de trabajo, en la parte inferior muestra el logotipo y la licencia del producto, el ComboBox dejará este producto seleccionado.  mod_menu_soa: Aquí mostramos un menú con enlaces a la presentación de cada producto contratado, al foro, a la zona de descarga y a la página de ayuda. Consta de un solo fichero llamado mod_menu_soa.php ubicado en .../joomla/modules/mod_menu_soa. A continuación mostramos su código. Figura 19. Módulo menu_soa. Fichero …/modules/mod_menu_soa. Con la ayuda del helper, obtiene una lista con los productos contratados, después mediante un bucle for para cada producto se muestra un enlace a la presentación del producto, al foro, a la zona de descarga y a la página de ayuda. En caso de no tener ningún producto con licencia vigente se muestra un texto indicando que no hay productos contratados.  mod_publi_soa: Este módulo muestra una publicidad de forma estática, se muestran las versiones nuevas de los productos contratados y las versiones de libre distribución de otros productos. Consta de un solo fichero llamado mod_publi_soa.php ubicado <?php defined( '_JEXEC' ) or die( 'Restricted access' ); require_once(JApplicationHelper::getPath( 'helper' , 'com_soa' )); $lista_prod = listasSoa::getInstance(); $lproductos = $lista_prod->getProductos(); if ($lproductos!=null){ foreach ($lproductos as $producto) { echo '<div style="padding-left: 5px"><BR>'; echo '<a href="index.php?option=com_content&view=article&id='. $producto->datos->articulo .'&prod='.$producto->datos->id.'"><span>'. $producto->datos->nombre .'</span></a><br/>'; echo '</div>'; echo '<div style="padding-left: 16px">'; echo '<a href="index.php?option=com_soa&task=ayuda&prod='.$producto->datos->id .'"><span>Ayuda</span></a><br/>'; echo '<a href="index.php?option=com_kunena&Itemid=0&func=showcat&catid='.$producto->datos->foro .'&prod='.$producto->datos->id.'"><span>'.Foro.'</span></a><br/>'; echo '<a href="index.php?option=com_soa&task=descargar&prod='.$producto->datos->id .'"><span>'.Descargas.'</span></a><br/>'; echo '</div>'; } echo '<BR>'; } else{ echo 'No tiene Productos contratados<BR>'; } ?> 51 en .../joomla/modules/mod_publi_soa. Figura 20.Módulo publi_soa.Fichero …/modules/mod_publi_soa/mod_publi_soa.php Obtiene una lista con las versiones cuyo atributo nuevo es 'Si' de los productos contratados y de versiones libres de otros productos con la ayuda del helper. Después muestra un enlace a la descarga de la versión. Para instalar el componente y los módulos hemos creado un paquete de instalación para cada extensión y hay que instalarlos por separado a través de la administración de Joomla. Los paquetes contienen un archivo install.xml que usa Joomla para instalar cada extensión. <?php // no direct access defined( '_JEXEC' ) or die( 'Restricted access' ); # # // require the helper require_once( JApplicationHelper::getPath( 'helper', 'com_soa' ) ); # $listas_publi = listasSoa::getInstance(); $listaVD = $listas_publi->getVerDis(); echo '<div style="padding-left: 5px" >'; echo '<TABLE CELLPADDING=2 CELLSPACING=7 >'; foreach($listaVD as $version){ echo '<tr><td>'; echo '<a href="index.php?option=com_soa&task=descargar_version&ver='.$version->id.'"><span>' . $version->nombre_producto.' ' .$version->version.'</span></a></td><td width="50" align="center">'; if($version->nuevo == Si) echo '<IMG SRC="images/new.png" align="center"></td>'; if($version->libre == 'Si') echo '<td><IMG SRC="images/gratis3.png" align="center"></td></tr>'; } echo '</TABLE>'; echo '</div>'; ?> 52 5 Casos de uso Este apartado pretende ser un pequeño tutorial donde explicamos cómo crear un producto y dar de alta un cliente para poder ofrecerle servicio paso a paso, incluyendo la creación de un foro, versiones del producto, etc... Cuando queremos dar de alta un producto en nuestra base de datos, antes que nada debemos crear un foro para el producto y un artículo para su presentación, también es conveniente subir el logotipo del producto antes de su creación. No es estrictamente necesario seguir este orden, podríamos crear un producto y dejar sus atributos vacíos para editarlos posteriormente, aunque el método que vamos a explicar pretende crear todo lo necesario en el mínimo número de pasos posibles. 5.1 Dar de alta un producto Aquí explicamos cómo crear un producto el cual llamaremos “Routing Maps” para darle un toque de realismo, ya que es uno de los productos ofertados por la empresa. 1. Crear un artículo de presentación: Vamos al gestor de artículos y creamos un artículo nuevo. Previamente es necesario haber creado una sección y una categoría dentro de ésta. El artículo podemos llamarlo Presentación Routing Maps. Debemos crearlo con acceso Registrado y debemos marcarlo como publicado. 2. Crear un foro: En segundo lugar será necesario un foro. Para esta tarea debemos ir al componente Kunena Forum y en el administrador de foros crear un foro que podemos llamar Zona Routing Maps. Dentro del foro creamos dos foros más uno será un foro público y otro será privado. Podemos llamarlos “Foro público RM” y “Foro privado RM” respectivamente. Todos los foros deben crearse con nivel de acceso “Todos registrados”. 3. Subir el logo: Antes de crear el producto aún nos queda un paso, que es subir el logotipo al servidor. Para ello podemos hacer uso del componente eXtplorer y debemos subir el logo a la carpeta .../joomla/administrator/components/com_soa/Productos/logos/. Esta carpeta se crea cuando se instala el componente com_soa. 4. Crear el producto: Por último vamos al componente Intranet SOA y en la sección productos creamos un producto nuevo poniendo como nombre Routing Maps, artículo de presentación Presentación Routing Maps, foro Foro privado RM y logo el que subimos previamente. En el campo Descripción del producto podemos añadir un texto con formato para describirlo. 53 En la siguiente imagen se muestra la interfaz para dar de alta un nuevo producto. Figura 21. Interfaz alta producto. 5.2 Dar de alta una versión Ahora vamos a dar de alta la versión 1.0 del producto. Antes de crear el objeto versión será necesario dar algunos pasos previos, asumimos que hemos creado ya un producto. 1. Subir fichero descarga Lo primero que tendremos que hacer es subir el fichero de descarga de la versión. Para ello usaremos como antes el eXtplorer y lo subiremos a la carpeta .../joomla/administrator/components/com_soa/Productos/Routing Maps/. Esta carpeta se crea automáticamente cuando creamos el producto y si renombramos el producto también se renombrará automáticamente. 2. Subir fichero ayuda Igual que el primer paso, pero la carpeta destino será .../joomla/administrator/components/com_soa/Productos/Routing Maps/Ayuda/. Esta carpeta también se ha creado al crear el producto. 54 3. Crear el artículo ayuda Además de un fichero de ayuda vamos a necesitar un artículo, ya que será necesario si queremos añadir algún vídeo para complementar la ayuda. Para añadir un vídeo debemos poner {“ext”}”nombre vídeo”{/”ext”} donde “ext” es la extensión del fichero que contiene el vídeo. También será necesario añadir una linea referente al plugin jumi para que en el artículo se incluya un script en PHP que le indiquemos. En concreto le vamos indicar que ejecute el scipt ubicado en .../joomla/components/com_soa/jumi_soa.php y para ello habrá que escribir una linea que ponga {jumi [components/com_soa/jumi_soa.php]}. 4. Crear el objeto version Con esto ya podemos ir a la sección versiones del componente Intranet SOA y crear nuestra versión. El resto de parámetros se dejan a opción del administrador. En la siguiente figura se muestra la interfaz para dar de alta una versión en la base de datos. Figura 22. Interfaz alta versión. 55 5.3 Dar de alta un cliente Para dar de alta un cliente, es necesario haber dado previamente de alta un usuario. El cliente puede relacionarse con un usuario, una empresa y un contacto, sin embargo el contacto y la empresa no son estrictamente necesarios, puesto que guardan una información que no urge a la hora de dar servicio, puesto que la cuenta de usuario ya guarda una cuenta de correo que sería lo mínimo necesario para poder comunicarnos con el cliente. La información de contacto está bien tenerla como información adicional, pero no es imprescindible y en cuanto a la información acerca de la empresa tampoco es imprescindible ya que un cliente podría ser un particular y ni siquiera tendría una empresa asociada. 1. Dar de alta al cliente: Una vez hayamos dado de alta al usuario podemos pasar directamente a dar de alta al cliente, solo tenemos que asociar un nombre para identificar el objeto cliente y podemos dejar la información de contacto y de empresa vacía por el momento. 5.4 Dar de de alta una licencia Este es el último paso necesario para poder ofrecer servicio al cliente. Tenemos que crear una licencia que relacione al cliente previamente dado de alta y el producto que ha contratado. 1. Dar de alta una licencia Aquí solo es necesario especificar un número de licencia que identificará el contrato, seleccionar el cliente y el producto que relaciona el contrato. El resto de campos sirven para mantener información de interés pero no son esenciales para el funcionamiento de la página. Una vez dado de alta el contrato podemos comprobarlo yendo a la sección cliente y pinchando en ver en la columna licencias. 56 6 Conclusiones Para desarrollar toda esta tarea en primer lugar ha sido necesaria un largo tiempo dedicado a documentación acerca de los CMS, y más concreto de Joomla. Primero fue necesario entender las herramientas sobre las que trabaja Joomla, la tecnología LAMP que se ha comentado al principio. Para poder usar Joomla era necesario instalar el servidor web Apache, el sistema de gestión de bases de datos MySQL y las librerías necesarias para poder ejecutar código en PHP. A falta de un servidor donde todo esto estuviera disponible se hizo en un ordenador personal con la idea de disponer de una versión local de la Intranet en la que trabajar. Después de instalar los paquetes básicos para poder usar Joomla fue necesario descargar el paquete de Joomla y hacer una instalación en el ordenador personal. La primera tarea fue familiarizarse con el entorno Joomla y analizar qué requisitos de la Intranet se podían satisfacer con el paquete básico de instalación. Joomla, como un gestor de contenidos que es, está pensado para crear páginas web de contenidos. Este tipo de páginas son muy abundantes, algunos ejemplos son blogs, portales de noticias, periódicos digitales, etc... Por tanto usar Joomla con el objetivo de crear un sitio web de este tipo es relativamente sencillo y no requiere la instalación de muchas extensiones. Sin embargo para crear una Intranet es necesario darle algunas funcionalidades que no tiene, aquí es donde empieza la tarea de buscar extensiones. Tras mucho tiempo buscando y probando extensiones fue posible darle a la Intranet gran parte de su funcionalidad. Buscando en los portales y foros dedicados a los usuarios de Joomla fue posible encontrar algunas de las extensiones más básicas para el funcionamiento requerido en la Intranet. Entre las extensiones fue fácil encontrar el administrador de foros Kunena Forum, el plugin para insertar vídeos en los contenidos AllVideos y el componente para realizar copias de respaldo Akeeba Backup. Por parte de la empresa se sugirió también la instalación del componente eXtplorer, su búsqueda e instalación fue algo trivial. Estos componentes están bastante extendidos y su uso es muy fácil e intuitivo, por lo que no fue necesario emplear mucho tiempo para aprender a usarlos. Sin embargo los problemas surgieron al tratar de mostrar contenidos personalizados según el usuario. Aunque el sistema de control de acceso de Joomla permite diferenciar entre varios tipos de usuarios y restringir el acceso a usuarios no registrados, este sistema era insuficiente para ofrecer vistas personalizadas como se requiere en una Intranet. Para solucionar esto, primero se hizo una búsqueda sobre extensiones que proporcionaran un control de acceso más flexible. La única extensión libre que se recomendaba en los foros de usuarios era NoixACL. Esta extensión daba la posibilidad de crear grupos de usuarios nuevos y restringir el acceso a módulos y componentes según el grupo. Aun así no fue suficiente porque no era posible ocultar los elementos no accesibles, simplemente se denegaba el acceso mostrando un mensaje. Al final se optó por programar un componente que permitiera controlar el contenido según el usuario y aquí comenzó una larga tarea que culminó con la programación de un componente y tres módulos que permitían controlar el acceso y constituían el principal funcionamiento de la Intranet. 57 Esta tarea comenzó con un largo tiempo de documentación en los foros de desarrolladores de Joomla, y el seguimiento de tutoriales tanto para desarrollar componentes y módulos como para aprender PHP, HTML, SQL y algunas nociones de JavaScript. Después de aprender lo suficiente para poder desarrollar las aplicaciones se comenzó la implementación a partir de componentes de prueba que fueron modificados de forma incremental hasta conseguir una parte administrativa, donde configurar lo que debía ver cada usuario, y la parte del usuario que mostraba los contenidos según la configuración que se había definido. Como resultado final, se ha obtenido una Intranet donde los usuarios pueden tener acceso a los servicios requeridos según los productos que se han contratado y una parte administrativa donde se pueden poner servicios para nuevos productos, así como otorgar permisos a los usuarios para acceder a éstos. Además del servicio ofrecido, la parte administrativa ofrece la posibilidad de guardar los datos relevantes de los usuarios, así como de las empresas que son clientes. Desarrollar una Intranet a partir de un CMS es una tarea que en un principio no requiere grandes conocimientos informáticos y que podría estar al alcance de cualquiera. Si se tiene experiencia en el uso del CMS y se tiene una idea clara de la funcionalidad que debe tener la Intranet y de como puede conseguirse dicha funcionalidad sería una tarea relativamente sencilla. Además de lo sencillo que resulta aumentar la funcionalidad de un CMS a partir de la instalación de extensiones, el desarrollo de nuevos componentes para conseguir funcionalidades más concretas no resulta una tarea muy costosa. Pero para aprovechar estas facilidades se requiere un conocimiento previo del entorno de Joomla, de las posibles extensiones que pueden ser útiles y de las herramientas de programación necesarias para implementar nuevas funcionalidades. Sin embargo para el desarrollo de la Intranet el punto de partida era la idea de lo que se quería conseguir pero sin conocimiento previo de las herramientas necesarias para su desarrollo. Bajo estas circunstancias el desarrollo de la Intranet ha requerido un largo trabajo de documentación acerca del entorno y las posibles herramientas para llevar a cabo el proyecto. Las tareas de documentación han sido el verdadero trabajo a la hora de realizar este PFC, lo que ha llevado a adquirir valiosos conocimientos acerca sobre HTML, PHP, SQL y sobre el Framework de Joomla, también algunos conocimientos, aunque en menor medida, sobre JavaScript. 64 Anexo 3: .../components/com_soa/controller.php <?php defined( '_JEXEC' ) or die( 'Restricted access' ); jimport('joomla.application.component.controller'); require_once(JApplicationHelper::getPath( 'helper' , 'com_soa' )); class SoaController extends JController { function __construct() { parent::__construct(); } function cambio(){ $articulo = $_POST["cambiar"]; if($articulo != 0){ $pagina = 'Location: index.php?option=com_content&view=article&id='.$articulo; $this->redirigir($pagina); } else $this->presentacion(); } function redirigir($pagina) { header($pagina); } function ayuda() { $id_producto = JRequest::getVar( 'prod' ); JRequest::setVar('producto',$id_producto); $producto = new Producto($id_producto,''); $versiones = $producto->getListaVersiones(); foreach ($versiones as $version){ echo '<br><a href="index.php?option=com_soa&task=mostrar_ayuda&ver='.$version->datos->id .'">Ayuda para la version '.$version->datos->version.'</a><br><br>'; } } function mostrar_ayuda(){ $id_Version = JRequest::getVar( 'ver' ); $version = new Version($id_Version,''); $producto = new Producto($version->datos->id_producto); JRequest::setVar('producto',$producto->datos->id); if($version->datos->ayuda){ $pag = 'administrator'.DS.'components'.DS.'com_soa'.DS.'Productos'.DS.$producto->datos- >nombre.DS .'Ayuda'.DS.$version->datos->ayuda; echo '<iframe src ="'.$pag.'" width="100%" height="600">'; echo '<p>Texto alternativo para navegores sin soporte para iframes.</p>'; echo '</iframe>'; } } function descargar() { $id_producto = JRequest::getVar( 'prod' ); if(comprobarLicencia($id_producto)){ JRequest::setVar('producto',$id_producto); $producto = new Producto($id_producto,''); $descargas = getTabla_descargas($producto->getListaVersiones()); echo $descargas; } else{ echo ' NO TIENES LICENCIA PARA ESTE PRODUCTO<BR>'; $pagina = "Refresh: 3; URL=index.php"; $this->redirigir($pagina); } } 65 Function descargar_version() { $id_Version = JRequest::getVar('ver'); $version = new Version($id_Version,''); JRequest::setVar('producto',$version->datos->id_producto); $producto = new Producto($version->datos->id_producto,''); if(comprobarLicencia($version->datos->id_producto) || $version->datos->libre == 'Si') { descarga_producto($version,$producto); } else{ echo ' NO TIENES LICENCIA PARA ESTE PRODUCTO<BR>'; $pagina = "Refresh: 4; URL=index.php"; $this->redirigir($pagina); } } function contar() { $version = new Version(JRequest::getVar('ver'),''); if(comprobarLicencia($version->datos->id_producto) || $version->datos->libre == 'Si') { descargado($version); $enlace = $version->enlace(); $pagina = "Refresh: 1; URL=$enlace"; header ($pagina); $this->descargar_version($version->datos->id); } else{ echo ' NO TIENES LICENCIA PARA ESTE PRODUCTO<BR>'; $pagina = "Refresh: 4; URL=index.php"; $this->redirigir($pagina); } } function actualizar_tablas() { $user = JFactory::getUSER(); if($user->gid != 25){ echo 'Esta tarea solo esta disponible en modo Super Administrador'; }else{ $db = & JFactory::getDBO(); $query=""; $db->setQuery($query); if(!$db->query()) echo $db->getErrorMsg(); } } function presentacion() { $listas = listasSoa::getInstance(); $lproductos = $listas->getProductos(); $licencias = $listas->getLicencias(); foreach($licencias as $licencia){ $producto = $lproductos[$licencia->id_producto]; presentar_licencia($licencia,$producto); } } } 66 Anexo 4: .../components/com_soa/helper.php <?php defined( '_JEXEC' ) or die( 'Restricted access' ); class listasSoa { var $mySelf = null; var $listaProductos = array(); var $listaVersiones = array(); var $listaLicencias = array(); static function getInstance() { if($mySelf == null) $mySelf = new listasSoa(); return $mySelf; } function queryVersiones() { $user = Jfactory::getUSER(); $query = ' SELECT DISTINCT V.*, P.nombre as nombre_producto' . ' FROM #__0Productos P, #__0Licencias L, #__0Clientes C, #__0Versiones V ' . ' WHERE (L.id_producto = P.id AND L.id_cliente = C.id AND C.id_usuario = '.$user->id . ' AND V.id_producto=P.id AND V.nuevo like "Si") OR (V.libre like "Si" AND P.id=V.id_producto)' . ' ORDER BY V.libre, V.id_producto' ; return $query; } function getVerDis() { $db = &JFactory::getDBO(); if (empty( $this->listaVersiones )) { $query = $this->queryVersiones(); $db->setQuery( $query ); $this->listaVersiones = $db->loadObjectList(); } return $this->listaVersiones; } function queryProductos() { $user = JFactory::getUSER(); $query = ' SELECT P.*' . ' FROM #__0Productos P, #__0Licencias L, #__0Clientes C ' . ' WHERE L.id_producto = P.id AND L.id_cliente = C.id AND C.id_usuario = '.$user->id ; return $query; } function getProductos() { $db = &JFactory::getDBO(); if (empty( $this->listaProductos )) { $query = $this->queryProductos(); $db->setQuery( $query ); $datos = $db->loadObjectList(); foreach($datos as $prod) $this->listaProductos[$prod->id] = new Producto('',$prod); } return $this->listaProductos; } 67 function getLicencias() { if (empty( $this->listaLicencias )) { $user = JFactory::getUSER(); $db = &JFactory::getDBO(); $query = 'SELECT L.* FROM #__0Licencias L, #__0Clientes C ' .'WHERE L.id_cliente=C.id AND C.id_usuario='.$user->id; $db->setQuery( $query ); $this->listaLicencias = $db->loadObjectList(); } return $this->listaLicencias; } } class Producto { var $datos; var $versiones; var $licencia; function Producto($id, $data) { if(empty($data)){ $db = &JFactory::getDBO(); $query = " SELECT * FROM #__0Productos WHERE id = {$id} "; $db->setQuery($query); $this->datos = $db->loadObject(); } else{ $this->datos = $data; } } function getLicencia() { if(empty($this->$licencia)){ $user = Jfactory::getUSER(); $db = &JFactory::getDBO(); $query = 'SELECT L.* FROM #__0Licencias L, #__0Clientes C ' .'WHERE L.id_producto='.$this->datos->id .' AND L.id_cliente=C.id AND C.id_usuario='.$user->id; $db->setQuery($query); $this->licencia = $db->loadObject(); } return $this->licencia; } function getListaVersiones() { if(empty($this->versiones)){ $db = &JFactory::getDBO(); $query = " SELECT DISTINCT V.* FROM #__0Versiones V WHERE V.id_producto = {$this->datos->id} "; $db->setQuery($query); $datos = $db->loadObjectList(); foreach($datos as $version) $this->versiones[] = new Version('',$version); } return $this->versiones; } function show_logo() { echo '<a href="index.php?option=com_content&view=article&id='.$this->datos->articulo.'"><img SRC="administrator' .DS.'components'.DS.'com_soa'.DS.'Productos'.DS.'logos'.DS.$this->datos->logo.'"></a>'; } } 68 class Version { var $datos; var $licencia; function Version($id, $data) { if(empty($data)){ $db = &JFactory::getDBO(); $query = " SELECT V.*, P.nombre as nombre_producto FROM #__0Versiones V, #__0Productos P WHERE V.id = {$id} AND V.id_producto = P.id "; $db->setQuery($query); $this->datos = $db->loadObject(); } else{ $this->datos = $data; } } function enlace(){ $enlace = 'administrator'.DS.'components'.DS.'com_soa'.DS.'Productos'.DS.$this->datos- >nombre_producto; $enlace = $enlace.DS.$this->datos->url_descarga; return $enlace; } } function getTabla_descargas($lista_versiones) { $tabla = '<TABLE CELLPADDING=5 CELLSPACING=5 ALIGN="center" >' .'<div style="padding-left: 1px" >' .'<tr><thead ALIGN="center"><th ALIGN="center">Producto<th ALIGN="center">' .'Version<th ALIGN="center">Tipo<th ALIGN="center">Fecha de publicacion<th ALIGN="center">' .'Cerrada<th ALIGN="center">mantenimiento</thead></tr>'; foreach($lista_versiones as $version){ $tabla = $tabla. '<tr><td ALIGN="center">'.$version->datos->nombre_producto.'<td align="center">' .$version->datos->version.'<td ALIGN="center">'.$version->datos->tipo.'<td ALIGN="center">' .$version->datos->fecha_publicacion.'<td ALIGN="center">'.$version->datos->cerrada .'<td ALIGN="center">'.$version->datos->mantenimiento .'<td ALIGN="center"><a href="index.php?option=com_soa&task=descargar_version&ver=' .$version->datos->id.'">descargar</td></tr>'; } $tabla= $tabla.'</div></TABLE>'; return $tabla; } function descarga_producto($version,$producto){ echo '<TABLE CELLPADDING=5 CELLSPACING=5 >'; echo '<div style="padding-left: 1px" >'; echo '<tr><td>'; $producto->show_logo(); echo '<td ALIGN="center">'.$version->datos->nombre_producto.'<br>version '.$version->datos->version.'<br>'; echo 'Total descargas: '.$version->datos->descargas.'</td></tr>'; echo '<tr ><td collspan=2>'.'<a href="index.php?option=com_soa&task=contar&ver=' .$version->datos->id.'">descargar <IMG SRC ="images/filesave.png" align="center"></a>'; echo '</div>'; echo '</TABLE>'; echo $version->datos->extra; } 69 function descargado($version){ $db = & JFactory::getDBO(); $version->datos->descargas++; $query = "UPDATE #__0Versiones V SET V.descargas={$version->datos->descargas} WHERE V.id={$version->datos->id}"; $db->setQuery( $query ); $db->query(); } function comprobarLicencia($id_producto){ $db = & JFactory::getDBO(); $user = JFactory::getUSER(); $query = "SELECT L.* FROM #__0Licencias L, #__0Clientes C WHERE C.id_usuario = {$user->id} AND L.id_cliente = C.id AND L.id_producto = {$id_producto} "; $db->setQuery( $query ); $result = $db->loadRowList(); if(!empty( $result)) return true; else return false; } function comprobar_acceso_foro($idforo) { $db = & JFactory::getDBO(); $query = "SELECT id,parent FROM #__fb_categories WHERE published='1'"; $db->setQuery($query); $lista_foros = $db->loadObjectList('id'); $foro = $lista_foros[$idforo]; $query = ' SELECT P.id,P.foro FROM #__0Productos P'; $db->setQuery($query); $all_productos = $db->loadObjectList('id'); $listas = listasSoa::getInstance(); $lproductos_contratados = $listas->getProductos(); $foro_padre = $foro->parent; while($foro_padre != 0){ foreach($all_productos as $producto){ if($producto->foro == $foro->id){ $acceso = false; foreach($lproductos_contratados as $contratado){ if($contratado->datos->foro == $foro->id) $acceso = true; } return $acceso; } } $foro = $lista_foros[$foro_padre]; $foro_padre = $foro->parent; } return true; } function presentar_licencia($licencia, $producto){ echo '<TABLE CELLPADDING=7 CELLSPACING=5 BORDER>'; echo '<thead><tr><td rowspan="2">'; $producto->show_logo(); echo '</td><th align="center">Numero de Licencia</th><th align="center">Tipo' .'</th><th align="center">Licencias adquiridas</th><th align="center">Fecha Inicio' .'</th><th align="center">Fecha Fin</th><th align="center">Precio</th><th align="center">' .'Renovaciones</th></tr><td align="center">'.$licencia->NumeroLicencia.'</td><td align="center" width="100">' .$licencia->Tipo.'</td><td align="center">'.$licencia->Cantidad.'</td><td align="center">' .$licencia->FechaInicio.'</td><td align="center">'.$licencia->FechaFin.'</td><td align="center">' .$licencia->CantidadPagada.'</td><td align="center">'.$licencia->NumeroRenovacion.'</td></tr>' .'<CAPTION ALIGN=top><B>'.$producto->datos->nombre.'<BR></B></CAPTION></TABLE>'; }