-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path11-Wordpress.Rmd
executable file
·611 lines (403 loc) · 78.2 KB
/
11-Wordpress.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
# Wordpress {#wordpress}
```{r setup, include=FALSE, echo=FALSE, message=FALSE, results='hide'}
knitr::opts_chunk$set(comment = '#', fig.align = "center")
#SciViews::R
```
La motivation principale de l'utilisation de [Wordpress](https://wordpress.org) dans la plateforme LearnIt::R est de pouvoir gérer pleinement des contenus **H5P** dans un bookdown ou dans un Quarto book, et de pouvoir enregistrer la progression des étudiants dans notre LRS. Cependant, étant basé sur un serveur LAMP (Linux-Apache-MySQL-PHP), Wordpress permet également d'utiliser des scripts PHP côté serveur pour implémenter des fonctionnalités qui seraient difficiles, voire impossibles avec un site statique à partir de bookdown. Ainsi, nous pouvons aussi y intégrer un enregistrement de l'utilisateur via GitHub (protocole OAuth2). Ceci est bien pratique pour faire le lien entre le travail de l'étudiant dans les exercices intégrés au bookdown d'un part, et son activité dans ses projets gérés par GitHub d'autre part. Un script PHP dans Wordpress permet aussi de récupérer des informations relatives à l'étudiant venant de Moodle, si ce dernier logiciel est également utilisé (mais cela reste optionnel).
```{block2, type="info"}
Nous avons choisi de privilégier l'authentification GitHub à celle pouvant provenir de l'institution où l'étudiant est inscrit pour les raisons suivantes :
- Il arrive qsue certains étudiants arrivent au cours sans être encore complètement inscrits, avec leur propre PC portable. Ils n'ont pas encore de login institutionnel et ne pourraient rien faire si le système dépendait exclusivement de ce login pour travailler. Avec GitHub, ces étudiants créent leur compte librement et sont immédiatement opérationnels.
- La plateforme LearnIt::R LRS est utilisable en dehors d'un contexte institutionnel (par exemple, pour une formation dans le cadre d'un workshop ou au sein d'une entreprise).
- Comme GitHub et GitHub Classroom occupent une place importante dans la plateforme au travers des projets, les étudiants doivent de toute façon créer et utiliser un compte GitHub. L'authentification via GitHub permet d'être certain que ce compte est créé et fonctionnel et que l'étudiant fournit effectivement son propre login.
Toutes ces raisons sont suffisantes pour que l'authentification GitHub soit considérées comme l'élément clé pour l'identification de l'étudiant dans LearnIt::R LRS. Ainsi pour éviter de multiplier les logins, l'identifiant Wordpress de l'étudiant sera toujours identique à son login GitHub avec cette façon de travailler (le compte Wordpress ne peut être créé *que* à partir de ce login GitHub).
```
Si vous utilisez uniquement un serveur statique bookdown hébergé sur GitHub Pages, Netlify, ou autre, vous devrez utiliser H5P.org (censé n'être utilisé qu'en test) ou H5P.com (très cher) pour publier vos exercices H5P. Dans LearnIt::R, vous n'aurez alors pas accès à différents fonctionnalités de la plateforme complète avec LRS, Wordpress et Posit Connect :
- Pas d'enregistrement des étudiants (suivi de progression impossible),
- Pas de service des applications Shiny et de learnrs. Vous devez faire exécuter ces applications en local sur l'ordinateur des apprenants via des packages R dédias au cours, voir pour un exemple, les packages R [BioDataScience](https://github.com/BioDataScience-Course/BioDataScience) et [BioDataScience1](https://github.com/BioDataScience-Course/BioDataScience1). Cela permet d'utiliser les learnrs, mais sans être vraiment très pratique pour les étudiants. TODO: il est prévu, en l'asence d'un LRS, de pouvoir enregistrer l'activité de ces application dans un dépôt GitHub, mais cette fonctionnalité n'est pas encore implémentée actuellement.
Au final, même si l'approche bookdown statique sur Github + learnr/Shiny en local permet d'obtenir le minimum de fonctions requises pour le suivi de la progression d'apprentissage des étudiants, ce n'est pas pratique à l'usage et il vous faudra dépanner souvent des étudiants...
## Agencement du site
La page principale de votre site Wordpress sert essentiellement à configurer le site lorsqu'elle est appelée depuis Moodle (enregistrement des données de l'étudiant dans un `localStorage`) et donne les instructions principales pour bien démarrer avec le contenu pédagogique. Cette page laisse une large place à gauche pour le login GitHub, quelques liens utiles (accueil, contact) et liste les différents bookdown disponibles, un par cours.
Chaque bookdown est dans une sous section du site, et reprend un numéro de version correspondant au début de à l'année académique : `/cours-2022/`, `/cours-2023/`, etc. Une fois la page principale activée depuis le lien Moodle **Cours**, l'étudiant peut aller vers le bookdown qui correspond à son cours et tout devrait fonctionner correctement. La page principale de chaque bookdown effectue de son côté les vérifications nécessaires, affiche un court compte-rendu, et permet d'effacer les données personnelles (compatibilité RGPD) si souhaité, voir \@ref(lrs).
Le site est complété d'une bannière supérieure dont l'aspect peut être personnalisé à travers les thèmes Wordpress et qui propose des liens vers différents items importants dans le cadre du cours pour obtenir de l'aide (Moodle, Issues, Email, ...), et donne aussi accès à l'explication pour installer le logiciel que l'étudiant va utiliser. Et c'est tout. Le but est de faire ici simple et efficace...
### Tableau de bord
Dès qu'un utilisateur s'enregistre sur le site, une barre supérieure noire apparaît avec des options supplémentaires en fonction de son rôle. Un étudiant a évidemment un nombre d'options limitées à l'édition de son profil et la consultation de sa progression H5P. Un éditeur (prof) peut aussi créer et modifier des pages. Enfin, un administrateur a accès à l'ensemble des fonctions pour personnaliser le site.
Pour tous les utilisateurs, un **tableau de bord** est accessible à partir de cette barre noire supérieure. Une fois le compte créé dans Wordpress, un étudiant a la possibilité de s'y connecter via GitHub et de modifier ses informations dans le tableau de bord, dont son adresse email. S'il le fait, cette adresse n'est alors plus la même que celle enregistrée initialement dans d'autres serveurs comme Posit Connect. C'est pourquoi, nous conservons ces deux informations séparément : `email` pour l'email du site Wordpress et `iemail` pour l'email institutionnel tel que renseigné à partir de Moodle. C'est toutefois l'adresse email enregistrée dans Wordpress qui est employée pour enregistrer les activités H5P. Pour les learnr et les app Shiny, c'est le login qui fait référence et qui doit être renseigné, sinon aucun enregistrement n'est réalisé (visiteur externe). Lorsque l'activité learnr ou app Shiny ne se fait, cela est indiqué par un message explicite pour éviter qu'un étudiant oublie de se logger, et puis que son travail soit perdu. Par contre, H5xAPIkatchu enregistre l'activité H5P sous un UUID créé à la volée. Nous pouvons toujours filtrer et éliminer ces données-là plus tard.
Par ailleurs, les évènements principaux H5P (début, fin, durée et résultat à la soumission des exercices) sont également enregistrés dans Wordpress directement. Cette information peut paraître redondante avec l'enregistrement H5PxAPIkatchu, mais elle est utile car l'étudiant ou l'enseignant y a accès directement dans son tableau de bord. Il peut y lire les détails de sa progression dans l'ensemble des exercices H5P de tous les cours, s'il le souhaite (voir capture d'écran). Reste à déterminer l'occupation disque de cette fonction afin de décider si nous la conservons activée sur le long terme\ !

Comme nous pouvons le voir, le tableau de bord de l'étudiant est réduit au minimum. En plus de la partie "H5P Content" où il peut voir et filtrer la liste des applications H5P et voir ses propres résultats H5P, il a accès à son profil où il peut modifier des données utilisées par nos outils. Il me semble que la maîtrise et la visibilité des données enregistrées le concernant font partie des contraintes RGPD pour lesquelles Wordpress assure la compatibilité.
Les enseignants sont enregistrés comme éditeurs sur le site. Dès lors, ils peuvent aussi modifier le contenu du site, et surtout, modifier et créer du contenu H5P avec des éditeurs conviviaux. Ainsi, l'ensemble des outils nécessaires pour l'édition du contenu sont regroupés dans ce tableau de bord... à l'exception des bookdowns et des applis Shiny/learnr. Ces dernières sont mise à disposition via un serveur RStudio Connect, totalement différent donc. Par contre, les bookdown doivent, eux, être intégrés dans le site. La façon de réaliser cette intégration est expliquée dans la section consacrée à bookdown (\@ref(bookdown)).
### Authentification des étudiants
Avec un site Wordpress correctement configuré pour s'intégrer dans la plateforme LearnIt::R LRS, l'authentification des étudiants se fait comme suit :
1. Vous ajouter un item de type "URL" dans Moodle pour transmettre au site Wordpress des informations relatives à l'utilisateur authentifié dans votre institution ("query string", c'est-à-dire la partie "?..." de l'URL). On obtient de cette façon, entre autres, son numéro de matricule, son adresse email, son nom et son prénom, le cours qu'il suit, ... Les détails sont dans la section correspondante (voir \@ref(moodle)) et ne seront donc pas discutés ici.
2. Dans Wordpress, vous pouvez intégrer une authentification sur base de leur compte GitHub via le protocole OAuth2 au travers d'une application qui fait le pont entre Wordpress et GitHub.

