Documentation Index
Fetch the complete documentation index at: https://mintlify.com/exelearning/mod_exelearning/llms.txt
Use this file to discover all available pages before exploring further.
mod_exelearning delivers and grades eXeLearning v4 (.elpx) packages inside a Moodle course, preserving the native eXe sidebar and recording multiple gradable items per activity. The plugin is deliberately layered: thin Moodle-mandated entry points delegate all domain work to testable classes under classes/local/* and classes/grades/*, with a single shared scoring pipeline that the web endpoint and the mobile web service both converge on.
One-paragraph model
A teacher uploads an.elpx (a ZIP with content.xml). lib.php stores it and extracts it to a per-revision file area; local\package parses content.xml and enumerates the gradable iDevices; lib.php registers one Moodle grade item per iDevice (multi-itemnumber). At view time view.php serves the package inside a sandboxed iframe and injects a SCORM 1.2 window.API shim; learner interactions are POSTed to track.php, normalised and scored server-side by local\track, recorded as attempts by local\attempts, and pushed to the gradebook by lib.php. The same scoring pipeline backs the save_track web service. classes/external exposes the API surface; classes/privacy declares personal data; backup/moodle2 exports and imports the activity.
Layered responsibility map
| Layer | Code | Responsibility |
|---|---|---|
| Moodle façade | lib.php | Module callbacks: *_supports, *_add/update/delete_instance, *_pluginfile, grade callbacks, reset, settings navigation. Each non-trivial callback is a thin delegator to a domain class. |
| Grades domain | classes/grades/grade_sync.php, grade_recalculator.php, grade_item_manager.php, completion_validator.php, gradeitems.php | Detect gradable iDevices and synchronise/soft-delete grade items; batched re-aggregation per user/item; overall-item guard and column naming; itemnumber_mapping interface. |
| Package domain | classes/local/package.php, classes/local/package_manager.php | Parse content.xml, detect gradable iDevices (isScorm), content hashing, XML hardening; store/locate the ELPX, validate content.xml, extract to content/{revision}/. |
| SCORM transforms | classes/local/scorm/scorm_injector.php, classes/local/scorm/idevice_patch.php | Inject the SCORM wrapper <script> tags + init() into extracted HTML; drop the body.exe-scorm save guard from form/scrambled-list iDevices (DEC-0042). |
| URLs / UI | classes/local/urls.php, classes/local/ui/teacher_mode_hider.php | Gradebook deep-link, grade-analysis, and navigation-before-key builders; queue the iframe teacher-toggle hider JS. |
| Tracking domain | classes/local/track.php | Ingest tracking payloads: normalise/clamp scores, route by stable objectid, recompute the overall server-side, enforce attempt caps, drive completion. Single source of truth for scoring. |
| Attempts domain | classes/local/attempts.php | Attempt numbering (session-token grouping), upsert of exelearning_attempt, aggregation (highest/average/first/last/lowest). |
| Gradebook mapping | classes/grades/gradeitems.php | itemnumber_mapping (0 = overall, 1..100 = per-iDevice) for Moodle 5.x completion-by-grade. Implements the core interface; strict_types. |
| API boundary | classes/external/* (7 classes) | Web services for the mobile app and admin AJAX editor management; each validates context, login, and capability. Fully declared in db/services.php. |
| Privacy | classes/privacy/provider.php | Declares exelearning_attempt metadata and the core_grades data flow; export/delete with grade recalculation. |
| Backup/Restore | backup/moodle2/* | Export/import instance, grade-item mappings, attempts (gated by userinfo), and the intro/package/content file areas; remap user ids. |
| Events | classes/event/* | attempt_deleted, report_viewed, course_module_instance_list_viewed. Selective observability — no per-commit event. |
| Global search | classes/search/activity.php | Search area extending \core_search\base_activity: indexes the activity intro and, via file indexing, the text extracted from the content file area. |
| Editor integration | classes/local/embedded_editor_*, classes/admin/*, amd/src/editor_modal.js, editor/index.php | Resolve/install/update/repair/uninstall the embedded editor; postMessage open/export bridge; save → re-extract → re-sync. |
| Entry points | view.php, track.php, grade.php, report.php, mod_form.php | View + SCORM shim; tracking endpoint; gradebook deep-link; attempts report; activity form. Thin controllers — security checks here, scoring logic delegated to local\*. |
Request flows
The three primary request flows show how each layer collaborates at runtime.1. Authoring (upload)
2. Delivery + grading (learner)
3. Mobile/external (web service)
The web and web-service paths cannot diverge on normalisation, objectid
filtering, overall recomputation, clamping, or the attempt cap — all of that
logic lives in the single unit-tested
track::ingest() (DEC-0040).Design principles
Thin controllers, fat domain classes
Entry-point PHP files handle authentication and transport. Scoring, parsing,
and aggregation live in
classes/local/* and classes/grades/*. lib.php
holds only Moodle-mandated callback signatures plus thin delegators (~960 lines
after the DEC-0054 extraction from ~1751).One scoring pipeline
Web and web-service paths converge on
track::ingest() (DEC-0040). A fix or
a hardening in that method applies to both channels simultaneously.Server authority over grades
The client never sets the overall grade. The server recomputes it from
per-iDevice
itemscores (DEC-0018). See the Tracking Pipeline
page for the full security model.Stable identity
Grade routing keys on the package
objectid (the odeIdeviceId from
content.xml), not page order (DEC-0017). Items soft-delete and carry a
content hash for staleness detection (DEC-0021).Defensive XML parsing
content.xml is parsed with a hardened DOM loader (no LIBXML_DTDLOAD,
no LIBXML_NOENT, internal entity rejection) and a controlled regex fallback
(DEC-0039). See the ELPX Package page for details.