Cambiar fechas de realización en un examen Moodle

A veces piden este tipo de cosas… Y el que diga que no. Miente. Dejando a un lado si es o no ético o con que fines se pueden querer manipular estos datos en una plataforma de e-learning voy a contaros en que tablas hay que tocar para dejar un examen a gusto del consumidor.

SELECT * FROM xxx.mdl_quiz_attempts where userid=nnnn;
update xxx.mdl_question_attempt_steps set timecreated=1415642340 where userid=nn and id in (a,b,c,d);

Con estas dos instrucciones correctamente montadas podremos cambiar las fechas de realización de un examen para un alumno, incluyendo las fechas internas (De cada pregunta). Hay que cambiar el prefijo de la BBDD (xxx), el id del alumno (nnnn), la fecha en segundos y los id’s de las preguntas (a,b,c,d).

Esto pude ser de utilidad http://currentmillis.com/

Nota: Desconozco si hay fechas (Que las habrá) en otras tablas, esto es solo una aproximación. Vamos que no es una ley, seguro que hay logs, y más sitios… Que no me venga nadie reclamando jajajaja.

Integración de usuarios WordPress con Moodle, Listado de cursos

Escenario: Tras integrar los usuarios de wordpres con Moodle necesitamos mostrar en WordPress un listado de los cursos en los que un alumno está matriculado en Moodle. Evidentemente el listado solo puede aparecer si el usuario está registrado y logado en WordPress. El enlace del curso debe llevar al alumno al curso dentro de Moodle con el usuario logado.

Requisitos en Moodle: Activar webservices

instalamos el plugin insert-php en nuestra instalación de WordPress, este plugin permite añadir código PHP a cualquier elemento tipo POST o PAGE. El código debe estar entre las etiquetas [insert_php][/insert_php]

// Necesitamos obtener el id del usuario logado en WordPress
global $current_user;
$idnumber = $current_user->ID;
$wsUrl = 'http://laURLdemoodle/webservice/rest/server.php';
$wsToken = 'eltokendemoodle';
        $curl = curl_init($wsUrl);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($curl, CURLOPT_NOBODY, false);
        $params = array(
            'wstoken' => $wsToken,
            'wsfunction' => 'core_user_get_users_by_field',
            'moodlewsrestformat' => 'json',
            'field' => 'idnumber',
            'values[0]' => $idnumber
        );
        curl_setopt($curl, CURLOPT_POSTFIELDS, $params);

        $info = curl_exec($curl);
         if (curl_errno($curl)!=0) {
            throw new \Exception(curl_error($curl));
	}
	$users = json_decode($info);

	if (count($users)!==0) {
		$user = $users[0];
		// Consultar los cursos en que está matriculado
		$params = array(
		    'wstoken' => $wsToken,
		    'wsfunction' => 'core_enrol_get_users_courses',
		    'moodlewsrestformat' => 'json',
		    'userid' => $user->id
		);
		curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
		$info = curl_exec($curl);
		 if (curl_errno($curl)!=0) {
		    throw new \Exception(curl_error($curl));
		}

		$courses = json_decode($info);
if (count($courses)!==0) {
			echo '<ul>';
			foreach ($courses as $course) {
echo "<li>[wp2moodle course='{$course->id}']{$course->fullname}[/wp2moodle]</li>";

			}
			echo '</ul>';
		}
	}

Aquí hay una pequeña salvedad. El plugin wp2moodle solo permite generar el enlace a Moodle pasando datos de grupos y cohortes… Nosotros necesitamos el curso.

Tenemos que modificar ambos plugins para que además de enviar los datos que lleva por defecto envíe el courseid del curso. No es una modificación compleja, pero si que requiere de conocimientos de programación PHP. En el lado de WordPress modificamos la función wp2moodle_handler para añadir el parámetro nuevo y wp2moodle_generate_hyperlink. Del lado de Moodle modificamos la página login.php para que reciba el id del curso y redirija a la página del mismo.

Objetivo conseguido. Desde WordPress accedemos directamente a un curso de Moodle.

Integración de usuarios WordPress con Moodle

Escenario: Necesitamos que al crear un usuario en una aplicación wordpress se genere automáticamente un usuario en Moodle con los mismos datos de acceso básicos (Nombre, apellidos, email, username y password). Tenemos las dos aplicaciones bajo el mismo dominio en directorios separados (/lms y /portal).

Necesario: Estos dos plugins. Uno en cada una de las aplicaciones.

Para instalar el plugin de WordPress, soltamos directamente el contenido en una carpeta “w2pmoodle” dentro de wp-content/plugins/ , lo activamos y lo configuramos.

Moodle Root URL: Http://ladireccióndeldominio/lms
Encryption secret: Unchurrodenumerosyletrasparalaseguridad (Luego lo usaremos en Moodle)
Update existing users: Yes

Para instalar la extensión en Moodle soltamos el contenido en una carpeta “w2pmoodle” dentro de “/auth”, activamos la extensión y vamos a su configuración.

Encryption key: Unchurrodenumerosyletrasparalaseguridad (La misma cadena que usamos en WordPress)
link timeout: 5
Logoff URL: A gusto del consumidor… puede ser la main de wordpress, por ejemplo.
Auto open course?: No
Update user profile fields using wordpress values?: No

Hasta aquí hemos terminado la primera parte. Ahora según las instrucciones de los plugins que hemos instalado, añadiendo enlaces del tipo [wp2moodle group='group2']A hyperlink[/wp2moodle] a cualquier elemento dentro de WordPress lanzaremos el evento que da de alta al usuario y matricula en grupos o cohortes (Que previamente debemos haber creado).

Esto en nuestro caso se nos quedaba corto, necesitábamos que la creación del usuario fuera inmediata sin dar de alta en ningún curso (Esto lo haríamos en procesos posteriores), tras validar que el usuario había pagado los cursos. Por tanto necesitábamos ir un paso más allá.

La creación de usuarios en WordPress pasa por la función edit_user() situada en wp-admin/includes/user.php por tanto cualquier acción que quisiéramos llevar a cabo debería pasar por dicha función. El plugin wp2moodle–wordpress- genera un enlace codificado que al llamarlo pasa por GET toda la información a Moodle para dar de alta al usuario, nuestro objetivo es generar dicho enlace y llamarlo de forma automática usando CURL. Para ello tuvimos que modificar la función que genera el enlace, ya que hace referencia al $current_user de WordPress y en nuestro caso necesitamos que sea del usuario que estamos creando. Lo vemos en código que queda mucho más claro.

include "../../wp-content/plugins/wp2moodle/wp2m.php";
...
function edit_user( $user_id = 0 ) {
...
// Vamos al final de la función
// actualizamos el id y mandamos el $user
$user->ID = $user_id;
$url = wp2moodle_generate_hyperlink_ikitonet ($user);
// Es una función modificada de la original
$ch = curl_init();
$options = array(
CURLOPT_RETURNTRANSFER => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTPHEADER => array('Content-type: application/html'),
CURLOPT_URL => $url
);
curl_setopt_array($ch, $options);
curl_exec($ch);

// return original de edit_user()
return $user_id;
}

Bien, hemos modificado la función de alta de usuario de wordpress para que al dar de alta un usuario llame por CURL a una URL, esta URL es la misma que genera el plugin “w2pmoodle”, con alguna modificación, en concreto le pasamos el $user… dejo aquí la función.

function wp2moodle_generate_hyperlink_ikitonet ($user, $cohort,$group) {
$update = get_option('wp2m_update_details') ?: "true";
$enc = array(
"offset" => rand(1234,5678),
"stamp" => time(),
"firstname" => $user->first_name,
"lastname" => $user->last_name,
"email" => $user->user_email,
"username" => $user->user_login,
"passwordhash" => $user->user_pass,
"idnumber" => $user->ID,
"cohort" => $cohort,
"group" => $group,
"updatable" => $update);
// encode array as querystring
$details = http_build_query($enc);
// encryption = 3des using shared_secret
return get_option('wp2m_moodle_url').WP2M_MOODLE_PLUGIN_URL.encrypt_string($details, get_option('wp2m_shared_secret'));
}

