[ Index ] |
PHP Cross Reference of moodle-2.8 |
[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 $node = $xml->imsx_POXHeader->imsx_POXRequestHeaderInfo->imsx_messageIdentifier; 61 $messageid = (string)$node; 62 63 return $messageid; 64 } 65 66 function lti_parse_grade_replace_message($xml) { 67 $node = $xml->imsx_POXBody->replaceResultRequest->resultRecord->sourcedGUID->sourcedId; 68 $resultjson = json_decode((string)$node); 69 70 $node = $xml->imsx_POXBody->replaceResultRequest->resultRecord->result->resultScore->textString; 71 72 $score = (string) $node; 73 if ( ! is_numeric($score) ) { 74 throw new Exception('Score must be numeric'); 75 } 76 $grade = floatval($score); 77 if ( $grade < 0.0 || $grade > 1.0 ) { 78 throw new Exception('Score not between 0.0 and 1.0'); 79 } 80 81 $parsed = new stdClass(); 82 $parsed->gradeval = $grade; 83 84 $parsed->instanceid = $resultjson->data->instanceid; 85 $parsed->userid = $resultjson->data->userid; 86 $parsed->launchid = $resultjson->data->launchid; 87 $parsed->typeid = $resultjson->data->typeid; 88 $parsed->sourcedidhash = $resultjson->hash; 89 90 $parsed->messageid = lti_parse_message_id($xml); 91 92 return $parsed; 93 } 94 95 function lti_parse_grade_read_message($xml) { 96 $node = $xml->imsx_POXBody->readResultRequest->resultRecord->sourcedGUID->sourcedId; 97 $resultjson = json_decode((string)$node); 98 99 $parsed = new stdClass(); 100 $parsed->instanceid = $resultjson->data->instanceid; 101 $parsed->userid = $resultjson->data->userid; 102 $parsed->launchid = $resultjson->data->launchid; 103 $parsed->typeid = $resultjson->data->typeid; 104 $parsed->sourcedidhash = $resultjson->hash; 105 106 $parsed->messageid = lti_parse_message_id($xml); 107 108 return $parsed; 109 } 110 111 function lti_parse_grade_delete_message($xml) { 112 $node = $xml->imsx_POXBody->deleteResultRequest->resultRecord->sourcedGUID->sourcedId; 113 $resultjson = json_decode((string)$node); 114 115 $parsed = new stdClass(); 116 $parsed->instanceid = $resultjson->data->instanceid; 117 $parsed->userid = $resultjson->data->userid; 118 $parsed->launchid = $resultjson->data->launchid; 119 $parsed->typeid = $resultjson->data->typeid; 120 $parsed->sourcedidhash = $resultjson->hash; 121 122 $parsed->messageid = lti_parse_message_id($xml); 123 124 return $parsed; 125 } 126 127 function lti_accepts_grades($ltiinstance) { 128 global $DB; 129 130 $acceptsgrades = true; 131 $ltitype = $DB->get_record('lti_types', array('id' => $ltiinstance->typeid)); 132 133 if (empty($ltitype->toolproxyid)) { 134 $typeconfig = lti_get_config($ltiinstance); 135 136 $typeacceptgrades = isset($typeconfig['acceptgrades']) ? $typeconfig['acceptgrades'] : LTI_SETTING_DELEGATE; 137 138 if (!($typeacceptgrades == LTI_SETTING_ALWAYS || 139 ($typeacceptgrades == LTI_SETTING_DELEGATE && $ltiinstance->instructorchoiceacceptgrades == LTI_SETTING_ALWAYS))) { 140 $acceptsgrades = false; 141 } 142 } else { 143 $enabledcapabilities = explode("\n", $ltitype->enabledcapability); 144 $acceptsgrades = in_array('Result.autocreate', $enabledcapabilities); 145 } 146 147 return $acceptsgrades; 148 } 149 150 /** 151 * Set the passed user ID to the session user. 152 * 153 * @param int $userid 154 */ 155 function lti_set_session_user($userid) { 156 global $DB; 157 158 if ($user = $DB->get_record('user', array('id' => $userid))) { 159 \core\session\manager::set_user($user); 160 } 161 } 162 163 function lti_update_grade($ltiinstance, $userid, $launchid, $gradeval) { 164 global $CFG, $DB; 165 require_once($CFG->libdir . '/gradelib.php'); 166 167 $params = array(); 168 $params['itemname'] = $ltiinstance->name; 169 170 $gradeval = $gradeval * floatval($ltiinstance->grade); 171 172 $grade = new stdClass(); 173 $grade->userid = $userid; 174 $grade->rawgrade = $gradeval; 175 176 $status = grade_update(LTI_SOURCE, $ltiinstance->course, LTI_ITEM_TYPE, LTI_ITEM_MODULE, $ltiinstance->id, 0, $grade, $params); 177 178 $record = $DB->get_record('lti_submission', array('ltiid' => $ltiinstance->id, 'userid' => $userid, 179 'launchid' => $launchid), 'id'); 180 if ($record) { 181 $id = $record->id; 182 } else { 183 $id = null; 184 } 185 186 if (!empty($id)) { 187 $DB->update_record('lti_submission', array( 188 'id' => $id, 189 'dateupdated' => time(), 190 'gradepercent' => $gradeval, 191 'state' => 2 192 )); 193 } else { 194 $DB->insert_record('lti_submission', array( 195 'ltiid' => $ltiinstance->id, 196 'userid' => $userid, 197 'datesubmitted' => time(), 198 'dateupdated' => time(), 199 'gradepercent' => $gradeval, 200 'originalgrade' => $gradeval, 201 'launchid' => $launchid, 202 'state' => 1 203 )); 204 } 205 206 return $status == GRADE_UPDATE_OK; 207 } 208 209 function lti_read_grade($ltiinstance, $userid) { 210 global $CFG; 211 require_once($CFG->libdir . '/gradelib.php'); 212 213 $grades = grade_get_grades($ltiinstance->course, LTI_ITEM_TYPE, LTI_ITEM_MODULE, $ltiinstance->id, $userid); 214 215 $ltigrade = floatval($ltiinstance->grade); 216 217 if (!empty($ltigrade) && isset($grades) && isset($grades->items[0]) && is_array($grades->items[0]->grades)) { 218 foreach ($grades->items[0]->grades as $agrade) { 219 $grade = $agrade->grade; 220 $grade = $grade / $ltigrade; 221 break; 222 } 223 } 224 225 if (isset($grade)) { 226 return $grade; 227 } 228 } 229 230 function lti_delete_grade($ltiinstance, $userid) { 231 global $CFG; 232 require_once($CFG->libdir . '/gradelib.php'); 233 234 $grade = new stdClass(); 235 $grade->userid = $userid; 236 $grade->rawgrade = null; 237 238 $status = grade_update(LTI_SOURCE, $ltiinstance->course, LTI_ITEM_TYPE, LTI_ITEM_MODULE, $ltiinstance->id, 0, $grade); 239 240 return $status == GRADE_UPDATE_OK; 241 } 242 243 function lti_verify_message($key, $sharedsecrets, $body, $headers = null) { 244 foreach ($sharedsecrets as $secret) { 245 $signaturefailed = false; 246 247 try { 248 // TODO: Switch to core oauthlib once implemented - MDL-30149. 249 lti\handle_oauth_body_post($key, $secret, $body, $headers); 250 } catch (Exception $e) { 251 $signaturefailed = true; 252 } 253 254 if (!$signaturefailed) { 255 return $secret; // Return the secret used to sign the message). 256 } 257 } 258 259 return false; 260 } 261 262 /** 263 * Validate source ID from external request 264 * 265 * @param object $ltiinstance 266 * @param object $parsed 267 * @throws Exception 268 */ 269 function lti_verify_sourcedid($ltiinstance, $parsed) { 270 $sourceid = lti_build_sourcedid($parsed->instanceid, $parsed->userid, 271 $ltiinstance->servicesalt, $parsed->typeid, $parsed->launchid); 272 273 if ($sourceid->hash != $parsed->sourcedidhash) { 274 throw new Exception('SourcedId hash not valid'); 275 } 276 } 277 278 /** 279 * Extend the LTI services through the ltisource plugins 280 * 281 * @param stdClass $data LTI request data 282 * @return bool 283 * @throws coding_exception 284 */ 285 function lti_extend_lti_services($data) { 286 $plugins = get_plugin_list_with_function('ltisource', $data->messagetype); 287 if (!empty($plugins)) { 288 try { 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 } catch (moodle_exception $e) { 297 $error = $e->getMessage(); 298 if (debugging('', DEBUG_DEVELOPER)) { 299 $error .= ' '.format_backtrace(get_exception_info($e)->backtrace); 300 } 301 $responsexml = lti_get_response_xml( 302 'failure', 303 $error, 304 $data->messageid, 305 $data->messagetype 306 ); 307 308 header('HTTP/1.0 400 bad request'); 309 echo $responsexml->asXML(); 310 } 311 return true; 312 } 313 return false; 314 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |