-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrack.php
More file actions
74 lines (63 loc) · 3.12 KB
/
Copy pathtrack.php
File metadata and controls
74 lines (63 loc) · 3.12 KB
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
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* mod_exelearning tracking endpoint (SCORM bridge).
*
* Receives CMI pairs from the SCORM 1.2 shim that lives in `view.php` and hands
* them to {@see \mod_exelearning\local\track::ingest()}, the shared scoring
* pipeline (also used by the `save_track` web service for the mobile app). This
* script only does the web-specific part: sesskey + capability authentication and
* the JSON response (including the 409 status when the attempt cap is reached).
*
* Endpoint: POST with sesskey + JSON `{ id: <cmid>, cmi: { "cmi.core.score.raw": "85", ... } }`.
*
* @package mod_exelearning
* @copyright 2026 ATE (Área de Tecnología Educativa)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('AJAX_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->dirroot . '/mod/exelearning/lib.php');
$cmid = required_param('id', PARAM_INT);
$mode = optional_param('mode', 'grading', PARAM_ALPHA);
require_sesskey();
$cm = get_coursemodule_from_id('exelearning', $cmid, 0, false, MUST_EXIST);
$course = $DB->get_record('course', ['id' => $cm->course], '*', MUST_EXIST);
$exelearning = $DB->get_record('exelearning', ['id' => $cm->instance], '*', MUST_EXIST);
require_login($course, false, $cm);
$context = context_module::instance($cm->id);
// Preview mode (DEC-0006): only when the caller has management capability.
// A regular student who changes ?mode=preview falls back to grading silently.
$ispreview = ($mode === 'preview')
&& has_capability('moodle/course:manageactivities', $context);
if (!$ispreview) {
require_capability('mod/exelearning:savetrack', $context);
}
$raw = file_get_contents('php://input');
$payload = $raw ? json_decode($raw, true) : null;
if (!is_array($payload) || !isset($payload['cmi']) || !is_array($payload['cmi'])) {
throw new \moodle_exception('invalidparameter', 'error');
}
// All scoring logic (normalisation, objectid routing, server-side overall
// recompute, attempt cap and completion) lives in the shared, unit-tested
// ingest() so the web and web-service paths cannot diverge.
$result = \mod_exelearning\local\track::ingest($exelearning, $course, $cm, $USER->id, $payload, $ispreview);
// The attempt cap is a conflict, not a server error: signal it with HTTP 409 as
// the client shim expects (the JSON body carries the details either way).
if (!empty($result['error']) && $result['error'] === 'maxattemptsreached') {
http_response_code(409);
}
echo json_encode($result);