Objetivo conseguido. Cada vez que se genera un usuario en wordpress tenemos el mismo usuario en Moodle,se transmiten datos tanto en el alta como en la modificación. Moodle se guarda el id de wordpress en el campo “idnumber”.

Nota: Comprobado y funcionando con WordPress 3.9.1, 3.9.2 y Moodle 2.7
Nota: Puede ser necesario el módulo de PHP mcrypt

Mejoras estéticas en cursos Moodle

Si hay algo que siempre echaba para atrás a cualquier usuario de Moodle es su estética tosca y poco llamativa, por suerte con las últimas versiones se ha mejorado bastante en este aspecto pero los cursos siguen quedando muy de la mano del formador. Salvo que metamos algún formato de curso ya preparado que mejore ligeramente la presencia, al final el curso en Moodle no pasa de ser una simple lista de elementos a realizar.

Vengo trabajando desde hace tiempo en hacer estos cursos en Moodle más atractivos para los usuarios y hemos realizado algunas pruebas muy satisfactorias sin tener que modificar absolutamente nada en la configuración del LMS. Todo pasa por crear una plantilla bien vistosa y por utilizar algo de programación JQuery para modificar ciertos elementos de la misma.

El proceso puede dividirse en 6 pasos.

  • Pasando por manos de algún diseñador muy “apañao”, como ha sido mi caso, necesitamos una plantilla HTML+CSS. El diseño no requiere ningún requisito en especial pero si que debe contener elementos propios del curso, por ejemplo: La lista de exámenes, foros…
  • Una vez tenemos dicha plantilla HTML la podremos añadir a cualquier curso de varias formas, en cualquier caso usaremos siempre la actividad de tipo “Label” o “Etiqueta” que nos permite añadir contenido de texto, imágenes… Solo que en este caso pulsaremos el botón de vista HTML y pegaremos ahí todo el contenido de nuestra plantilla. La otra forma es crear en el directorio raiz de Moodle una carpeta donde meteremos todas las plantillas y las cargaremos igualmente mediante la actividad “Label” o “Etiqueta” con el siguiente código:
<script>
 $(function(){
 $("#includedContent").load("../cursos/plantillas/pla1.html");
 });
</script><div id="includedContent"></div>
  • Añadimos un tema de Moodle nuevo,  en nuestro caso hemos elegido uno que añade un menú para el usuario en la cabecera con los elementos más comunes.
  • Añadimos un formato de curso que mejora a los ya existentes, en nuestro caso hemos elegido uno en pestañas “TabTopics”.
  • Finalmente necesitamos añadir algo de programación JQuery a la plantilla que nos permita modificar el HTML, añadir y modificar ciertas funcionalidades (Ya que inicialmente está libre de elementos), en nuestro caso por ejemplo queremos que los foros del curso aparezcan listados en la plantilla en un elemento denominado “Comunicación”. Mediante JQuery buscamos los elementos de tipo “Foro” que además hemos creado con el prefijo [Foro] y los añadimos a la plantilla con un código parecido a este:
