<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://bendevries.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://bendevries.com/" rel="alternate" type="text/html" /><updated>2025-10-14T19:45:42+00:00</updated><id>https://bendevries.com/feed.xml</id><title type="html">Ben de Vries</title><subtitle></subtitle><entry><title type="html">Connecting Moodle H5P Content with an LRS</title><link href="https://bendevries.com/2020/09/02/connecting-moodle-h5p-content-with-an-lrs.html" rel="alternate" type="text/html" title="Connecting Moodle H5P Content with an LRS" /><published>2020-09-02T00:00:00+00:00</published><updated>2020-09-02T00:00:00+00:00</updated><id>https://bendevries.com/2020/09/02/connecting-moodle-h5p-content-with-an-lrs</id><content type="html" xml:base="https://bendevries.com/2020/09/02/connecting-moodle-h5p-content-with-an-lrs.html"><![CDATA[<p>This post is updated version of <a href="https://juliandavis.com/connecting-h5p-interactive-activity-in-moodle-to-an-lrs/">this blog post</a> by Julian Davis. There is an existing plugin for Moodle called <a href="https://github.com/trax-project/moodle-trax-logs">Trax Logs for Moodle</a> which allows Moodle to send xAPI statements about H5P content to an LRS. This is a more robust solution for many installations but as of the writing of this post much of the data generated by the H5P content is lost before sending the xAPI statement to the LRS. One of the drawbacks of the solution outlined here is that the statements can <em>not</em> be sent retroactively, this will only send xAPI statements as they are being made by the H5P content. This solution has been tested on Moodle version <code class="language-plaintext highlighter-rouge">3.9</code> with PHP version <code class="language-plaintext highlighter-rouge">7.4.9</code>.</p>

<p>You will need to make a new directory <code class="language-plaintext highlighter-rouge">js</code> in the <code class="language-plaintext highlighter-rouge">mod/hvp</code> of your Moodle installation. There you will make 3 new files as shown in this directory tree</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.
├── mod
│   └── hvp
│       ├── view.php
│       └── js
│           ├── xapi-stmt-dispatcher.js
│           ├── xapiwrapper.min.js
│           └── xapiwrapper.min.js.map
...
</code></pre></div></div>

