2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * LTI web service endpoints
22 * @copyright Copyright (c) 2011 Moodlerooms Inc. (http://www.moodlerooms.com)
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * @author Chris Scribner
27 require_once(dirname(__FILE__
) . "/../../config.php");
28 require_once($CFG->dirroot
.'/mod/lti/locallib.php');
29 require_once($CFG->dirroot
.'/mod/lti/servicelib.php');
31 // TODO: Switch to core oauthlib once implemented - MDL-30149
32 use moodle\mod\lti
as lti
;
34 $rawbody = file_get_contents("php://input");
36 foreach (getallheaders() as $name => $value) {
37 if ($name === 'Authorization') {
38 // TODO: Switch to core oauthlib once implemented - MDL-30149
39 $oauthparams = lti\OAuthUtil
::split_header($value);
41 $consumerkey = $oauthparams['oauth_consumer_key'];
46 if (empty($consumerkey)) {
47 throw new Exception('Consumer key is missing.');
50 $sharedsecret = lti_verify_message($consumerkey, lti_get_shared_secrets_by_key($consumerkey), $rawbody);
52 if ($sharedsecret === false) {
53 throw new Exception('Message signature not valid');
56 $xml = new SimpleXMLElement($rawbody);
58 $body = $xml->imsx_POXBody
;
59 foreach ($body->children() as $child) {
60 $messagetype = $child->getName();
63 switch ($messagetype) {
64 case 'replaceResultRequest':
66 $parsed = lti_parse_grade_replace_message($xml);
67 } catch (Exception
$e) {
68 $responsexml = lti_get_response_xml(
72 'replaceResultResponse');
74 echo $responsexml->asXML();
78 $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid
));
80 lti_verify_sourcedid($ltiinstance, $parsed);
82 $gradestatus = lti_update_grade($ltiinstance, $parsed->userid
, $parsed->launchid
, $parsed->gradeval
);
84 $responsexml = lti_get_response_xml(
85 $gradestatus ?
'success' : 'failure',
86 'Grade replace response',
88 'replaceResultResponse'
91 echo $responsexml->asXML();
95 case 'readResultRequest':
96 $parsed = lti_parse_grade_read_message($xml);
98 $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid
));
100 //Getting the grade requires the context is set
101 $context = get_context_instance(CONTEXT_COURSE
, $ltiinstance->course
);
102 $PAGE->set_context($context);
104 lti_verify_sourcedid($ltiinstance, $parsed);
106 $grade = lti_read_grade($ltiinstance, $parsed->userid
);
108 $responsexml = lti_get_response_xml(
109 isset($grade) ?
'success' : 'failure',
115 $node = $responsexml->imsx_POXBody
->readResultResponse
;
116 $node = $node->addChild('result')->addChild('resultScore');
117 $node->addChild('language', 'en');
118 $node->addChild('textString', isset($grade) ?
$grade : '');
120 echo $responsexml->asXML();
124 case 'deleteResultRequest':
125 $parsed = lti_parse_grade_delete_message($xml);
127 $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid
));
129 lti_verify_sourcedid($ltiinstance, $parsed);
131 $gradestatus = lti_delete_grade($ltiinstance, $parsed->userid
);
133 $responsexml = lti_get_response_xml(
134 $gradestatus ?
'success' : 'failure',
135 'Grade delete request',
137 'deleteResultResponse'
140 echo $responsexml->asXML();
145 //Fire an event if we get a web service request which we don't support directly.
146 //This will allow others to extend the LTI services, which I expect to be a common
147 //use case, at least until the spec matures.
148 $data = new stdClass();
149 $data->body
= $rawbody;
151 $data->messagetype
= $messagetype;
152 $data->consumerkey
= $consumerkey;
153 $data->sharedsecret
= $sharedsecret;
155 //If an event handler handles the web service, it should set this global to true
156 //So this code knows whether to send an "operation not supported" or not.
157 global $lti_web_service_handled;
158 $lti_web_service_handled = false;
160 events_trigger('lti_unknown_service_api_call', $data);
162 if (!$lti_web_service_handled) {
163 $responsexml = lti_get_response_xml(
166 lti_parse_message_id($xml),
170 echo $responsexml->asXML();
177 //echo print_r(apache_request_headers(), true);
181 //echo file_get_contents("php://input");