$("div.activityinstance").each(function (index){
var forumList = [];
var forumIndex=0;
var forum = [];
if (instancename.substring(0,7) == ("[Forum]") )
 {
 var forum = [];
 // Eliminamos cadenas de textos sobrantes
 instancename = instancename.replace("[Forum]", "");
 instancename = instancename.replace("Foro", "");
// Almacenamos
 forum[0] = instancename;
 forum[1] = $(this).find("a").attr("href");
 forumList[forumIndex] = forum;
 forumIndex=forumIndex+1;
 }
}
forumList.forEach(function(entry) {
 $("#foros").append('<li><a href="' +entry[1] + '"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;'+entry[0]+'</a></li>');
 });
  • Finalmente, para dar importancia a la presencia sobre la misma Moodle hemos decidido ampliar el espacio del curso y ocultar la barra lateral de opciones. Esto no implica una pérdida de funcionalidad para el usuario, ya que las opciones para un estudiante suelen ser pocas y hemos previsto que las más importantes ya están en la plantilla o en el menú de la cabecera. El código en nuestro caso (depende del tema de Moodle) es el siguiente:
$("#region-main").removeClass("col-md-9").addClass("col-md-12");
$("#region-main").removeClass("col-sm-8").addClass("col-sm-12");
$("#block-region-side-post").css("display","none");

Resumiendo.

Hemos cambiado totalmente la estética de un curso Moodle para los estudiantes cambiando el tema de Moodle, añadiendo un formato de curso más atractivo e insertando un elementos “Label” con un HTML+CSS+JQUERY dinámico que cargará todos los elementos y actividades que necesitemos.

Prometo poner capturas.

Gamificación de cursos en Moodle 2.7

La gamificación mola, está de moda, y no creo que te cruces con cualquier tecnócrata que no te suelte el dichoso término en cualquiera de sus discursos. Resumiendo mucho y aun a costa de que los expertos en el tema se me lancen al cuello gamificar no es más que aplicar dinámicas de juego a cualquier otro campo, tratando por tanto de ejercer algún tipo de alteración en el comportamiento normal del usuario y por supuesto aprovechar dicha alteración en nuestro favor.  La gamificación como tal tiene una vida muy corta de apenas un par de años, al menos aquí en España. Por ello Moodle no tiene actualmente nada, nada, nada y todo, todo, todo lo que queráis implementar va a ser siempre tirando de desarrollo o de pequeños trucos, atajos y hacks en el LMS.

En este artículo vamos a tratar de mejorar el aspecto visual de los cursos Moodle y a implementarles algunas de las dinámicas más comunes de gamificación, siempre dentro de las posibilidades del LMS, y en muchos casos rozando los límites del  ¿Y esto es gamificación?.

Realizaremos los ejemplos sobre un LMS Moodle 2.7, por ser la última versión que tenemos disponible, pero es muy probable que estos cambios  sean totalmente aplicables a versiones anteriores o posteriores.

Como requisito previo a cualquiera de los cambios que vamos a realizar se requiere que la plataforma tenga activados dos parámetros de configuración.

  • enablecompletion“. Habilitar el rastreo de finalización y activarlo por defecto en los cursos creados “moodlecourse | enablecompletion”, o habilitarlo al menos para el curso que queramos usar.
  • enableavailability“. Habilitar acceso condicional.

Moodle_gamificacion01

Con estos cambios en la configuración del LMS obtenemos varias ventajas, para empezar el LMS pasa a darse cuenta cuando un alumno ha finalizado alguna actividad y además podremos configurar las actividades para que permitan su acceso con condicionantes.

Utilizaremos como formato del curso el “formato de temas”, aunque con un poco de habilidad seguramente podríamos usar cualquier otro formato. En mi caso este me parece el más sencillo de usar.

Crearemos un curso en blanco con dos secciones. Una primera en la que vamos a insertar todo el contenido del curso y una segunda que utilizaremos más adelante.

Para una gran mayoría de las mejoras estéticas que vamos a implementar utilizaremos un recurso del tipo “Etiqueta”. que utilizaremos para añadir imágenes y texto dentro de nuestro curso.

Moodle_gamificacion02

Comenzaremos por crear una cabecera para nuestro curso, pensaremos en añadir alguna imagen impactante, muy visual y una descripción clara del contenido o del objetivo de la formación. El ancho de dicha imagen, y en general el ancho de todas las imágenes que vamos a usar depende del gusto de cada uno, debido a que no vamos a desarrollar contenido Responsive (No es el objetivo, por ahora) me he decantado por un ancho de 800Px y alto a discreción del consumidor. En la siguiente imagen podéis ver como con dos recursos  del tipo “Etiqueta” hemos creado una bonita y llamativa introducción para nuestro curso. (Esta imagen es de un proyecto de BBVA, espero que no se me enfaden).

Moodle_gamificacion03

Como veis en la introducción ya le estamos adelantando al alumno que mientras esté realizando el curso va a ir accediendo a una serie de “distintivos”, con esto ya al menos estamos fomentando su curiosidad.

Ahora procedemos a ir creando nuestro curso con cierta normalidad, solo quizás añadiendo recursos de tipo “Etiqueta” para separar elegantemente diferentes módulos o temas y siempre tirando de imágenes o textos muy llamativos. Por ejemplo…

Moodle_gamificacion04

Una vez tengamos nuestro curso completamente creado, con las pequeñas mejoras estéticas a base de etiquetas, procederemos a configurar todas las actividades. Básicamente iremos a editar cada una de las actividades y nos centraremos en los apartados “Restricciones de acceso” y “Finalización de actividad“.

Para este ejemplo vamos a configurarlas de una manera sencilla, permitiendo que el mismo alumno marque como finalizadas las actividades. En un entorno real lo más probable es que en lugar de permitir que el alumno marque las actividades como finalizadas prefiramos que la finalización sea marcada por alguno de las dos opciones que ofrece Moodle, que hayan entrado en la actividad o que hayan obtenido una calificación de aprobado.

Moodle_gamificacion05

En cuanto a las restricciones de acceso vamos a configurarlas según nuestras necesidades de una manera secuencial, no queremos que un alumno haga el examen 2 si antes no ha pasado por el examen 1 y no queremos que haga el examen 1 si antes no ha revisado la documentación.

Moodle_gamificacion06Observaréis que este apartado de configuración permite añadir una o varias restricciones, por tanto podremos hacer restricciones del tipo, “No quiero que esté accesible si antes no ha completado A,B,C y D). Aunque en honor a la verdad suele ser más sencillo configurar “No quiero que esté accesible hasta que no haya completado D” y configurar D para que exija el completado de C y C para que termine B…

