[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 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. 8 // 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. 13 // 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/>. 16 17 /** 18 * Utility code for LTI service handling. 19 * 20 * @package mod_lti 21 * @copyright Copyright (c) 2011 Moodlerooms Inc. (http://www.moodlerooms.com) 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 * @author Chris Scribner 24 */ 25 26 defined('MOODLE_INTERNAL') || die; 27 28 require_once($CFG->dirroot.'/mod/lti/OAuthBody.php'); 29 30 // TODO: Switch to core oauthlib once implemented - MDL-30149. 31 use moodle\mod\lti as lti; 32 33 define('LTI_ITEM_TYPE', 'mod'); 34 define('LTI_ITEM_MODULE', 'lti'); 35 define('LTI_SOURCE', 'mod/lti'); 36 37 function lti_get_response_xml($codemajor, $description, $messageref, $messagetype) { 38 $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><imsx_POXEnvelopeResponse />'); 39 $xml->addAttribute('xmlns', 'http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0'); 40 41 $headerinfo = $xml->addChild('imsx_POXHeader')->addChild('imsx_POXResponseHeaderInfo'); 42 43 $headerinfo->addChild('imsx_version', 'V1.0'); 44 $headerinfo->addChild('imsx_messageIdentifier', (string)mt_rand()); 45 46 $statusinfo = $headerinfo->addChild('imsx_statusInfo'); 47 $statusinfo->addchild('imsx_codeMajor', $codemajor); 48 $statusinfo->addChild('imsx_severity', 'status'); 49 $statusinfo->addChild('imsx_description', $description); 50 $statusinfo->addChild('imsx_messageRefIdentifier', $messageref); 51 $incomingtype = str_replace('Response', 'Request', $messagetype); 52 $statusinfo->addChild('imsx_operationRefIdentifier', $incomingtype); 53 54 $xml->addChild('imsx_POXBody')->addChild($messagetype); 55 56 return $xml; 57 } 58 59 function lti_parse_message_id($xml) { 60 if (empty($xml->imsx_POXHeader)) { 61 return ''; 62 } 63 64 $node = $xml->imsx_POXHeader->imsx_POXRequestHeaderInfo->imsx_messageIdentifier; 65 $messageid = (string)$node; 66 67 return $messageid; 68 } 69 70 function lti_parse_grade_replace_message($xml) { 71 $node = $xml->imsx_POXBody->replaceResultRequest->resultRecord->sourcedGUID->sourcedId; 72 $resultjson = json_decode((string)$node); 73 74 $node = $xml->imsx_POXBody->replaceResultRequest->resultRecord->result->resultScore->textString; 75 76 $score = (string) $node; 77 if ( ! is_numeric($score) ) { 78 throw new Exception('Score must be numeric'); 79 } 80 $grade = floatval($score); 81 if ( $grade < 0.0 || $grade > 1.0 ) { 82 throw new Exception('Score not between 0.0 and 1.0'); 83 } 84 85 $parsed = new stdClass(); 86 $parsed->gradeval = $grade; 87 88 $parsed->instanceid = $resultjson->data->instanceid; 89 $parsed->userid = $resultjson->data->userid; 90 $parsed->launchid = $resultjson->data->launchid; 91 $parsed->typeid = $resultjson->data->typeid; 92 $parsed->sourcedidhash = $resultjson->hash; 93 94 $parsed->messageid = lti_parse_message_id($xml); 95 96 return $parsed; 97 } 98 99 function lti_parse_grade_read_message($xml) { 100 $node = $xml->imsx_POXBody->readResultRequest->resultRecord->sourcedGUID->sourcedId; 101 $resultjson = json_decode((string)$node); 102 103 $parsed = new stdClass(); 104 $parsed->instanceid = $resultjson->data->instanceid; 105 $parsed->userid = $resultjson->data->userid; 106 $parsed->launchid = $resultjson->data->launchid; 107 $parsed->typeid = $resultjson->data->typeid; 108 $parsed->sourcedidhash = $resultjson->hash; 109 110 $parsed->messageid = lti_parse_message_id($xml); 111 112 return $parsed; 113 } 114 115 function lti_parse_grade_delete_message($xml) { 116 $node = $xml->imsx_POXBody->deleteResultRequest->resultRecord->sourcedGUID->sourcedId; 117 $resultjson = json_decode((string)$node); 118 119 $parsed = new stdClass(); 120 $parsed->instanceid = $resultjson->data->instanceid; 121 $parsed->userid = $resultjson->data->userid; 122 $parsed->launchid = $resultjson->data->launchid; 123 $parsed->typeid = $resultjson->data->typeid; 124 $parsed->sourcedidhash = $resultjson->hash; 125 126 $parsed->messageid = lti_parse_message_id($xml); 127 128 return $parsed; 129 } 130 131 function lti_accepts_grades($ltiinstance) { 132 global $DB; 133 134 $acceptsgrades = true; 135 $ltitype = $DB->get_record('lti_types', array('id' => $ltiinstance->typeid)); 136 137 if (empty($ltitype->toolproxyid)) { 138 $typeconfig = lti_get_config($ltiinstance); 139 140 $typeacceptgrades = isset($typeconfig['acceptgrades']) ? $typeconfig['acceptgrades'] : LTI_SETTING_DELEGATE; 141 142 if (!($typeacceptgrades == LTI_SETTING_ALWAYS || 143 ($typeacceptgrades == LTI_SETTING_DELEGATE && $ltiinstance->instructorchoiceacceptgrades == LTI_SETTING_ALWAYS))) { 144 $acceptsgrades = false; 145 } 146 } else { 147 $enabledcapabilities = explode("\n", $ltitype->enabledcapability); 148 $acceptsgrades = in_array('Result.autocreate', $enabledcapabilities); 149 } 150 151 return $acceptsgrades; 152 } 153 154 /** 155 * Set the passed user ID to the session user. 156 * 157 * @param int $userid 158 */ 159 function lti_set_session_user($userid) { 160 global $DB; 161 162 if ($user = $DB->get_record('user', array('id' => $userid))) { 163 \core\session\manager::set_user($user); 164 } 165 } 166 167 function lti_update_grade($ltiinstance, $userid, $launchid, $gradeval) { 168 global $CFG, $DB; 169 require_once($CFG->libdir . '/gradelib.php'); 170 171 $params = array(); 172 $params['itemname'] = $ltiinstance->name; 173 174 $gradeval = $gradeval * floatval($ltiinstance->grade); 175 176 $grade = new stdClass(); 177 $grade->userid = $userid; 178 $grade->rawgrade = $gradeval; 179 180 $status = grade_update(LTI_SOURCE, $ltiinstance->course, LTI_ITEM_TYPE, LTI_ITEM_MODULE, $ltiinstance->id, 0, $grade, $params); 181 182 $record = $DB->get_record('lti_submission', array('ltiid' => $ltiinstance->id, 'userid' => $userid, 183 'launchid' => $launchid), 'id'); 184 if ($record) { 185 $id = $record->id; 186 } else { 187 $id = null; 188 } 189 190 if (!empty($id)) { 191 $DB->update_record('lti_submission', array( 192 'id' => $id, 193 'dateupdated' => time(), 194 'gradepercent' => $gradeval, 195 'state' => 2 196 )); 197 } else { 198 $DB->insert_record('lti_submission', array( 199 'ltiid' => $ltiinstance->id, 200 'userid' => $userid, 201 'datesubmitted' => time(), 202 'dateupdated' => time(), 203 'gradepercent' => $gradeval, 204 'originalgrade' => $gradeval, 205 'launchid' => $launchid, 206 'state' => 1 207 )); 208 } 209 210 return $status == GRADE_UPDATE_OK; 211 } 212 213 function lti_read_grade($ltiinstance, $userid) { 214 global $CFG; 215 require_once($CFG->libdir . '/gradelib.php'); 216 217 $grades = grade_get_grades($ltiinstance->course, LTI_ITEM_TYPE, LTI_ITEM_MODULE, $ltiinstance->id, $userid); 218 219 $ltigrade = floatval($ltiinstance->grade); 220 221 if (!empty($ltigrade) && isset($grades) && isset($grades->items[0]) && is_array($grades->items[0]->grades)) { 222 foreach ($grades->items[0]->grades as $agrade) { 223 $grade = $agrade->grade; 224 if (isset($grade)) { 225 return $grade / $ltigrade; 226 } 227 } 228 } 229 } 230 231 function lti_delete_grade($ltiinstance, $userid) { 232 global $CFG; 233 require_once($CFG->libdir . '/gradelib.php'); 234 235 $grade = new stdClass(); 236 $grade->userid = $userid; 237 $grade->rawgrade = null; 238 239 $status = grade_update(LTI_SOURCE, $ltiinstance->course, LTI_ITEM_TYPE, LTI_ITEM_MODULE, $ltiinstance->id, 0, $grade); 240 241 return $status == GRADE_UPDATE_OK; 242 } 243 244 function lti_verify_message($key, $sharedsecrets, $body, $headers = null) { 245 foreach ($sharedsecrets as $secret) { 246 $signaturefailed = false; 247 248 try { 249 // TODO: Switch to core oauthlib once implemented - MDL-30149. 250 lti\handle_oauth_body_post($key, $secret, $body, $headers); 251 } catch (Exception $e) { 252 $signaturefailed = true; 253 } 254 255 if (!$signaturefailed) { 256 return $secret; // Return the secret used to sign the message). 257 } 258 } 259 260 return false; 261 } 262 263 /** 264 * Validate source ID from external request 265 * 266 * @param object $ltiinstance 267 * @param object $parsed 268 * @throws Exception 269 */ 270 function lti_verify_sourcedid($ltiinstance, $parsed) { 271 $sourceid = lti_build_sourcedid($parsed->instanceid, $parsed->userid, 272 $ltiinstance->servicesalt, $parsed->typeid, $parsed->launchid); 273 274 if ($sourceid->hash != $parsed->sourcedidhash) { 275 throw new Exception('SourcedId hash not valid'); 276 } 277 } 278 279 /** 280 * Extend the LTI services through the ltisource plugins 281 * 282 * @param stdClass $data LTI request data 283 * @return bool 284 * @throws coding_exception 285 */ 286 function lti_extend_lti_services($data) { 287 $plugins = get_plugin_list_with_function('ltisource', $data->messagetype); 288 if (!empty($plugins)) { 289 // There can only be one. 290 if (count($plugins) > 1) { 291 throw new coding_exception('More than one ltisource plugin handler found'); 292 } 293 $data->xml = new SimpleXMLElement($data->body); 294 $callback = current($plugins); 295 call_user_func($callback, $data); 296 297 return true; 298 } 299 return false; 300 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |