Du plugin local_learning_analytics au plugin block_socialflow_analytics


A présent que les données pertinente sont stockées en base de données, il faut réussir à les exploiter pour afficher les indicateurs souhaités. Le défi consiste à réussir l’affichage des informations sur le flux social en veillant à optimiser au mieux les requêtes …

Procédure d’install

L’installation semble amener un plugin local et 5 rapports :

  • Modules du cours: visuel pour indiquer les visites par section, par type d’activité et par module les plus consultés
  • Tableau de bord du cours : tableau de bord global des visites dans le cours
  • Participants : affiche des infos sur les cours suivis en parralèle par les participants
  • Tests et devoirs : affiche la liste des tests et devoirs actifs
  • Infographie des requêtes : horaire de fréquentation du cours

Les 5 rapports sont inclus dans le dossier reports du plugin local.

Dans l’interface de Moodle, quand on est dans un cours, on peut accéder à une vue sur les différents rapports via le menu Plus > Statistiques d’utilisation.

Dans mon cas, il faudra composer un bloc qui s’inspire du rapport Modules du cours.

En base de données

RAS en base de données. A l’install, il y a juste une visite guidée qui s’installe.

Analyse du rapport activities

Pas simple de s’en inspirer car ce sont des indicateurs très différents.

Conception du bloc de Flux Social

La requête pour extraire la liste des activités du flux social

Il faut jouer avec une requête Group by et un order adapté pour obtenir la liste des éléments à afficher dans le flux social, avec une liste de cours donnée et pour une période de référence donnée.

SELECT contextid,eventid,COUNT(DISTINCT userid) AS hits FROM mdl_logstore_socialflow_log
WHERE courseid IN (7,8,9) AND timecreated > 1711362224
GROUP BY contextid, eventid
ORDER BY hits DESC;

Je me demande si le filtre sur la participation doit être appliqué d’entrée de jeu ou pas. Si je l’applique d’entrée de jeu, cela donne cette requête :

SELECT log.contextid,log.eventid,COUNT(DISTINCT log.userid) AS hits FROM mdl_logstore_socialflow_log log, mdl_logstore_socialflow_evts evts
WHERE log.courseid IN (7,8,9) AND log.timecreated > 1711362224 AND log.eventid=evts.id AND evts.actiontype IN ('consult','contrib')
GROUP BY log.contextid, log.eventid
ORDER BY hits DESC;

Pour remplacer l’ordonnancement sur base des hits par l’ordonnancement sur base des fréquences et je peux enregistrer le nombre de participants dans les cours de l’utilisateur dans le tableau associatif qui contient les information liées. C’est possible de faire une requête qui utilise cette valeur …

SELECT log.id, log.contextid,log.eventid,log.courseid, COUNT(DISTINCT log.userid) AS hits 
FROM mdl_logstore_socialflow_log log, mdl_logstore_socialflow_evts evts 
WHERE log.courseid IN (7,6,4,2,3) AND log.timecreated > 1711717211 AND log.eventid=evts.id 
GROUP BY log.contextid, log.eventid 
ORDER BY 
CASE 
WHEN log.courseid =7 THEN COUNT(DISTINCT log.userid)/24 WHEN log.courseid =6 THEN COUNT(DISTINCT log.userid)/2 WHEN log.courseid =4 THEN COUNT(DISTINCT log.userid)/1 WHEN log.courseid =2 THEN COUNT(DISTINCT log.userid)/2 WHEN log.courseid =3 THEN COUNT(DISTINCT log.userid)/1 END 
DESC; 
Relier le contextid à l’activité ciblée …

Dans la table logstore_socialflow_log, on a le contextid qui doit être reliée à l’activité ciblée.

Dans la table context, on retrouve le contextid dans le champ id et on a aussi un champ instanceid.

Dans la table course_modules, l’instanceid est repris dans le champ id. Et on retrouve 2 autres champs qui nous permettent d’accéder à l’activité ciblée:

  • module : indique un identifiant qui permet de savoir quel type d’activité est ciblée en recherchant dans la table modules;
  • instance : contient l’id de l’activité dans la table liée au type d’activité

Bref, 3 jointures, mais un seul résultat de recherche à chaque fois.

L’approche la plus simple me semble être de faire des requêtes successive pour extraire une ligne dans chaque table mais il faudra voir si c’est optimal :

supposons que les données de la ligne sélectionnées de la table logstore_socialflow_log soient enregistrées dans $contextid et $courseid

SELECT instanceid
FROM context
WHERE id=$contextid;

on récupère l'instanceid dans une variable $instanceid

SELECT module, instance, visible
FROM course_modules
WHERE id=$instanceid
si visible=0, on passe (pas utile de donner des infos sur une activité cachée)

notons $moduleid et $instance les variables de résultat

on récupère les informations importantes sur le cours
SELECT shortname
FROM course
WHERE id=$courseid
on enregistre le résultat dans une variable $courseshortname

on récupère l'info sur le type de module ciblé
SELECT name
FROM modules
WHERE id=$moduleid
le résultat est stocké dans une variable $modulename

on récupère enfin l'info sur l'activité ciblée par l'action:
SELECT name
FROM $modulename
WHERE id=$instance
on stocke le résultat dans la variable $customname

sur base de la valeur de $modulename, on récupère aussi le chemin vers l'icône liée via la fonction pix_icon
$moduleicon = $OUTPUT->pix_icon('iconname', 'iconalttext', $modulename, array('class' => 'iconlarge activityicon'));
Le résultat semble livré emballé dans la balise img.


sur base de l'eventid de l'événement, on récupère aussi l'information sur le type d'action (consultation ou contribution) et on stocke l'info dans $actiontype

et on a tous les éléments d'une ligne de flux social :
- $courseshortname avec un lien vers le cours $courseid
- $moduleicon qui semble contenir la balise img
- $curstomname dans une balise a avec un lien direct vers l'activité grace au $moduleid
- $actiontype qui suppose d'avoir une icône et/ou un texte avec traduction
- l'indicateur "Fait, Pas fait" pour l'utilisateur est généré sur base d'une simple recherche liée à son $userid dans la table des événements:
SELECT id
FROM logstore_socialflow_log
WHERE contextid=$contextid AND eventid=$eventid
AND userid=$userid
s'il y a au moins un ligne, l'utilisateur a fait l'activité ciblée.

Nombre de jours dédiés à cet article et au développement du plugin : 5 jours