Muy atentos al “true” que tengo marcado en la imagen, por defecto aparece siempre como “false” y es algo que no termino de ver claro. En versiones anteriores existía una opción que nos permitía decidir si el contenido se veía sombreado o no indicando las restricciones, esto es de mucha ayuda para que el alumno vea en todo momento como es el curso y que tiene que ir haciendo en lugar de tener un curso completamente vacío a la espera de que haga el primer elemento. Con este “true” hacemos esto, que se vea todo, pero no sea accesible. Bueno pues en Moodle 2.7 no veo esta opción, y parece que la única opción es modificar esta fórmula a mano.

Moodle_gamificacion07

Este proceso de modificar las restricciones y la criterios de finalización lo realizamos según nuestro interés con todas las actividades del curso.

Pasamos ahora a configurar las “medallas” que vamos a ir otorgando a los alumnos según realicen ciertas acciones. Usaremos de nuevo el recurso “Etiqueta” que colocaremos justo debajo de nuestra cabecera. Cada Etiqueta será un distintivo que tendrá, una imagen a la izquierda y un pequeño texto descriptivo del logro y que infunda un poco de ánimo al alumno. Por ejemplo, he creado un “logro” que se desbloquea al realizar todo el contenido de la primera unidad.

Moodle_gamificacion09

Como veis aparece sombreada, porque no será visible para el alumno hasta que complete el requisito “EXAMEN 01″, que además tengo configurado para que no sea accesible hasta que no haya hecho todo el resto del contenido. Os dejo aquí la configuración por si hubiera dudas.

Moodle_gamificacion10Atentos a “Showc”:[false], que en este caso no queremos que sea visible para los alumnos hasta que no hayan completado todas las restricciones. También atentos a que esta actividad no necesita ser rastreada para su finalización y mucho cuidado con configurar muy bien la restricción de acceso, no queremos que sea accesible a los alumnos antes de lo deseado.

Os dejo aquí otro ejemplo.

Moodle_gamificacion11

Como podéis ver hemos añadido otro logro que se lanza cuando se marca como finalizado todo el contenido opcional del curso y otro mucho más interesante. Una de las opciones que nos permiten añadir estas restricciones de acceso es un criterio totalmente personal, del tipo “No muestres este elemento a nadie, solo al que tenga tales apellidos”. Esto nos da mucho juego ya que podremos hacer que ciertas insignias o logros solo sean otorgados a algunos participantes del curso. Como podéis ver en este caso yo lo he configurado con un “No insertado” en Apellidos, con idea de que el Tutor del curso una vez  se acerque el final del curso pueda cambiarlo por los apellidos del alumno con mejor resultado. Con esto además insertamos una recompensa personalizada, en este caso un código promocional.

