. /** * LTI web service endpoints * * @package mod * @subpackage lti * @copyright Copyright (c) 2011 Moodlerooms Inc. (http://www.moodlerooms.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @author Chris Scribner */ require_once(dirname(__FILE__) . "/../../config.php"); require_once($CFG->dirroot.'/mod/lti/locallib.php'); require_once($CFG->dirroot.'/mod/lti/servicelib.php'); // TODO: Switch to core oauthlib once implemented - MDL-30149 use moodle\mod\lti as lti; $rawbody = file_get_contents("php://input"); foreach (getallheaders() as $name => $value) { if ($name === 'Authorization') { // TODO: Switch to core oauthlib once implemented - MDL-30149 $oauthparams = lti\OAuthUtil::split_header($value); $consumerkey = $oauthparams['oauth_consumer_key']; break; } } if (empty($consumerkey)) { throw new Exception('Consumer key is missing.'); } $sharedsecret = lti_verify_message($consumerkey, lti_get_shared_secrets_by_key($consumerkey), $rawbody); if ($sharedsecret === false) { throw new Exception('Message signature not valid'); } $xml = new SimpleXMLElement($rawbody); $body = $xml->imsx_POXBody; foreach ($body->children() as $child) { $messagetype = $child->getName(); } switch ($messagetype) { case 'replaceResultRequest': try { $parsed = lti_parse_grade_replace_message($xml); } catch (Exception $e) { $responsexml = lti_get_response_xml( 'failure', $e->getMessage(), uniqid(), 'replaceResultResponse'); echo $responsexml->asXML(); break; } $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid)); lti_verify_sourcedid($ltiinstance, $parsed); $gradestatus = lti_update_grade($ltiinstance, $parsed->userid, $parsed->launchid, $parsed->gradeval); $responsexml = lti_get_response_xml( $gradestatus ? 'success' : 'failure', 'Grade replace response', $parsed->messageid, 'replaceResultResponse' ); echo $responsexml->asXML(); break; case 'readResultRequest': $parsed = lti_parse_grade_read_message($xml); $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid)); //Getting the grade requires the context is set $context = get_context_instance(CONTEXT_COURSE, $ltiinstance->course); $PAGE->set_context($context); lti_verify_sourcedid($ltiinstance, $parsed); $grade = lti_read_grade($ltiinstance, $parsed->userid); $responsexml = lti_get_response_xml( isset($grade) ? 'success' : 'failure', 'Result read', $parsed->messageid, 'readResultResponse' ); $node = $responsexml->imsx_POXBody->readResultResponse; $node = $node->addChild('result')->addChild('resultScore'); $node->addChild('language', 'en'); $node->addChild('textString', isset($grade) ? $grade : ''); echo $responsexml->asXML(); break; case 'deleteResultRequest': $parsed = lti_parse_grade_delete_message($xml); $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid)); lti_verify_sourcedid($ltiinstance, $parsed); $gradestatus = lti_delete_grade($ltiinstance, $parsed->userid); $responsexml = lti_get_response_xml( $gradestatus ? 'success' : 'failure', 'Grade delete request', $parsed->messageid, 'deleteResultResponse' ); echo $responsexml->asXML(); break; default: //Fire an event if we get a web service request which we don't support directly. //This will allow others to extend the LTI services, which I expect to be a common //use case, at least until the spec matures. $data = new stdClass(); $data->body = $rawbody; $data->xml = $xml; $data->messagetype = $messagetype; $data->consumerkey = $consumerkey; $data->sharedsecret = $sharedsecret; //If an event handler handles the web service, it should set this global to true //So this code knows whether to send an "operation not supported" or not. global $lti_web_service_handled; $lti_web_service_handled = false; events_trigger('lti_unknown_service_api_call', $data); if (!$lti_web_service_handled) { $responsexml = lti_get_response_xml( 'unsupported', 'unsupported', lti_parse_message_id($xml), $messagetype ); echo $responsexml->asXML(); } break; } //echo print_r(apache_request_headers(), true); //echo '
'; //echo file_get_contents("php://input");