D ISEÑO DEL SISTEMA
6.1. Detalles de implementación
Como ya se ha comentado previamente las tecnologías utilizadas para el desarrollo del proyecto han sido, por el lado del servidor, PHP sobre el framework Codeigniter, utilizando una base de datos MYSQL, y por el lado del cliente ha sido desarrollado con HTML, CSS utilizando el framework Bootstrap, AJAX y JavaScript utilizando la librería JQuery.
A continuación se va a redactar los detalles de implementación y para ello se va a empezar comentando las rutas definidas para este proyecto y después se explicarán los detalles relacionados a la implementación de alguna de estas rutas, ya que muchas de ellas son muy similares y sería muy repetitivo. Cabe destacar que hay dos tipos de rutas definidas, las que se utilizarán para mostrar una página y las que serán usadas como API para agilizar las acciones mediante AJAX y no tener que recargar la página constantemente.
Antes de continuar se debe comentar que para conseguir que Codeigniter funcione como un API debemos utilizar una libreria proporcionada por un tercero, que puede ser encontrada en la url https://github.com/chriskacerguis/codeigniter-restserver, que permite de una forma muy sencilla crear un servidor REST.
Imagen I01: Ejemplo de implementación método PUT
Las rutas utilizadas para mostrar una página han sido las siguientes:
- R01: survey/(:num) - R02: control/surveys - R03: control/survey/(:num)
- R04: control/survey/(:num)/organize-questions - R05: control/survey/(:num)/statistics
Las rutas utilizadas para el API han sido las siguientes:
- R06: control/api-surveys/survey -> POST - R07: control/api-surveys/survey/(:num) -> DELETE - R08: control/api-surveys/survey/(:num)/organize -> PUT - R09: control/api-surveys/version -> POST - R10: control/api-surveys/version/(:num) -> PUT - R11: control/api-surveys/version/(:num)/activate -> PUT - R12: control/api-surveys/question -> POST - R13: control/api-surveys/question/(:num) -> PUT - R14: control/api-surveys/question/(:num) ->DELETE - R15: control/api-surveys/option -> POST - R16: control/api-surveys/option/(:num) -> PUT - R17: control/api-surveys/option/(:num) -> DELETE - R18: api-surveys/surveyed -> POST - R19: api-surveys/surveyed/(:num) -> PUT - R20: api-surveys/surveyedResponse ->POST
- R21:control/api-surveys/survey/(:num) -> PUT
- R22: control/survey/(:num)/statistics/export-data -> GET
Para definir las rutas en Codeigniter se utiliza, como ya se ha comentado, el fichero
routes.php. La estructura utilizada para definir dichas rutas es la utilizada en la siguiente
imagen, donde se puede apreciar que lo que se hace para definir una ruta es definir un
vector que tiene como clave el nombre de la ruta y como valor otro vector que debe ser
rellenado con una clave correspondiente a uno de los métodos HTTP y con el valor
correspondiente al método y controlador donde encontrar el código a ejecutar cuando se
acceda a esa ruta. Imagen I02: Definición de las rutas de la aplicación. La ruta R01: survey/(:num) es la utilizada públicamente por los encuestados para
contestar a una encuesta. Si el número que se pasa en la url no corresponde al identificador de una encuesta o
existe pero no está activa o no es pública el sistema mostrará un mensaje indicando que la encuesta no existe.
Si la encuesta existe el usuario se encuentra con un botón para iniciar encuesta. En
cuanto el usuario presiona el botón, mediante AJAX se hace una llamada al API para
crear un nuevo encuestado (api-surveys/surveyed). En caso de error se muestra un error
indicando el motivo. En caso de haber creado el encuestado correctamente se oculta el
contenedor (div) de inicio y se muestra el contenedor (div) de las preguntas, además, se
guarda el identificador del encuestado para usarlo posteriormente y se solicita preparar
la siguiente pregunta ($.nextQuestionStep()). Imagen I03: Método JavaScript para iniciar encuesta El método $.nextQuestionStep() se encarga de obtener la siguiente pregunta ($.nextQuestion()), en el caso de existir siguiente pregunta se actualiza la barra de
progreso ($.setSurveyProgress( númeroPreguntas, máximoPreguntas)) y se actualiza el
html en función a la actual pregunta ($.setActualQuestion(actualQuestion)). En caso de
no existir una siguiente pregunta se da paso a la finalización de la encuesta ($.finishSurvey()).
Imagen I04: Código para el cambio a la siguiente pregunta
El método $.nextQuestion() es el encargado de encontrar la siguiente pregunta, para ello, recorre los caminos todavía disponibles y de cada uno de ellos obtiene la questionWrapper correspondiente al identificador obtenido al acceder a la posición n (número de preguntas) del camino. Para cada uno de los wrappers obtenidos se comprueba si pasa los filtros necesarios para poder seguir el camino. En el caso de tener filtro “ELSE” ese camino se añade al final de todo el vector de caminos, para que solo sea seleccionado ese camino en caso de no haber otro disponible, y por lo tanto, cumplir la función de “else”.
Imagen I05: Código que devuelve la siguiente pregunta.
El método $.finishSurvey() simplemente esconde el contenedor de preguntas, muestra el
contenedor de finalizar encuesta, cambia el progreso de la barra al 100%, obtiene el
camino seguido por el usuario y finalmente realiza la petición AJAX al API para
actualizar el encuestado marcándolo como finalizado y guardando el camino seguido (api-surveys/surveyed).
Imagen I06: Código que finaliza la encuesta.
Para cargar los caminos tenemos el método $.loadQuestionsPath() que en función del siguiente JSON obtiene los caminos.
Imagen I07: JSON con los questionsWrappers
Este JSON es almacenado en el sistema cuando se guarda el diagrama al organizar preguntas. El JSON está formado por una lista de questionsWrappers, cada uno de ellos formados por su identificador, el identificador de la pregunta, una lista de identificadores de los questionsWrappers padres y un campo filtro con el código necesario para evaluar el filtro en javascript.
El método $.loadQuestionsPath() se encarga a partir del JSON de crear un mapa con clave identificador del questionWrapper y con valor un vector con sus hijos. A partir de este mapa se llama a una función recursiva que obtiene el vector con los posibles caminos.
Imagen I08: Código para la generación de los caminos
Para conseguir diferenciar una parte pública y una parte privada dentro de la aplicación se han utilizado los hooks de Codeigniter, que nos permiten programar orientado a aspectos para que se ejecute siempre el código contenido en el hook, en el caso de este proyecto se ha seleccionado la opción post_controller_constructor. Las partes de la aplicación que consiguen hacerse cargo de las comentadas sesiones son:
- El hook auth.php: Es el encargado de redirigir al login en el caso de no tener acceso a una parte de la aplicación.
- El controlador auth_c.php: Es el encargado de mostrar la vista de login, de verificar con el modelo si el login es correcto y posteriormente establecer la sesión.
- El modelo auth_m.php: Es el encargado de verificar si el usuario y contraseña son válidos.
- El fichero de configuración hooks.php: Es el encargado de activar el hook y definir la configuración de dicho hook.
- El fichero de configuración auth.php: Es el encargado de definir las partes públicas de la aplicación.