Moodle_gamificacion12En un próximo capítulo le daremos una nueva vuelta de tuerca al concepto de gamificación en Moodle, aunque ya he dejado alguna pista en una de las capturas.

Espero que os pueda servir de ayuda.

Mi nefasto Acer Aspire 5536G

Hay veces en las que por más que miras y remiras una compra antes de realizarla no sabes lo que te vas a encontrar después. En su momento cuando decidí comprar mi primer portátil hace ya unos años este modelo (Acer Aspire 5536G) era la mejor relación calidad precio, y pensé que sería una buena compra. Me equivoqué.

Para empezar la tarjeta gráfica ATI de 512Mb no tiraba de juegos, no es que uno se compre un portátil de 500€ y de pronto quiera que el último juego en salir te funcione a máxima calidad… No, es que al menos el juego pudiera jugarse con un mínimo de decencia. Todos por defecto tenía que ponerlos a la mínima calidad y con el mínimo de detalles para que el juego andase decentemente… No tengo claro si es realmente culpa de la gráfica o del micro, el caso es que no daba el rendimiento esperado.

La batería apenas aguantaba 2 horas, por lo que se limita por completo lo de “Portátil”, además apenas pasaron 2 años dejó de cargarse y tuve que comprar una nueva, esta vez si, con algo más de capacidad.

Temperatura. Terrible, se calienta muchísimo.

Pantalla. Lo que se vendía como lo mejor de lo mejor para ver películas, con sonido envolvente y pantalla home cinema y blablabla. Terminó por ser una tortura, cualquier leve roce con la pantalla, hacia que aparecieran pixeles negros,  un día un niño le dio con el dedo y me dejó un punto negro del tamaño de una moneda de 20 céntimos en todo el centro que no se quita de ninguna manera, si tratas de estimularlo de alguna manera no haces más que agrandarlo. Es la peor pantalla que he visto nunca.

Para colmo de males, la bombilla led de la pantalla comenzó a fallar a los tres años y a veces la pantalla que queda en negro… Ahora parece que no llega corriente y el cambio de pantalla puede irse a 150€ en una tienda o a unos 60€ si compro las piezas.

Aunque no me he metido a reemplazar la pantalla, se me ha ido por completo el “inverter” por lo que de vez en cuando la pantalla pierde la iluminación. La pieza, unos 12€.

¿Y cual es la tortura? Pues que a pesar de todos estos problemas el bicho funciona y en más de una ocasión he deseado que se casque de alguna manera para poder pasar página. desde luego tengo muy claro que Acer para mi termino con este portátil.

Si… lo sé, poner una crítica de un portátil que ya probablemente ni se venda es una tontería pero es algo que llevo sufriendo años y quiero desahogarme. Ahí queda.

Moodle desactivar suscripción e-mail a foro de novedades

Por defecto Moodle autosuscribe alforo de Novedades de los cursos en los que se encuentran matriculados los alumnos. ¿Como podemos desactivar esto?.

  1. Vamos al curso
  2. Activamos edición
  3. En el foro de novedades, pulsamos la tuerca… editar
  4. Desplegamos el apartado “Suscripción y seguimiento”
  5. En el campo ” modalidad de suscripción al valor “Suscripción opcional”

Y con esto ya la suscripción será decisión de cada alumno… Pero… ¿Que pasa si ya tengo 500 cursos y quiero desactivarlo en todos?, No, no tienes que hacerlo uno a uno.

Vamos a la BBDD y ejecutamos un simple update, en mi caso lo más fácil ha sido buscar por el nombre del foro que siempre es el mismo por defecto “Novedades”. Pero ojo que no tiene que ser así para todos.

update basededatos.mdl_forum set forcesubscribe=0 where name='Novedades';

Envío de e-mail desde Moodle con la función email_to_user