<p>This first file <code class="language-plaintext highlighter-rouge">xapi-stmt-dispatcher.js</code> should have the following contents.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nf">ready</span><span class="p">(</span><span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
	<span class="nx">ADL</span><span class="p">.</span><span class="nx">XAPIWrapper</span><span class="p">.</span><span class="nf">changeConfig</span><span class="p">({</span>
		<span class="dl">'</span><span class="s1">endpoint</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">http://your.lrs.edu/data/xAPI/</span><span class="dl">'</span><span class="p">,</span>
		<span class="dl">"</span><span class="s2">auth</span><span class="dl">"</span> <span class="p">:</span> <span class="dl">"</span><span class="s2">Basic </span><span class="dl">"</span> <span class="o">+</span> <span class="nf">toBase64</span><span class="p">(</span><span class="dl">'</span><span class="s1">username:password</span><span class="dl">'</span><span class="p">)</span>
	<span class="p">});</span>
	<span class="nx">H5P</span><span class="p">.</span><span class="nx">externalDispatcher</span><span class="p">.</span><span class="nf">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">xAPI</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
		<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">statement</span><span class="p">);</span>
		<span class="kd">var</span> <span class="nx">stmt</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ADL</span><span class="p">.</span><span class="nc">XAPIStatement</span><span class="p">(</span>
			<span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">statement</span><span class="p">.</span><span class="nx">actor</span><span class="p">,</span>
			<span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">statement</span><span class="p">.</span><span class="nx">verb</span><span class="p">,</span>
			<span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">statement</span><span class="p">.</span><span class="nx">object</span><span class="p">,</span>
			<span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">statement</span><span class="p">.</span><span class="nx">result</span><span class="p">);</span>
		<span class="nx">stmt</span><span class="p">.</span><span class="nf">generateId</span><span class="p">();</span>
		<span class="nx">stmt</span><span class="p">.</span><span class="nx">context</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">statement</span><span class="p">.</span><span class="nx">context</span><span class="p">;</span>
		<span class="nx">stmt</span><span class="p">.</span><span class="nf">generateRegistration</span><span class="p">();</span>
		<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">stmt</span><span class="p">));</span>
		<span class="nx">ADL</span><span class="p">.</span><span class="nx">XAPIWrapper</span><span class="p">.</span><span class="nf">sendStatement</span><span class="p">(</span><span class="nx">stmt</span><span class="p">)</span>
	<span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>

<p>The information for the result and context were added (not included in the post by Julian Davis) as this information is also provided by the H5P content.</p>

<p>The other two files <code class="language-plaintext highlighter-rouge">xapiwrapper.min.js</code> and <code class="language-plaintext highlighter-rouge">xapiwrapper.min.js.map</code> should have the contents of <a href="https://raw.githubusercontent.com/adlnet/xAPIWrapper/master/dist/xapiwrapper.min.js"><code class="language-plaintext highlighter-rouge">xapiwrapper.min.js</code></a> and <a href="https://raw.githubusercontent.com/adlnet/xAPIWrapper/master/dist/xapiwrapper.min.js.map"><code class="language-plaintext highlighter-rouge">xapiwrapper.min.js.map</code></a> respectively. This has been tested with the files as they were after the commit in the <a href="https://github.com/adlnet/xAPIWrapper">xAPIWrapper</a> repo with hash <code class="language-plaintext highlighter-rouge">fd2e083</code>.</p>

<p>Further the <code class="language-plaintext highlighter-rouge">mod/hvp/view.php</code> file should be updated to include the following lines</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// xAPI (ADL) js wrapper.</span>
<span class="nv">$PAGE</span><span class="o">-&gt;</span><span class="n">requires</span><span class="o">-&gt;</span><span class="nf">js</span><span class="p">(</span><span class="k">new</span> <span class="nc">moodle_url</span><span class="p">(</span><span class="s1">'/mod/hvp/js/xapiwrapper.min.js'</span><span class="p">),</span> <span class="kc">true</span><span class="p">);</span>
<span class="nv">$PAGE</span><span class="o">-&gt;</span><span class="n">requires</span><span class="o">-&gt;</span><span class="nf">jquery</span><span class="p">();</span>
<span class="nv">$PAGE</span><span class="o">-&gt;</span><span class="n">requires</span><span class="o">-&gt;</span><span class="nf">js</span><span class="p">(</span><span class="k">new</span> <span class="nc">moodle_url</span><span class="p">(</span><span class="s1">'/mod/hvp/js/xapi-stmt-dispatcher.js'</span><span class="p">),</span> <span class="kc">true</span><span class="p">);</span>
</code></pre></div></div>

<p>after the lines</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Configure page.</span>
<span class="nv">$PAGE</span><span class="o">-&gt;</span><span class="nf">set_url</span><span class="p">(</span><span class="k">new</span> <span class="nc">\moodle_url</span><span class="p">(</span><span class="s1">'/mod/hvp/view.php'</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'id'</span> <span class="o">=&gt;</span> <span class="nv">$id</span><span class="p">)));</span>
</code></pre></div></div>

<p>Once you save these changes you should see the xAPI statements outputted to the JavaScript console in your browser (to suppress these logs remove the log calls from the file) and sent to the LRS stated in the <code class="language-plaintext highlighter-rouge">xapi-stmt-dispatcher.js</code> file.</p>]]></content><author><name></name></author><category term="moodle," /><category term="h5p," /><category term="hvp," /><category term="lrs," /><category term="learning" /><category term="analytics" /><summary type="html"><![CDATA[This post is updated version of this blog post by Julian Davis. There is an existing plugin for Moodle called Trax Logs for Moodle which allows Moodle to send xAPI statements about H5P content to an LRS. This is a more robust solution for many installations but as of the writing of this post much of the data generated by the H5P content is lost before sending the xAPI statement to the LRS. One of the drawbacks of the solution outlined here is that the statements can not be sent retroactively, this will only send xAPI statements as they are being made by the H5P content. This solution has been tested on Moodle version 3.9 with PHP version 7.4.9.]]></summary></entry></feed>