C'est doublement intéressant car vous obtenez ainsi leur login GitHub, et aussi, vous êtes certain•es que leur compte GitHub est créé et actif dès le moment où ils sont enregistrés dans Wordpress avec le *même* login. Que des avantages, donc. De plus, dans l'implémentation choisie, la connexion via GitHub montre clairement à l'étudiant s'il est connecté ou non.


Afin d'éviter que n'importe qui ayant un compte GitHub ne s'enregistre dans Wordpress, vous pouvez faire en sorte que vos étudiants doivent rappatrier leur identité à partir de Moodle avant de pouvoir se connecter via leur compte GitHub.. Dès que l'étudiant s'est enregistré, les données utiles venant de Github sont rentrées dans la table des utilisateurs Wordpress. Vous combinez les données provenant de Moodle et de GitHub pour établir un profil complet de l'étudiant dans votre site Wordpress automatiquement. A noter que Wordpress tente de récupérer aussi d'autres informations venant de GitHub, dont l'email. Cependant, ce dernier peut être caché dans le compte GitHub (c'est d'ailleurs le cas par défaut), et n'est donc pas accessible. La plupart du temps, vous n'avez donc que l'email institutionnel à disposition. **Dans la plateforme LearnIt::R LRS, vous pouvez utiliser l'email Wordpress, l'email institutionnel, ou le login Github de manière interchangeable selon le contexte comme identifiant**, mais seule la présence du login est vérifiée pour activer l'enregistrement de l'activité dans H5P/learnr/Shiny. Il reste souhaitable que l'étudiant indique le *même* email que son email institutionnel comme email primaire dans son compte GitHub, sans quoi, ses commits ne pourront peut-être pas lui être attribués dans GitHub. *C'est de sa responsabilité et actuellement, nous n'avons aucune visibilité sur l'email utilisé sous GitHub par l'étudiant dans l'implémentation mise en place^[Pour les enseignants, lors des premiers commits réalisés par vos étudiants, veuillez vérifier s'ils sont clairement identifiables. Sinon, faites corriger l'information (identifiant git et email).].*
### Variables contextuelles {#var-context}
Pour l'enregistrement de l'activité des étudiants, nous avons besoin de définir un certain nombre de variables reprises dans le tableau ci-dessous. Toutes ces variables sont obtenues directement à partir de Moodle, si cette plateforme est utilisée. La colonne origine indique d'où nous obtenons ces informations (il faut que l'étudiant ait cliqué sur l'item qui envoie ces informations depuis son compte Moodle et à partir de la page de cours correspondante).
| Variable | Contenu | Origine |
|:--------------|:----------------------------------------------------------------------|:------------------------------------------------|
| login | Le login GitHub de l'étudiant | WP via GitHub |
| email | Le mail renseigné dans Wordpress | WP via GitHub si public |
| displayname | Nom utilisateur Wordpress(/Github) | WP |
| firstname | Prénom comme indiqué dans Wordpress | WP |
| lastname | Nom de famille comme indiqué dans Wordpress | WP |
| iemail | Le mail UMONS (institutionnel) de l'étudiant | Moddle `iemail`= Adresse de courriel |
| iid | Numéro de matricule de l'étudiant | Moodle `iid` = Nom d'utilisateur |
| ifirstname | Prénom comme indiqué dans Moodle | Moodle `ifirstname` = Prénom |
| ilastname | Nom de famille comme indiqué dans Moodle | Moodle `ilastname` = Nom |
| institution | Institution (ici `UMONS`) | Moodle `institution` = Institution |
| icourse | Nom de code Moddle du cours (ex.: `S-BIOG-006`) | Moodle `icourse` = N° d'identification du cours |
| iurl | URL du serveur institutionnel (Moodle) | Moodle `iurl` = URL du serveur |
| iref | Identifiant unique dans Moodle | Moodle `iref` = Numéro d'identification |
| ictitle | Titre du cours (ex. Science des Données I: visualisation) | Moodle `ictitle` = Cours |
| icflag | Indicateur pour les étudiants suivants plusieurs cours simultanément | WP (éditeur des utilisateurs en mode admin) |
| user_login2 | Second login GitHub pour le même utilisateur | WP (éditeur des utilisateurs en mode admin) |
A noter que nous croisons différentes sources (Moodle, GitHub, Wordpress), et les infos peuvent différer entre ces sources. Considérant un étudiant qui a "installé" ses outils correctement, à savoir\ :
- Son compte est créé au préalable dans Wordpress via un enregistrement approprié (voir au début de la section),
- Il a créé un compte GitHub et y a renseigné son adresse mail UMONS,
- Il a au moins une fois lancé la page https://wp.sciviews.org depuis le lien Moodle "Cours" dans la section "Ressources en ligne" de son cours,
- Dans la page qui s'ouvre, il s'est connecté dans Wordpress à partir du bouton de login via GitHub/BioDataScience.
A ce moment-là, tout sera en place pour gérer correctement son identité dans les différents matériels pédagogiques (bookdown, H5P, learnrs, apps Shiny, etc.). Le seul point sur lequel il faudra rester vigilant est l'identifiant de l'étudiant pour ses commits, pour lequel nous n'avons pas de contrôle automatique pour l'instant. Il ne lui restera plus alors qu'à installer la SciViews Box pour être pleinement opérationnel. Cela semble être un nombre important d'opérations à réaliser pour arriver à cela, mais l'étudiant est guidé de manière naturelle\ : il va dans Moodle, se connecte et sélectionne le cours dans la liste (il a déjà l'habitude). A partir de là, il clique naturellement sur "Cours", d'où la page qui l'enregistre et lui propose de créer un compte GitHub. Une fois que c'est fait, il peut cliquer sur le gros bouton bleu "GitHub/BioDataScience" pour se connecter dans le site "Science des Données Biologiques", et il sélectionne le manuel correspondant à son cours dans la liste. A ce stade, c'est fait. Il est enregistré^[Il est conseillé aux enseignants de tester la procédure auparavant pour vérifier qu'ils en maîtrisent bien la logique.]\ !
```{block2, type="note"}
Faut-il *forcer* le login de l'étudiant dans Wordpress\ ? Autrement dit, il n'aurait accès aux cours que s'il est connecté. Il existe des plugins Wordpress qui permettent de faire cela, et aussi d'exclure les pages qui peuvent être vues par tous. Un de ces plugins est **[Force login](https://wordpress.org/plugins/wp-force-login/)**. Nous verrons à l'usage...
```
Toutes les informations de son compte sont accessibles à l'étudiant dans Wordpress, et il peut librement les modifier dans le tableau de bord, sauf son `login`. Donc, cela signifie que l'information cruciale pour identifier un étudiant est `login` qui est par ailleurs toujours le même que le login GitHub, et `iemail`, son adresse email de l'UMONS fournie par Moodle. Nous avons éventuellement besoin aussi de `email`, son email Wordpress sous lequel les activités H5P sont enregistrées.
Si nous continuons à utiliser Discord, ce serait bien d'avoir le login Discord de l'étudiant aussi. Mais ici, il a le droit d'y poser des questions de manière anonymisée (c'est notre souhait). Néanmoins, il serait utile d'avoir un champ où nous pouvons éventuellement rentrer cette info à la main si souhaité dans la liste des utilisateurs enregistrés dans Wordpress (TODO: vérifier si c'est possible). Une autre colonne `comment` serait aussi utile. Nous pourrions y indiquer par exemple si un étudiant a des difficultés particulières, ou la date de son arrivée pour les étudiants étrangers en passerelle, par exemple.
### Redirection d'URL d'iframe bookdown
Les contenus de type {bookdown} forment l'essentiel de l'information contenue dans le site. Cependant, ces pages sont générées indépendamment des pages Wordpress. Elles sont servies à partir du même domaine, mais pas réellement intégrées dans le site Wordpress lui-même. Elles y sont insérées dans un iframe géré par le plugin "Advanced Iframe Pro".
Une conséquence visible de cette organisation est l'URL qui présente de manière explicite le fait que la page bookdown est contenue dans un iframe. Par exemple pour https://wp.sciviews.org/sdd-umons-2023/nuage-de-points.html en présentation directe hors iframe, la même page est servie par le site Wordpress à https://wp.sciviews.org/sdd-umons/?iframe=wp.sciviews.org/sdd-umons-2023/nuage-de-points.html. Jusqu'ici tout va bien. L'adresse est un peu longue, mais ce n'est pas tellement grave en pratique.
Tout fonctionne bien, à part une petite subtilité concernant les **ancres**. Une ancre est un signet placé dans une page. Elle permet de l'afficher à partir de cet endroit au lieu d'afficher juste le haut de la page. Par exemple, la page `nuage-de-points.html` ci-dessus peut être affichée à partir du point "2.2.1 Echelles de graphiques" correspondant à l'ancre `échelles-de-graphiques` à l'aide de l'URL suivante : https://wp.sciviews.org/sdd-umons-2023/nuage-de-points.html#échelles-de-graphiques. Mais si nous rajoutons `#échelles-de-graphiques` à la fin de l'URL correspondante de Worpress, il ne se passe rien. La page s'affiche au début, et non pas au point 2.2.1 comme demandé. En fait l'ancre est interprétée pour la page de base Wordpress, pas pour la page contenue dans l'iframe. Pour corriger cela, il faut **URLencoder** l'ancre, qui consiste à remplacer le `#` par son code qui est `%23`. Ainsi, si on écrit https://wp.sciviews.org/sdd-umons/?iframe=wp.sciviews.org/sdd-umons-2023/nuage-de-points.html%23échelles-de-graphiques, alors l'ancre fait maintenant partie de l'URL de l'iframe et cela fonctionne comme prévu.
Vous noterez aussi que les ancres ne sont pas rajoutées automatiquement à l'URL lorsque vous cliquez dessus dans une page {bookdown} contenue dans un iframe. **Vous devez donc effectuer le rajout à la main si nécessaire pour enregistrer correctement cette URL.** En effet, "Advanced Iframe Pro" ne gère pas encore correctement les ancres de manière automatique. Une façon simple de découvrir l'identifiant d'une ancre consiste à cliquer bouton droit dessus et à choisir "Ouvrir dans un nouvel onglet" dans le menu contextuel. A ce moment, la redirection du lien cliqué dans l'iframe s'affiche dans une page séparée *hors iframe*, avec son URL complète, y compris son ancre. Copiez cette ancre et collez-là à la fin de l'URL de la page de départ avec iframe après modification du `#` en `%23`, et le tour est joué.
À part ces petits tracas relatifs aux ancres, les pages {bookdown} dans les iframes se comportent très bien par ailleurs et permettent de combiner le meilleur des deux mondes : Wordpress et ses nombreuses fonctions et plugins et {bookdown} pour un contenu riche créé à partir de documents R Markddown.
## Installation Wordpress
Vous devez choisir un hébergeur qui propose une solution LAMP (Linux + Apache + MySQL + PHP); si possible avec un Wordpress préconfiguré, c'est plus facile. Vous devrez aussi enrtegistrer un nom de domaine pour votre site, ainsi qu'un certificat pour pouvoir utiliser une adresse commençant par `https://`. Bien sûr, tout est plus facile si votre site est configuré sur les serveurs de votre institution par votre service informatique. Une fois cela réalisé, vous devrez installer et configurer quelques plugins Wordpress.
### Plugins Wordpress
Les extensions suivantes sont à installer (les versions correspondent à la configuration de Wordpress au 05/01/2022 et sont toutes à jour à cette date) :
- **[H5P](https://fr.wordpress.org/plugins/h5p/) 1.15.3**. Il faut installer les libraires séparément et les principales ont été rajoutées dès le départ. Les 5 ou 6 widgets H5P que nous avions déjà créés sont facilement importés en les exportant de leur site original au format `.h5p` en cliquant sur le bouton `Reuse` en bas à gauche du widget. Ensuite dans Wordpress, on va dans le tableau de bord -> H5P Content, on clique `Add New` puis `Téléverser` et on sélectionne le ficher `.h5p`. Une sauvegarde de ces fichiers `.h5p` est également effectué sur p-Cloud dans le dossier `sdd_h5p_backup`. Le plugin est ensuite configuré pour ne pas montrer la bannière H5P en bas des widgets et pour générer tous les événements xAPI possibles (voir \@ref(h5p)).
- **[SNORDIAN's H5PxAPIkatchu](https://fr.wordpress.org/plugins/h5pxapikatchu/) 0.4.11** capture les évènements xAPI générés par H5P et les stocke directement dans la base de données MySQL liée à Wordpress. Il y a une interface simpliste pour visualiser les tables, les filtrer et les exporter au format CSV. Nous avons patché cette version pour y rajouter l'enregistrement des évènements xAPI directement dans notre base de données MongoDB Atlas, et n'utiliser l'enregistrement local original que comme solution d'appoint au cas où l'enregistrement en MongoDB s'avère impossible pour une raison ou une autre (base saturée, indisponible, erreur, ou port 27017 de MongoDB bloqué). **Attention\ : depuis la version 0.4.7, il faut activer l'option "Embed support", sinon, les exercices H5P des pages bookdown ne sont pas enregistrées à partir de certains navigateur Web (testés avec la version 0.4.11\ : Safari et Chrome sous MacOS Big Sur, Edge et Chrome sous Windows 10 et Chromium et Firefox sous Ubuntu 20.04LTS).**
- **[OAuth Single Sign On](https://fr.wordpress.org/plugins/miniorange-login-with-eve-online-google-facebook/) - SSO (OAuth Client) 6.21.6** configuré pour enregistrer et connecter un utilisateur via son compte Github. Pour permettre ceci une application Github nommée **BioDataScience** a été créée sur Github. La configuration de ce plugin est disponible depuis le tableau de bord de Wordpress -> miniOrange -> OAuth.
- **[Import and export users and customers 1.19.1.2](https://fr.wordpress.org/plugins/import-users-from-csv-with-meta/)** permet d'exporter un tableau contenant tous les utilisateurs enregistrés dans Wordpress, accompagné des métadonnées. Ce tableau CSV est ensuite lu par la fonction `sdd_users()` pour créer les informations utilisateurs accessibles par Posit Connect et les learnrs/apps Shiny exécutées directement dans la SciViews Box. Sa fonction d'importation des données permet de mettre à jour rapidement des données et métadonnées relatives à un grand nombre d'étudiants en une seule fois à partir d'un tableau CSV.
- **[Advanced iFrame](https://fr.wordpress.org/plugins/advanced-iframe/) Pro 2021.9** permet d'insérer un iframe avec plein d'options : sécurisation, adaptation de la taille, passage de paramètres, réécriture d'URL, etc. Nous utilisons ce plugin pour intégrer les bookdowns dans le site Wordpress, et ainsi conserver la bannière supérieure de notre site tout en affichant le bookdown. La version standard est installée depuis le site plugins Wordpress. Il vous faut cemendant activer la version PRO pour une some modique afin d'accéder à toutes les fonctionnalités requises. Pour la mise-à-jour, on télécharge la nouvelle version sous forme de fichier zippé depuis Evanto, on supprime l'ancienne version (config conservée), et on installe la nouvelle version en téléversant le fichier .zip. La configuration est telle qu'elle correspond au code suivant (qui peut être utilisé tel quel sans modifier par ailleurs quoi que ce soit dans les boites de dialogue) :
```
[advanced_iframe use_shortcode_attributes_only="true"
src="//www.tinywebgallery.com/blog/advanced-iframe"
width="100%" height="600" add_iframe_url_as_param="same"
show_iframe_loader="true" enable_responsive_iframe="true"
hide_elements=".tg-site-footer-bar,.entry-footer" additional_height="100"
multi_domain_enabled="false" use_post_message="false"]
```
- **[My Custom Functions](https://fr.wordpress.org/plugins/my-custom-functions/) 4.51** permet de rajouter des fonctions PHP au site sans devoir créer de plugin Wordpress pour cela et sans "polluer" les autres fichiers (comme `functions.php` du thème). Les fonctions rajoutées créent des variables dans `localStorage` du browser web sur le client pour l'identification de l'étudiant entre bookdown, H5P et les applis Shiny/learnr, pour enregistrer les évènements H5P xAPI dans MongoDB Atlas via H5PxAPIkatchu, et pour modifier Wordpress de manière cosmétique (pas d'icône Wordpress dans la barre du haut, logo et lien BioDataScience dans la page de login).
- **[WP User Avatars](https://wordpress.org/plugins/wp-user-avatars/) 1.4.1** permet de gérer les avatars des utilisateurs. Nous l'employons pour placer les photos de chaque étudiant issues des données UMONS. Pour l'instant, nous devons vérifier chaque utilisateur manuellement et rajouter ces photos à la main... mais au moins, ce plugin permet de le faire.
- **[UpdraftPlus](https://fr.wordpress.org/plugins/updraftplus/) 1.16.69** comme système de sauvegarde de l'ensemble (fichiers Wordpress + base MySQL). Le backup se fait en local pour l'instant dans `lamp0/web/vhosts/wp.sciviews.org/htdocs/wp-content/updraft`, mais il est recopié manuellement par sFTP sur un disque de backup ou de toute autre manière qui vous convient.
- Quelques autres plugins ne sont pas essentiels, mais aident à gérer le site Wordpress\ : **[Broken Link Checker](https://fr.wordpress.org/plugins/broken-link-checker/) 1.11.16**, **[Health Check & Troubleshooting](https://fr.wordpress.org/plugins/health-check/) 1.4.5**, **[WP-Optimize](https://fr.wordpress.org/plugins/wp-optimize/) 3.2.1**, **[WP Rollback](https://wordpress.org/plugins/wp-rollback/) 1.7.1** & **[WordPress REST API Authentication](https://wordpress.org/plugins/wp-rest-api-authentication/) 1.6.6**.
Tous ces plugins sont distribués sur le site plugins de Wordpress, sont à jour et activement maintenus, avec un grand nombre d'utilisateurs. Nous avons évité les plugins plus "confidentiels" pour lesquels nous ne sommes pas certains de la pérennité à plus long terme. **Note : en janvier 2022, nous avons recherché la compatibilité PHP 8.0 de ces plugins dans la doc, mais sans les tester. Nous avons trouvé des indications de compatibilité pour tous sauf OAuth SSO, Wordpress REST API, WP Rollback, WP User Avatars & Health Check & Troubleshouting. Nous n'avons pas non plus trouvé d'indications de compatibilité pour le thème Zakra utilisé (voir ci-dessous). De plus, il faudra faire une mis-à-jour des fichiers composer pour l'extension MongoDB pour PHP !**
### Thème du site
Un site Wordpress est complètement paramétrable et son apparence peut être facilement modifiée à l'aide de thèmes. Il en existe beaucoup. Nous vous conseillons [Zakra](https://fr.wordpress.org/themes/zakra/) version "free", à jour, activement maintenu et totalement personnalisable. En jouant sur les options uniquement, nous avons pu façonner le site de telle manière qu'il reprenne une identité et les couleurs UMONS, tout en restant le plus simple, intuitif et facile d'accès possible.
### Configuration serveur et git
Simple hosting de Gandi.net permet d'accéder aux fichiers sur le serveur de trois façons :
- Par sFTP (TODO: détails)
- Par Console SSH (TODO: détails). La console n'est pas active en permanence. Il faut l'activer dans le panneau de configuration du simple hosting sur Gandi.net. Cette activation reste valable pour 2 heures seulement par sécurité.
- Via git. C'est le plus simple pour développer et synchroniser son site. C'est d'ailleurs aussi la seule façon de faire pour ajouter des dépendances à PHP via composer (et nous aurons besoin de rajouter une dépendance par rapport à MongoDB pour enregistrer les évènements H5P xAPI dans notre base de données).
#### Sécurisation du site Wordpress
- Modification du fichier `.htaccess` dans `htdocs`. Afin d'éviter des attaques de type [pingback xmlrpc](https://perishablepress.com/wordpress-xmlrpc-pingback-vulnerability/) sur le site Wordpress, il faut rajouter la ligne suivante dans le fichier `.htaccess`0 :
```
RewriteRule ^xmlrpc\.php$ "http\:\/\/0\.0\.0\.0\/" [R=301,L]
```
- Utilisation des plugins "Health Check & Troubleshooting" et "WP-Optimize" pour diagnostiquer et remédier aux problèmes potentiels. Un seul problème reste impossible à résoudre pour l'instant, il s'agit de "A plugin has prevented updates by disabling `wp_version_check()`." qui peut avoir de nombreuses origines, et dans le cas de notre site, nous n'avons pas pu détecter la cause. Même en désactivant tous les plugins et le thème, le message reste. Un autre avertissement concerne la conservation de thème inutilisés. En effet, nous conservons les thèmes par défaut de Wordpress "Twenty Twenty" et "Twenty Twenty-One" car il est conseillé de les garder, au cas où Zakra aurait des problèmes. Enfin, nous utilisons aussi "Broken Link Checker". Cet outil détecte les URL incorrectes dans la pages Wordpress uniquement (pas dans les bookdowns, donc), mais cela aide. Les "issues" étant des liens qui nécessitent une authentification, cet outil les détectent tous les quatee comme incorrects, mais nous pouvons ignorer ces avertissements également. Pour tester les liens dans les bookdowns, nous utilisons un plugin Chrome en plus.
- Nous avons aussi utilisé l'outil de sécurité et d'audit de Chrome dans les outils développeurs pour détecter les failles éventuelles et les erreurs côté client (Javascript, CSS, ...), et nous assurer que le site est sain. Globalement, il n'y a pas de failles majeures, mais certains aspects pourraient être améliorés pour avoir un site plus rapide, par exemple. Nous examinerons ces points plus tard.
#### Utilisation de git {#wordpress-git}
Il faut git et un client SSH installé (pas de problèmes pour macOS ou Linux). Les infos pour utiliser git sont dans la page de gestion du site sur Gandi.net. Dans un premier temps, l'identification se fait via un mot de passe. Voici comment cloner le dépôt git à partir d'un répertoire racine de votre choix, mais nous aurons absolument besoin que ce répertoire racine soit le même que celui où les dépôts GitHub de votre organisation sont également placés (sur macOS, il est facile de s'y placer en tapant `cd` suivi d'une espace, et puis en allant faire un drag&drop du dossier depuis le Finder vers le terminal, puis d'exécuter cette commande).
```
# Placez-vous dans le bon dossier
#cd <dossier racine des dépôts BioDataScience-Course>
git clone git+ssh://<ID>@git.sd3.gpaas.net/<SITE>.git
```
Accepter (`yes`) pour le message relatif à l'authenticité, puis rentrer le mot de passe d'administration du site. **Vérifier que les fichiers du dépôt git ont bien été rajoutés dans le dossier avant de continuer.** Avant de pouvoir effectuer un push via GitHub Desktop, il faut avoir configuré git correctement et avoir une clé SSH.
```
git config --global user.name <username>
git config --global user.email <user@email.com>
# Générer une clé SSH pour l'authentification
ssh-keygen -t rsa -b 4096 -C '<user@email.com>'
```
Une fois la clé SSH générée, copier le contenu de la clé publique `~/.ssh/id_rsa.pub` d'une part vers "SSH Keys" dans GitHub -> Settings -> SSH and GPG Keys (pour être aussi en ordre vis-à-vis de GitHub), et d'autre part, la fournir à l'administrateur de votre serveur Wordpress afin qu'il l'ajoute dans le panneau principal `Simple hosting` de Gandi.net (note : dans la section sécurité, cliquer sur "Ajouter une clé SSH". Puis créer une nouvelle clé et y coller le contenu).
**Avant de travailler dans un des bookdowns du cours, toujours se mettre à jour en local en faisant un pull dans le dépôt GitHub depuis RStudio, ainsi qu'un pull ou un fetch depuis GiHub Desktop sur le dépôt créé ci-dessus** Essayez une petite modification anodine dans votre dépôt git en local, puis commit et push sur GitHub. A ce stade, ce sont les *sources* du bookdown qui sont synchronisées. Allez ensuite dans GitHub Desktop au dépôt et faites-y également un commit, et puis un push ou fetch. A ce moment-là, les pages du bookdown sont synchronisées avec le dépôt git de Gandi.net, mais pas encore *publiées* sur le site wp à ce stade ! Il faut **déployer** ces changements en faisant dans une fenêtre terminal :
```
cd <Répertoire de base qui contient le dossier wp.sciviews.org>
ssh <ID>@git.sd3.gpaas.net 'deploy <SITE>.git'
```
Le `deploy` ajoute des nouveaux fichiers et remplace les fichiers existants sur le site (à condition que le droit en écriture sur les fichiers soit OK). Par contre, il n'élimine pas de fichiers. On risque donc d'accumuler des fichiers devenus inutiles au fur et à mesure de l'édition des blogdown. Si cela ne devrait pas impacter l'affichage des pages, cela utilise inutilement de l'espace disque sur le serveur. Ne procédez **jamais** à un nettoyage complet avec `clean` : cette instruction effacerait toute la configuration et la base de données de votre site Wordpress par la même occasion !
### Ajout de mongodb pour PHP
Le serveur sur Gandi.net n'autorise qu'une seule manière de rajouter des dépendances pour PHP : via git + ssh en utilisant `composer`. Et il faut créer les fichiers `composer.json` et `composer.lock` sur une machine locale avant de pouvoir faire un push sur le serveur. Cela signifie d'avoir PHP et la dépendance mongodb pour PHP installés localement. Ceci n'est pas facile, et il faut les mêmes versions que sur le serveur.
- Noter la version X.Y de PHP utilisée sur le serveur (ici 7.3). Il faudra la même en local.
- Aller dans MongoDB Atlas et regarder la version de MongoDB déployée (ici 4.2). Il faudra une version de l'extension MongodB qui supporte à la fois la version de PHP et celle de MongoDB qui gère notre base de données.
- Rechercher la version compatible dans le tableau relatif à PHP [ici](https://docs.mongodb.com/drivers/php/). Nous pouvons voir qu'il nous faut l'extension 1.6+ ou 1.7+, avec la librairie 1.5 ou 1.6, respectivement, et par ailleurs cette version de l'extension est bien compatible avec la version 7.3 de PHP.
- Installer un (X)Ubuntu d'un version telle qu'il propose la bonne version de PHP dans VirtualBox. La 18.04LTS utilise PHP 7.2, pas bon. La 20.04LTS utilise la version 7.4 de PHP. Au final, une 19.10 convient, et c'est la version la plus récente avant qu'Ubuntu ne passe à PHP 7.4. Une machine virtuelle préinstallée peut être téléchargée depuis [Osboxes](https://www.osboxes.org). La façon de l'installer dans VirtualBox est expliquée sur le site. Le disque virtuel initial de la machine occupe 5,89Go.
- Configurer la machine virtuelle dans VirtualBox pour avoir un dossier partagé, par exemple 'Desktop' partagé en 'MacDesktop', avec connexion automatique.
- Lancer la machine virtuelle. Login : "oxboxes", mot de passe : "oxboxes.org", mais attention, en clavier configuré QWERTY. Avec un AZERTY, il faut entrer en fait "oxboxes:org" comme mot de passe.
- Aller dans le panneau de configuration et changer le clavier (belge, ou français (Macintosh) par exemple).
- Lancer un terminal et exécuter les lignes suivantes :
```
# Rendre le dossier partagé VirtualBox accessible pour l'utilisateur oxboxes
sudo usermod -aG vboxsf osboxes
# Mettre la machine à jour
sudo apt update
sudo apt upgrade
sudo apt autoremove
sudo apt autoclean
sudo apt clean
# Redémarrer
sudo reboot
```
- Il se peut que la machine virtuelle rebascule en QWERTY. Vérifier et corriger à nouveau. Ensuite, installer PHP et ses dépendances nécessaires :
```
sudo apt install php7.3-cli php7.3-dev php-pear php-mongodb composer
```
Ensuite, nous devrions pouvoir créer les fichiers nécessaires via la commande `composer require mongodb/mongodb`, mais cela ne fonctionne pas lorsque `php-mongodb` est installé via le package Ubuntu. Nous devons le compiler nous-même avec `pecl` sur la machine^[Créer `composer.lock` via la commande `composer update` en ayant été écrire à la main un `composer.json` qui contient les lignes minimales renseignées sur la page d'aide de [Gandi.net](https://docs.gandi.net/fr/simple_hosting/langages/php.html#sommaire), mais cela donne une version trop ancienne du driver !] :
```
# Créer un répertoire dans le dossier partagé et s'y placer
mkdir /media/sf_MacDesktop/php-mongodb
cd /media/sf_MacDesktop/php-mongodb
# Compiler mongodb depuis les sources
sudo pecl install mongodb
# Créer composer.json et composer.lock (entre autres)
composer require mongodb/mongodb
```
Pour Xubuntu 20.04LTS et mongodb dernière version pour PHP 7.4, vous pouvez faire :
```
sudo apt install php7.4-cli php7.4-dev php-pear php-mongodb composer
mkdir ~/Desktop/php-mongodb
cd ~/Desktop/php-mongodb
sudo pecl install mongodb # Fails because it is not indicated in php.ini
# But the compilation of the .so file did succeed
composer require mongodb/mongodb # Warnings about deprecated composer 1 ignored
```
- Copier `composer.json` et `composer.lock` ainsi obtenus à la racine du dépôt git, faire un commit, un push et un deploy (`ssh <ID>@git.sd3.gpaas.net 'deploy wp.sciviews.org.git'`). Cette fois-ci MongoDB PHP 1.6 semble s'être bien installé sur le serveur lors du deploy, mais pour l'upgrade à 1.11, il m'indique que je n'ai pas mongodb-ext 1.12.0, mais 1.10.0. Ceci peut aussi être vu à la console avec :
```
#php --ini
php -m # mongodb must be listed
php --re mongodb | head -1
```
Cela signifie que la version max. de MongoDB lib qui peut être installée avec mon PHP 7.4 est la 1.9 si je ne veux pas mettre à jour également mongodb-ext. Donc :
```
sudo pecl uninstall mongodb
sudo pecl install mongodb-1.10.0
composer require mongodb/mongodb ^1.9
```
Maintenant, vous avez les bons `composer.json` et `composer.lock` pour une version reconnue par MongoDB 7.0 (avec une limitation en lecture, mais ici, on n'accède que en écriture). Faire commit, push et deploy et vérifier que tout se passe bien.
- Faire un test dans Wordpress. Aller jusqu'à une contenu H5P quelconque sur le site et interagir avec lui. Aller ensuite voir si les données correspondantes ont bien été enregistrées dans notre MongoDB ATLAS, dans la collection `sdd.h5p`. Si pas, vérifier si ces mêmes données sont enregistrées dans H5PxAPIkatchu dans le tableau de bord Wordpress. Si c'est le cas, c'est un problème d'accès à la base de données MongoDB ATLAS, sinon, c'est un problème plus profond : est-ce que l'enregistrement xAPI est bien activé, et est-ce que les extensions bookdown nécessaires ont bien été injectées grâce à une configuration correcte de [{learnitdown}](https://github.com/learnitr/learnitdown) ? L'option de débogage de H5PxAPIkatchu devrait s'avérer utile ici pour déterminer ce qui ne va pas, voir \@ref(h5p).
## Bookdown dans Wordpress
Le format gitbook de bookdown qui est le format le plus utilisé pour les tutoriels, les cours et les manuels (type "textbook") en ligne n'est pas prévu pour s'intégrer à Wordpress. Cependant, grâce à [{learnitdown}](https://github.com/learnitr/learnitdown), il est possible d'obtenir un résultat indiscernable visuellement d'un réelle intégration via l'inclusion du bookdown dans un iframe à l'intérieur d'une page Wordpress. De plus, {learnitdown} transfère des informations relatives à l'utilisateur Wordpress enregistré, et aux fonctions côté serveur pour l'enregistrement des données H5P. Ainsi, l'intégration est complète puisque les applications H5P incluses dans le bookdown bénéficient des mêmes fonctionnalités que si elles étaient directement affichées à l'intérieur d'une page Wordpress. Les mêmes fonctions de détection de l'utilisateur et d'enregistrement des évènements générés par les applications Shiny et learnr sont également implémentées dans {learnitdown}. La partie à modifier dans le bookdown pour réaliser cette intégration ayant été abordée ci-dessus, voyons maintenant ce que nous devons faire du côté du serveur Wordpress pour la finaliser.
1. Inclusion des pages du bookdown dans le serveur Wordpress
Les pages du bookdown ont été générées dans un sous-dossier dans le dépôt git de votre dépoiement Wordpress. Vous devez maintenant effectuer un commit, un push sur Gandi.net, et enfin un deploy comme expliqué à la section précédente :
```
cd <path_to_site_folder>
git add .
git commit -m "New version of course-2023"
git push origin master
ssh <ID>@git.sd3.gpaas.net 'deploy <SITE>.git'
```
2. Créer une page contenant uniquement un iframe dans Wordpress
Avec un compte ayant des droits en édition, aller dans le tableau de bord de Wordpress, ensuite dans `Pages`-> `Ajouter`. Dans l'éditeur, n'indiquez aucun titre, mais ajouter un bloc en dessous et sélectionner le type `HTML personnalisé`.

Collez-y le code ci-dessous après avoir modifié `<SITE>` et `<URL>` par l'URL de la page et adaptez le contenu de `src` en fonction de votre propre page, ainsi que la hauteur de la barre supérieure en pixels dans `height="calc(100vh - 50px)"` (ici, 50 pixels).
```
[advanced_iframe id="bookdown" name="bookdown" src="https://<SITE>.org/<URL>"
width="100%" height="calc(100vh - 50px)" use_shortcode_attributes_only="true"
map_parameter_to_url="iframe" add_iframe_url_as_param="same" show_iframe_loader="true"
enable_responsive_iframe="true" hide_elements=".tg-site-footer-bar,.entry-footer"
additional_height="100" multi_domain_enabled="false" use_post_message="false"]
```
Appuyez sur le bouton `Publier`. Vous devez obtenir quelque chose qui se rapproche de ceci :

3. Allez dans l'onglet `Document`, puis `Permalien`-> `Slug d'URL` et choisissez un nom de la page *qui diffère de celui du dépôt GitHub* (donc dans notre cas, pas `sdd-umons3-2020`). Par exemple, `sdd3-2020`.

4. Enfin, allez tout en bas de l'éditeur dans `Réglages de la page` -> `Général` et sélectionnez la mise en page la plus simple en bas à droite et cochez également `Supprimer la marge du contenu`.
5. Cliquez sur le bouton `Mettre à jour`. Visualisez votre page et naviguez dans la section `Introduction` du bookdown pour tester les différentes fonctionnalités.
6. A partir d'un compte administrateur Wordpress, cliquez sur `Personnaliser` dans la barre noire supérieure. Ensuite, éditez le menu qui apparait à gauche pour y inclure un lien vers la page que nous venons de créer.
Au final, le bookdown se présente sous deux formes :
- Les pages affichées telles quelles via une URL reprenant le nom du dépôt GitHub (il s'agit de `https://<SITE>/<URL>/`). Nous avons une présentation bookdown classique. Les informations de l'identité de l'étudiant sont transmise via `localStorage`, mais le bandeau supérieur du site et la barre noire supérieure de gestion Wordpress ne sont pas affichés. Le bookdown n'est pas vraiment intégré dans le site et les évènements xAPI de H5P ne sont pas renvoyés au serveur Wordpress. Cette représentation est utile pour l"utilisation du bookdown dans un contexte hors cours UMONS.
- Les même page du bookdown, **mais intégrées sous forme d'iframe** dans une page de Wordpress dédiée à partir du lien de la page Wordpress (`https://<SITE>/<URL_WORDPRESS>`). La page conserve des éléments issus de Wordpress comme la barre d'outils supérieure (accès à Moodle, Discord, etc.) ainsi que la barre noire supérieure de contrôle Wordpress qui permet aussi de vérifier d'un coup d'œil que l'on est connecté, et sous quelle identité nous le sommes. S'il veut lire le contenu du bookdown sans voir la bannière haute, le lecteur peut faire coulisser la page jusque tout en bas et cette bannière viendra se cacher derrière la barre noire supérieure Wordpress (qui, elle, reste toujours visible tant que l'utilisateur est connecté au site).
## Installation de H5P
H5P ne peut fonctionner seul. Il doit être inclus dans un serveur plus large, soit un LMS (Learning Management System ou plateforme d'apprentissage en ligne comme), soit un CMS (Content Management System, système de gestion de contenu).
L'un des LMS les plus populaires est [Moodle](https://moodle.com/fr/). H5P est compatible avec Moodle (il peut être installé comme plugin). Ce serait donc parfaitement logique de l'utiliser de cette manière si Moodle est déjà employé. Malheuresuement, le contenu H5P n'est **pas** utilisable ailleurs que dans Moodle lui-même. Or, notre souhait est d'intégrer le contenu H5P dans un bookdown qui ne peut être hébergé sur Moodle^[D'un point de vue technique, le contenu H5P s'affiche dans un iframe. Or les possibilités des iframes inter-sites sont limitées par le protocole HTML5 sous-jacent lui-même pour éviter les abus. Il nous faut donc le bookdown (pages statiques) et le contenu H5P (devant être lié à un serveur LMS ou CMS) servis par le *même* site.]. Une autre option consiste à utiliser soit [Wordpress](https://fr.wordpress.com/), soit [Drupal](https://www.drupal.org/) pour lesquels H5P est également compatible. Après comparaison des possibilités des deux, nous avons opté pour Wordpress, plus largement utilisé.
H5P permet de récupérer des informations concernant l'activité des étudiants dans les exercices sous forme de requêtes [xAPI](https://xapi.com/overview/). xAPI est un standard développé pour permettre l'interaction entre un LMS comme Moodle et un LRS (Learning Record Store) une base de données chargée d'enregistrer les traces de l'apprentissage En complément de H5P lui-même et de Wordpress comme serveur principal, il nous faut donc un LRS et un plugin qui fasse le pont entre H5P et ce LRS. Enfin, l'information n'est utile que si elle est identifiable comme provenant d'un étudiant en particulier. Le serveur doit donc gérer l'authentification des utilisateurs et transmettre l'identité de l'étudiant au travers de la requête xAPI. Si tout cela parait très compliqué, voici un petit schéma qui résume l'ensemble (à noter que nous avons choisi l'authentification par GitHub parce que les étudiants ont également d'autres activités sur GitHub/GitHub Classroom, et il est dès lors plus facile de gérer une identité commune à toutes ces activités.

### Installation du plugin H5P
Une fois le serveur Wordpress opérationnel, l'installation de H5P lui-même est très simple :
- Se connecter au serveur Wordpress comme administrateur,
- Aller dans le tableau de bord -> Extensions -> Ajouter.
- Dans le champ de recherche, introduire "H5P",
- Sélectionner "Interactive content - H5P". Cliquer "Installer", puis "Activer".
C'est fait ! H5P est installé, mais aucune forme de contenu n'est encore disponible. H5P conseille d'installer des **librairies** de contenu. À partir du tableau de bord, cela se fait via "H5P Content -> Libraries". Cependant, cela n'apparaît pas nécessaire en pratique car lorsqu'on importe du contenu H5P dans le site, les librairies nécessaires sont automatiquement importées également... plus d'explications ci-dessous.
### Configuration de H5P
Le panneau de configuration est accessible pour l'administrateur Wordpress depuis le tableau de bord -> Réglages -> H5P. Voici une copie d'écran de la configuration choisie.

- La barre d'outils H5P en dessous du contenu est désactivée par défaut ("Controlled by author" non coché). Cette barre d'outils permet le partage et la réutilisation de contenu. Nous la garderions bien activées, mais le bouton de réemploi doit apparemment être activé pour que l'inclusion dans un bookdown soit possible. Or, si ce bouton est activé, tout le monde peut inclure le contenu dans d'autres sites... et impacter notre quotas d'utilisation de requêtes. Nous ne le souhaitons bien évidemment pas. *Pour récupérer un contenu sous forme de fichier .h5p, il faut réactiver cette option temporairement dans le tableau de bord, et seul l'administrateur du site peut le faire (voir Gestion des contenus H5P plus loin).*
- Les résultats utilisateurs ("Log results..." est coché) permet d'avoir des statistiques de base utilisateur par utilisateur sur les H5P. C'est utile, mais il faudra voir à terme l'impact sur l'espace disque utilisé pour cette fonction.
- La sauvegarde du contenu ("Allow logged-in users to resume tasks") est activée et utile puisqu'elle permet la mémorisation d'une session à l'autre des sélections dans les contenus H5P pour les utilisateurs enregistrés.
- "Show toggle switch for others' H5P contents" n'est pas très clair. Il est sur "Yes, show all contents by default". Est-ce qu'il s'agit de voir le contenu *crée* par d'autres utilisateurs ? Si, oui, c'est ce qu'on veut (les étudiant utilisent le contenu créé par les profs).
- "Add content method" est réglé sur "id".
- L'option suivante, "Enable LRS dependent content types" est importante et doit être coché pour pouvoir enregistrer l'activité via xAPI (voir plus loin).
- Les deux dernières options sont en relation avec la gestion et le développement H5P. Nous les laissons cochées ("Use H5P Hub" et "Automatically contribute usage statistics").
### Enregistrement H5P xAPI
Une fois le plugin H5P installé, il nous faut encore permettre l'enregistrement des activités des étudiants. Nous l'avons déjà vu, cette possibilité est prévue dans H5P et le protocole standardisé xAPI est utilisé, ce qui le rend compatible avec les LRS du marché. Dans Wordpress, nous utiliserons le plugin H5PxAPIkatchu pour faire la liaison avec notre base de données MongoDB.
#### H5PxAPIkatchu
Ce plugin est facile à installer puisqu'il est disponible depuis Wordpress plugins. La procédure est la même que pour l'installation de H5P lui-même (l'administrateur va dans la partie installation d'extension du tableau de bord, rentre "H5PxAPI" dans la zone de recherche, sélectionne l'item et clique "Installer" puis "Activer"). Ce plugin est gratuit et il semble bien maintenu^[Nous avons fait une proposition de pull request à l'auteur qui a répondu immédiatement.].
La configuration est également extrêmement simple.

Comme nous souhaitons récolter un maximum d'information sur l'activité des étudiants, et voulons récupérer le contenu xAPI intact, nous cochons "Store complete statements" et "Capture everything". L'option "Debug" n'est pas nécessaire et peut rester décochée.
Une fois cette configuration effectuée, l'activité H5P est enregistrée directement dans la base de données MySQL de Wordpress. Cette base de données n'est pas disponible de l'extérieur dans notre configuration (le fournisseur verrouille les bases de données pour un accès local uniquement par sécurité). Par contre, H5PxAPIkatchu permet de visualiser un tableau avec les données, de le filtrer, et de récupérer le résultat sous forme de fichier CSV avec le bouton "Download" (le lien "Delete" permet d'effacer le contenu et n'est disponible que pour l'administrateur du site).

Et c'est tout ! Pas besoin de LRS, pas besoin de configuration à rallonge... par contre, cela ne convient que pour du *dépannage*. En effet, l'accès aux données n'est pas possible pour, par exemple, générer les rapports de progression des étudiants. L'extraction sous forme CSV doit se faire *manuellement* !
Avec cette configuration, l'enregistrement de l'activité se fait uniquement lorsque le contenu H5P est utilisé directement dans Wordpress (à partir d'une page Wordpress ou du tableau de bord). Mais cela ne **fonctionne pas encore dans le bookdown !** En effet, notre bookdown en pages statiques va se voir déléguer le travail. Le schéma suivant explique le détail de l'implémentation.

Pour que notre bookdown enregistre les évènements H5P, il faut lui adjoindre le code en Javascript nécessaire pour faire le transfert. Ce code est repris et adapté de H5P lui-même, ainsi que de H5PxAPIkatchu. Ce code est placé dans le fichier `header.html` qui est inclus dans le bookdown grâce à ceci dans `index.Rmd` :
```yaml
output:
bookdown::gitbook:
includes:
in_header: header.html
```
Tout d'abord, la partie H5P de configuration. La partie **H5PIntegration** est normalement générée à partir de Wordpress, mais comme nous utilisons des pages statiques dans bookdown, nous le copions tel quel ici. Comme elle contient des informations contextuelles liées au site et à l'installation de H5P, nous devrons récupérer cela autrement afin d'avoir une version à jour, mais pour l'instant, ça fonctionne de cette manière. Voici ce que cela donne dans notre site exemple :
```html
<!-- Required for H5P xAPI feedback -->
<script>H5PIntegration = {"baseUrl":"https:\/\/wp.sciviews.org","url":"\/wp-content\/uploads\/h5p","postUserStatistics":false,"ajax":{"setFinished":"https:\/\/wp.sciviews.org\/wp-admin\/admin-ajax.php?token=e6b10366a6&action=h5p_setFinished","contentUserData":"https:\/\/wp.sciviews.org\/wp-admin\/admin-ajax.php?token=ea1774d67b&action=h5p_contents_user_data&content_id=:contentId&data_type=:dataType&sub_content_id=:subContentId"},"saveFreq":"30","siteUrl":"https:\/\/wp.sciviews.org","l10n":{"H5P":{"fullscreen":"Fullscreen","disableFullscreen":"Disable fullscreen","download":"Download","copyrights":"Rights of use","embed":"Embed","size":"Size","showAdvanced":"Show advanced","hideAdvanced":"Hide advanced","advancedHelp":"Include this script on your website if you want dynamic sizing of the embedded content:","copyrightInformation":"Rights of use","close":"Close","title":"Title","author":"Author","year":"Year","source":"Source","license":"License","thumbnail":"Thumbnail","noCopyrights":"No copyright information available for this content.","reuse":"Reuse","reuseContent":"Reuse Content","reuseDescription":"Reuse this content.","downloadDescription":"Download this content as a H5P file.","copyrightsDescription":"View copyright information for this content.","embedDescription":"View the embed code for this content.","h5pDescription":"Visit H5P.org to check out more cool content.","contentChanged":"This content has changed since you last used it.","startingOver":"You'll be starting over.","by":"by","showMore":"Show more","showLess":"Show less","subLevel":"Sublevel","confirmDialogHeader":"Confirm action","confirmDialogBody":"Please confirm that you wish to proceed. This action is not reversible.","cancelLabel":"Cancel","confirmLabel":"Confirm","licenseU":"Undisclosed","licenseCCBY":"Attribution","licenseCCBYSA":"Attribution-ShareAlike","licenseCCBYND":"Attribution-NoDerivs","licenseCCBYNC":"Attribution-NonCommercial","licenseCCBYNCSA":"Attribution-NonCommercial-ShareAlike","licenseCCBYNCND":"Attribution-NonCommercial-NoDerivs","licenseCC40":"4.0 International","licenseCC30":"3.0 Unported","licenseCC25":"2.5 Generic","licenseCC20":"2.0 Generic","licenseCC10":"1.0 Generic","licenseGPL":"General Public License","licenseV3":"Version 3","licenseV2":"Version 2","licenseV1":"Version 1","licensePD":"Public Domain","licenseCC010":"CC0 1.0 Universal (CC0 1.0) Public Domain Dedication","licensePDM":"Public Domain Mark","licenseC":"Copyright","contentType":"Content Type","licenseExtras":"License Extras","changes":"Changelog","contentCopied":"Content is copied to the clipboard","connectionLost":"Connection lost. Results will be stored and sent when you regain connection.","connectionReestablished":"Connection reestablished.","resubmitScores":"Attempting to submit stored results.","offlineDialogHeader":"Your connection to the server was lost","offlineDialogBody":"We were unable to send information about your completion of this task. Please check your internet connection.","offlineDialogRetryMessage":"Retrying in :num....","offlineDialogRetryButtonLabel":"Retry now","offlineSuccessfulSubmit":"Successfully submitted results."}},"hubIsEnabled":true,"reportingIsEnabled":true,"libraryConfig":null,"crossorigin":null,"crossoriginCacheBuster":null,"pluginCacheBuster":"?v=1.15.0","libraryUrl":"https:\/\/wp.sciviews.org\/wp-content\/plugins\/h5p\/h5p-php-library\/js","core":{"styles":["\/wp-content\/plugins\/h5p\/h5p-php-library\/styles\/h5p.css?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/styles\/h5p-confirmation-dialog.css?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/styles\/h5p-core-button.css?ver=1.15.0"],"scripts":["\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/jquery.js?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p.js?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-event-dispatcher.js?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-x-api-event.js?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-x-api.js?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-content-type.js?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-confirmation-dialog.js?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-action-bar.js?ver=1.15.0","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/request-queue.js?ver=1.15.0"]},"loadedJs":[],"loadedCss":[],"contents":{"cid-7":{"library":"H5P.MultiChoice 1.14","jsonContent":"{\"answers\":[{\"correct\":false,\"tipsAndFeedback\":{\"tip\":\"\",\"chosenFeedback\":\"\",\"notChosenFeedback\":\"\"},\"text\":\"<div>The header of the document<\\\/div>\\n\"},{\"correct\":true,\"tipsAndFeedback\":{\"tip\":\"\",\"chosenFeedback\":\"<div>Excellent! A chunk is indeed a special area delimited by \\u0010\\u0010```{R} and ``` tags that contains R code to be evaluated in place when the document is compiled.<\\\/div>\\n\",\"notChosenFeedback\":\"<div>Oww! You should go back to the capsule about R Markdown to learn what a chunk is.<\\\/div>\\n\"},\"text\":\"<div>An area that contains R code<\\\/div>\\n\"},{\"correct\":false,\"tipsAndFeedback\":{\"tip\":\"\",\"chosenFeedback\":\"\",\"notChosenFeedback\":\"\"},\"text\":\"<div>A area that contains markdown text<\\\/div>\\n\"}],\"overallFeedback\":[{\"from\":0,\"to\":100}],\"UI\":{\"checkAnswerButton\":\"Check\",\"showSolutionButton\":\"Show solution\",\"tryAgainButton\":\"Retry\",\"tipsLabel\":\"Show tip\",\"scoreBarLabel\":\"You got :num out of :total points\",\"tipAvailable\":\"Tip available\",\"feedbackAvailable\":\"Feedback available\",\"readFeedback\":\"Read feedback\",\"wrongAnswer\":\"Wrong answer\",\"correctAnswer\":\"Correct answer\",\"shouldCheck\":\"Should have been checked\",\"shouldNotCheck\":\"Should not have been checked\",\"noInput\":\"Please answer before viewing the solution\"},\"behaviour\":{\"enableRetry\":true,\"enableSolutionsButton\":true,\"enableCheckButton\":true,\"type\":\"auto\",\"singlePoint\":true,\"randomAnswers\":true,\"showSolutionsRequiresInput\":true,\"confirmCheckDialog\":false,\"confirmRetryDialog\":false,\"autoCheck\":false,\"passPercentage\":100,\"showScorePoints\":true},\"confirmCheck\":{\"header\":\"Finish ?\",\"body\":\"Are you sure you wish to finish ?\",\"cancelLabel\":\"Cancel\",\"confirmLabel\":\"Finish\"},\"confirmRetry\":{\"header\":\"Retry ?\",\"body\":\"Are you sure you wish to retry ?\",\"cancelLabel\":\"Cancel\",\"confirmLabel\":\"Confirm\"},\"question\":\"<p>What is a chunk in R Markdown?<\\\/p>\\n\",\"media\":{\"disableImageZooming\":false}}","fullScreen":"0","exportUrl":"\/wp-content\/uploads\/h5p\/exports\/multiple-choice-7.h5p","embedCode":"<iframe src=\"https:\/\/wp.sciviews.org\/wp-admin\/admin-ajax.php?action=h5p_embed&id=7\" width=\":w\" height=\":h\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe>","resizeCode":"<script src=\"https:\/\/wp.sciviews.org\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-resizer.js\" charset=\"UTF-8\"><\/script>","url":"https:\/\/wp.sciviews.org\/wp-admin\/admin-ajax.php?action=h5p_embed&id=7","title":"multiple-choice","displayOptions":{"frame":false,"export":false,"embed":true,"copyright":false,"icon":false,"copy":false},"metadata":{"title":"multiple-choice","license":"U"},"contentUserData":[{"state":"{}"}],"scripts":["\/wp-content\/uploads\/h5p\/cachedassets\/bbb484ab91a596c1d881578ee3d99ab92df05f05.js","https:\/\/wp.sciviews.org\/wp-content\/plugins\/h5pxapikatchu\/js\/h5pxapikatchu-listener.js?ver=0.4.2"],"styles":["\/wp-content\/uploads\/h5p\/cachedassets\/bbb484ab91a596c1d881578ee3d99ab92df05f05.css"]}}};</script><link rel='stylesheet' id='h5p-core-styles-h5p-css' href='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/styles/h5p.css' media='all' />
<link rel='stylesheet' id='h5p-core-styles-h5p-confirmation-dialog-css' href='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/styles/h5p-confirmation-dialog.css' media='all' />
<link rel='stylesheet' id='h5p-core-styles-h5p-core-button-css' href='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/styles/h5p-core-button.css' media='all' />
<script src='https://wp.sciviews.org/wp-includes/js/wp-embed.min.js'></script>
```
Et ce n'est pas tout ! Il nous faut encore le code Javascript H5P et H5PxAPIkatchu :
```html
<script>
var wpAJAXurl = "https:\/\/wp.sciviews.org\/wp-admin\/admin-ajax.php";
var debugEnabled = "0";
var captureAllH5pContentTypes = "1";
var h5pContentTypes = [""];
window.H5PxAPIkatchu = {
captureAllH5pContentTypes: captureAllH5pContentTypes,
debugEnabled: debugEnabled,
h5pContentTypes: h5pContentTypes,
jQuery: jQuery,
wpAJAXurl: wpAJAXurl
};
</script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/jquery.js'></script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/h5p.js'></script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/h5p-event-dispatcher.js'></script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/h5p-x-api-event.js'></script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/h5p-x-api.js'></script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/h5p-content-type.js'></script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/h5p-confirmation-dialog.js'></script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/h5p-action-bar.js'></script>
<script src='https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/request-queue.js'></script>
```
Voilà, avec tout cela, nous recompilons le bookdown, plaçons tout le contenu de `\docs` sur le serveur... et une fois cela réalisé, nous pouvons aussi enregistrer l'activité des H5P inclus dans les pages bookdown de notre site.
```{block2, type="warning"}
En dépis de sa simplicité, H5PxAPIkatchu ne convient *pas* tel quel pour l'objectif que nous poursuivons. Nous avons imaginé étendre le plugin pour enregistrer les données dans notre base de données MongoDB Atlas comme première solution. Cela a nécessité du développement PHP et l'utilisation d'une librairie PHP mongodb qu'il faut installer sur le serveur. Une autre solution consiste à utiliser un autre plugin et à passer par un véritable LRS. Ceci est envisagé dans le paragraphe suivant.
```
Il s'avère que, une fois l'incorporation du driver MongoDB dans PHP effectuée (c'est en fait la partie la plus difficile), le code en PHP qu'il faut ajouter à H5PxAPIkatchu pour effectuer l'enregistrement dans notre base MongoDB est assez succinct (ce code est placé dans la zone dédie du plugin **My custom functions** après avoir remplacé `<USER>`, `<PASSWORD>`, `<SERVER|2|3>` et `<SHARD>` par les valeurs correspondantes au compte configuré pour accéder à votre base de données MongoDB sur Atlas ou autre) :
```php
// Custom h5pxapikatchu data insertion
function h5pxapi_actor( $actor ) {
global $doc;
$doc['actor'] = $actor;
return $actor;
}
add_filter( 'h5pxapikatchu_insert_data_actor', 'h5pxapi_actor' );
function h5pxapi_verb( $verb ) {
global $doc;
$doc['verb'] = $verb;
return $verb;
}
add_filter( 'h5pxapikatchu_insert_data_verb', 'h5pxapi_verb' );
function h5pxapi_object( $object ) {
global $doc;
$doc['object'] = $object;
return $object;
}
add_filter( 'h5pxapikatchu_insert_data_object', 'h5pxapi_object' );
function h5pxapi_result( $result ) {
global $doc;
$doc['result'] = $result;
// Added by PhG
// Note: 'time' is like recorded in MySQL, but truncated down to second
//$doc['time'] = current_time( 'mysql' );
$doc['date'] = current_time( 'Y-m-d H:i:s.u', $gmt = 1 );
return $result;
}
add_filter( 'h5pxapikatchu_insert_data_result', 'h5pxapi_result' );
function h5pxapi_xapi( $xapi ) {
global $doc;
$doc['xapi'] = $xapi;
return $xapi;
}
add_filter( 'h5pxapikatchu_insert_data_xapi', 'h5pxapi_xapi' );
//function h5pxapikatchu_custom_insert_data( $actor, $verb, $object, $result, $xapi ) {
function h5pxapi_custom_insert_data() {
global $doc;
$response = false;
try {
$manager = new MongoDB\Driver\Manager( 'mongodb://<USER>:<PASSWORD>@<SERVER>.mongodb.net:27017,<SERVER2>.mongodb.net:27017,<SERVER3>.mongodb.net:27017/test?ssl=true&replicaSet=<SHARD>&authSource=admin' );
$bulk = new MongoDB\Driver\BulkWrite;
//$doc = [
// 'actor' => $actor,
// 'verb' => $verb,
// 'object' => $object,
// 'result' => $result,
// Added by PhG: 'time' => $time,
// 'xapi' => $xapi,
//];
$bulk->insert( $doc );
$result = $manager->executeBulkWrite( 'sdd.h5p', $bulk );
$response = true;
} catch (Throwable $e) {
//echo "Catured Throwable: " . $e->getMessage() . PHP_EOL;
// Manage error here...
}
if ($response) {
wp_die();
}
return $response;
}
add_action( 'h5pxapikatchu_insert_data_pre_database', 'h5pxapi_custom_insert_data' );
```
Cela fonctionne, mais pour une utilisation plus robuste, il nous faudra passer les paramètres nécessaires à la requête AJAX sur Wordpress de manière dynamique à nos pages bookdown. C'est ce que nous avons implémenté dans le package R [{learnitdown}](https://github.com/learnitr/learnitdown). **TODO:** remanier ceci avec une procédure simplifiée en utilisant {learnitdown}.
#### Autres plugins H5P
- Le même auteur de H5PxAPIkatchu propose aussi [H5P Resize Pulse](https://fr-be.wordpress.org/plugins/snordians-h5p-resize-pulse/) qui permet de régler un problème d'affichage apparemment de H5P dans certains containers. Dans les bookdowns, nous ne rencontrons pas de problèmes pour l'instant, mais c'est bon à savoir... Il propose aussi [H5P sharing](https://fr-be.wordpress.org/plugins/h5p-sharing/) pour obtenir aisément le code `<iframe>...</iframe>` d'un contenu H5P. Nous n'en avons pas besoin car la fonction `learnitdown::h5p()` remplit la même fonction dans R.
## Contenu H5P dans bookdown
Nous avons déjà vu que le contenu H5P s'affiche dans un iframe dans un document principal. Il lui transmet les évènements xAPI, et c'est donc ce document principal qui doit les traiter. Nous avons ici une impossibilité à le faire si nous sommes dans un cas où H5P est servi par un serveur différent que notre bookdown. En effet, les accès en "Cross-Origin Resource Sharing" ou CORS sont restreintes pour éviter des attaques de site évidentes. Ainsi un iframe issu d'un serveur différent de la page qui l'héberge ne peut communiquer librement avec la page qui le contient si elle provient d'un site différent. Or, nous avons besoin de cette communication pour transmettre les événements xAPI...
La solution que nous avons trouvée est d'ajouter le dossier qui contient nos pages statiques du bookdown à Wordpress directement. Ainsi les deux sont maintenant servis à partir de la même adresse. Une fois que c'est fait, l'inclusion d'applications H5P dans le bookdown est facile. Il suffit d'utiliser la fonction `h5p()` de {learnitdown} en indiquant juste le numéro ID de l'application H5P tel qu'affiché dans le tableau de bord de Wordpress avec un code du type `learnitdown::h5p(6, baseurl = "https://wp.sciviews.org")` dans du code inline dans notre bookdown (ici, l'ID serait '6', ce qui correspond à l'application H5P nommée "drag-words" dans la copie d'écran ci-dessous). On peut éventuellement repréciser `width =`ou `height = ` pour changer la taille de l'iframe hébergeant l'application H5P.

Pour comprendre ce que la fonction `learnitdown::h5p()` fait, nous pouvons nous concentrer sur la version simplifiée suivante :
```{r, eval=FALSE}
h5p <- function(id, width = 780, height = 500) {
glue::glue("\n<iframe src=\"https://wp.sciviews.org/wp-admin/admin-ajax.php?action=h5p_embed&id={id}\" width=\"{width}\" height=\"{height}\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\" class=\"h5p\"></iframe><script src=\"https://wp.sciviews.org/wp-content/plugins/h5p/h5p-php-library/js/h5p-resizer.js\" charset=\"UTF-8\"></script>\n")
}
```
La fonction construit un fragment HTML qui ajoute un iframe et un script pour gérer l'inclusion du contenu H5P dans notre bookdown. A partir d'ici, ajouter un contenu H5P est aussi simple que d'ajouter `h5p(id)` dans du code R en ligne où "id" est l'ID que nous avons noté. On peut aussi jouer sur les arguments `width=` et `height=` pour ajuster l'emplacement et la taille du contenu H5P dans la page.
Ainsi programmé notre contenu H5P se comporte comme suit :
- pour un utilisateur enregistré dans Wordpress, les évènements xAPI sont enregistrés à son nom. Nous pouvons donc suivre la progression de nos étudiants via les contenus H5P parsemés dans le bookdown également, en plus des applis Shiny et des learnrs. De plus, l'état d'achèvement de l'exercice est aussi enregistré pour un bon nombre de contenus H5P et rétabli lorsque la page est rechargée par le même utilisateur.
- pour un utilisateur non enregistré, les contenus H5P fonctionnent normalement, mais aucun évènement xAPI n'est enregistré, et l'état de complétude de l'exercice n'est pas conservé non plus. Si la page est rechargée, les contenus H5P retournent à leur état initial à chaque fois.
Ceci est un inconfort mineur pour un utilisateur anonyme et permet l'utilisation des contenus H5P de manière optimale pour nos étudiants dûment enregistrés, tout en permettant une libre utilisation par d'autres visiteurs sans polluer notre base de données.
Nous avons également tenté de passer des arguments supplémentaires via l'URL qui lance la page bookdown, et qui les transfère vers l'iframe H5P, mais sans succès car apparemment Worpress réécrit l'URL et laisse tomber ces arguments supplémentaires. Mais de toutes façons, ce n'est pas important pour l'instant car nous pouvons tracer nos utilisateurs enregistrés dans Wordpress telle que c'est actuellement implémenté.
### Gestion des contenus H5P
Chaque contenu H5P est indépendant du reste. Attention que les contenus complexes sont volumineux. Par exemple, les vidéos interactives occupent chacune 2,8Mo sur le serveur lorsque les vidéos sont sur Youtube (donc, occupation de place minimale puisque la vidéo elle-même n'est **pas** directement dans le site Wordpress).
Au départ, aucun contenu n'est réalisable car les **librairies** nécessaires ne sont pas encore installée. Heuresuement, il ne faut pas les installer manuellement. Il suffit de téléverser du contenu pour que leur installation se fasse automatiquement (mais si de nouvelles librairies sont nécessaires, il faut alors le faire avec le compte admin de Wordpress). Donc, la procédure pragmatique suivante est retenue pour enrichir le site des librairies nécessaire :
- Pour un type de contenu qui n'est pas encore supporté, aller sur [h5p.org](https://h5p.org). Se connecter (créer un compte gratuit, si nécessaire).
- Aller dans "Examples and Downloads" et choisir un exemple de type de contenu souhaité. Cliquer sur "Reuse". Ou alors aller dans "Contents" -> "Create New Content" et créer un contenu du type souhaité. Puis cliquer sur "Reuse" lorsqu'on est satisfait du contenu.
Voici un exemple avec le contenu de type "True/False".



Ensuite, dans le tableau de bord de Wordpress (en ayant pris soin de s'être enregistré comme administrateur), aller dans H5P Content -> Add New. Sélectionner "Téléverser" et indiquer le fichier `.h5p` que l'on vient de sauver, puis "Utiliser".

Une fois que c'est fait, non seulement le contenu est téléversé, mais les librairies requises sont également ajoutées. De cette façon, un autre contenu de ce type peut maintenant être créé *directement* depuis la tableau de bord de Wordpress, H5P content -> Add New par n'importe quel utilisateur qui a les droits d'édition sur le site (donc, les enseignants).
### Backup H5P
Le backup du site entier Wordpress est effectué. Par contre, il est utile d'avoir une copie des différents contenus H5P au format de fichier `.h5p`. Pour cela, un administrateur de site doit au préalable temporairement cocher l'option "Toolbar Below Content" dans les paramètres du plugin H5P de Wordpress (tableau de bord), de sorte que le bouton "Reuse" apparaisse en dessus d'un contenu H5P. Pour chaque contenu que l'on souhaite sauvegarder, l'afficher, et cliquer sur son bouton "Reuse" pour récupérer le fichier `.h5p`. Ensuite, placer les fichiers `.h5p` à l'emplacement de backup désiré.
**TODO:** une solution de récupération automatisée des fichiers `.h5p` d'un site devrait être développée à la place, la procédure décrite ci-dessus ne devrait être utilisée que ponctuellement pour récupérer un petit nombre de contenus H5P.
### Gestion des événements xAPI
Pour les enseignants, les évènements xAPI générés par H5P (voir \@ref(h5p)) qui n'ont pas pu être enregistrés dans la base de données MongoDB Atlas dédiée pour une raison ou une autre sont accessibles à partir du tableau de bord de Wordpress dans la section H5PxAPIkatchu. De là, ils peuvent être exportés au format CSV, et réinjectés dans MongoDB à l'aide d'un peu de code R. **TODO:** H5PxAPIkatchu ne fournit **pas** la date et l'heure de chaque évènement via ce tableau, mais l'enregistre dans la base de données MySQL avec une précision de la seconde. Il faudra peut-être un accès directe à cette base de données pour récupérer l'information complète dans ce cas. Dans MongoDB Atlas, cette information est enregistrée, par contre, avec une précision de la milliseconde.