Desde las tripas de Moodle podemos enviar un correo electrónico a cualquier usuario (Previa configuración de servidor de correo).

La función es la siguiente:

/lib/moodlelilb.php

param: stdClass $user A {@link $USER} object
param: stdClass $from A {@link $USER} object
param: string $subject plain text subject line of the email
param: string $messagetext plain text version of the message
param: string $messagehtml complete html version of the message (optional)
param: string $attachment a file on the filesystem, relative to $CFG->dataroot
param: string $attachname the name of the file (extension indicates MIME)
param: bool $usetrueaddress determines whether $from email address should
param: string $replyto Email address to reply to
param: string $replytoname Name of reply to recipient
param: int $wordwrapwidth custom word wrap width, default 79
return: bool Returns true if mail was sent OK and false if there was an error.

Viendo los parámetros será fácil saber que necesitamos, básicamente un usuario que envía y un usuario que recibe, un asunto, un texto plano, un html si el alumno permite este tipo de contenido, adjunto… Para obtener un objeto del tipo stdClass de un usuario concreto usamos:

$to_mail = $DB->get_record('user', array('id' => '1449'));
$from_mail = 'Soporte Moodle';
$mailresult = email_to_user($to_mail, $from_mail, $subject, $messagetext, $messagehtml);

Esto mandará un correo con el remitente definido por defecto en Moodle (noreply) al usuario 1449. En el caso de que queramos modificar el remitente tendremos que recurrir a una nueva variable de tipo stdClass, algo así:

$to_mail = $DB->get_record('user', array('id' => 1448));
$from_mail = $DB->get_record('user', array('id' => '1'));
$from_mail->firstname = 'Soporte';
$from_mail->lastname = '';
$mailresult = email_to_user($to_mail, $from_mail, $subject, $messagetext, $messagehtml,null,null,true);

Modificamos el firstname y el lastname ya que la función genera el nombre uniendo estos dos campos.

Aumentar upload_max_filesize y post_max_size en nginx

Por motivos que no vienen al caso (Como casi siempre) me tengo que pelear a veces con algo diferente, acostumbrado al mas que trillado y no por ello mas conocido Apache, hace poco iniciamos un proyecto con un servidor web en auge, Nginx. Y muchos os preguntaréis, ¿Eso que es?, pues sin entrar en mucho detalle es el servidor web potente que se está usando desde hace tiempo en sitios con mucho, mucho, muchísimo tráfico… Seguro que algunos os habéis encontrado con un “404 Not Found / nginx” sobre todo en páginas porno, guarretes.

El caso es que subiendo archivos tuve que andar rebuscando la forma de cambiar la configuración por defecto para el tamaño de upload y de post de archivos. En primer lugar decir que la documentación de nginx brilla por su ausencia así que toca tirar de mucho blog y mucho foro. Lo primero localizar el php.ini. En mi caso la forma más facil fue usar un phpinfo(); en una php. Con esto sales por completo de dudas de la localización del php.ini y de los valores que tienes actualmente configurados.

Editamos el php.ini, en mi caso en “/usr/local/lib/php.ini”, buscamos los dos valores post_max_size y upload_max_filesize y los agrandamos al tamaño que necesitemos… En mi caso 200M.

Reiniciamos php y recargamos nginx.

/etc/init.d/php-fpm restart
/etc/init.d/nginx restart

Y listo.

Bloque Configurable reports Moodle 2.6, pequeños hacks

Hoy os voy a hablar de un bloque o extensión para Moodle, a día de hoy probado en la 2.6, que me está salvando muchísimas horas de desarrollo en lo referente a facilitarle al cliente consultas sobre el estado de los alumnos en el proceso formativo de una forma algo más clara y completa a como lo presenta la misma plataforma.

El bloque configurable reports de Juan Leyva , permite configurar informes con consultas de relativa complejidad al LMS, incluso algunas de ellas ya vienen completamente preparadas en su repositorio. Añade mejoras importantes como son el uso de paginación, orden mediante Jquery, descarga en XLS, CSV y ODS… Si sabes a lo que me refiero comprenderás que antes de lanzarte a programar una nueva consulta desde cero con este bloque puedes cubrir casi con total seguridad tus necesidades sin tener que tirarte horas y horas programando. Para rematar la faena permite crear una consulta a partir de SQL, con lo que las posibilidades se tornan prácticamente infinitas.

Un cliente muy exigente (Que raro), nos pedía una consulta que hacía un uso bastante intensivo de la base de datos por la gran cantidad de alumnos y datos de seguimiento que necesitaba. Se nos presentaron tres problemas principales:

  1. Al poner un filtro de cursos, el filtro aparece ordenado por el ID de la tabla, cosa poco útil para un manejo realmente rápido.
  2. Al ser una consulta tan bestia descubrimos que el bloque hace una “comprobación” de que es una SQL válida cada vez que entrábamos en la pestaña de edición del SQL. Esto nos tiraba el sistema abajo. ¿Por qué? Pues porque la ejecuta sin filtro, por lo que hace una consulta de la totalidad de los cursos del LMS.
  3. Unido al problema anterior teníamos que el bloque al ir a “View report” ejecuta igualmente una primera consulta sin aplicar el filtro, con un molesto “All” que de nuevo nos lo tiraba todo abajo.

Como el tiempo apremiaba y no podíamos empezar de cero tuvimos que hacer una serie de cambios de urgencia para no tener problemas de sobrecarga.

Modificar el orden del filtro de cursos.

Tocamos “components/filters/courses/plugin.class.php”, “function print_filter”
Añadimos simplemente el parámetro de ordenación ‘fullname’

$courses = $remoteDB->get_records_select('course',"id $usql",$params,'fullname');

Evitar la ejecución “All” al entrar en “View report”

Tocamos “components/filters/courses/plugin.class.php”, “function execute”

function execute($finalelements, $data){
$filter_courses = optional_param('filter_courses',0,PARAM_INT);
 if ($filter_courses==0)
 $filter_courses=1;
 if(!$filter_courses)
 return $finalelements;

 if($this->report->type != 'sql'){
 return array($filter_courses);
 }
 else{
 if(preg_match("/%%FILTER_COURSES:([^%]+)%%/i",$finalelements,
 $output)){
 $replace = ' AND '.$output[1].' = '.$filter_courses;
 return str_replace('%%FILTER_COURSES:'.$output[1].'%%',$replace,$finalelements);
 }
 } return $finalelements; }

Hemos añadido las líneas 3 y 4 del código anterior, al poner $filter_courses a 1 evitamos la primera ejecución y por tanto no hacemos una consulta sin filtro.

Evitar la validación de seguridad de las custom SQL

¡Ojo!¡Atención!¡Pánico! Esto solo se debe hacer si sabes muy bien lo que estás tocando, ya que impides que el formulario de SQL te reporte cualquier tipo de error… Tocamos “Components/customsql/form.php” dos funciones “validate_high_security” y  ”validate_low_security”. Comentamos la siguiente instrucción else en las dos funciones.

/* Comentamos esto para evitar una primera evaluación del SQL con "ALL"

 $sql = $this->_customdata['reportclass']->prepare_sql($sql);
 $rs = $this->_customdata['reportclass']->execute_query($sql, 2);
 if (!$rs) {
   $errors['querysql'] = get_string('queryfailed', 'block_configurable_reports', $db->ErrorMsg());
 } else if (!empty($data['singlerow'])) {
 if (rs_EOF($rs)) {
   $errors['querysql'] = get_string('norowsreturned', 'block_configurable_reports');
 }
 }
if ($rs) {
 $rs->close();
 }
 */

Con esto evitamos que el bloque revise la SQL y nos ahorra una ejecución sin filtro.
En resumen, un bloque magnifico que permite gran versatilidad y dar soluciones muy rápidas a necesidades muy concretas. Con las pequeñas modificaciones que hemos realizado (Entiendo que facilmente entendibles y trasladables a cualquier otro filtro, se parchean dos pequeños problemas muy párticulares que surgieron para casos muy concretos. Espero que pueda ser de ayuda a alguien.

Post Navigation