// Store things that gradeSubmit.php will need into the session session_start(); $_SESSION['lis_outcome_service_url'] = $_REQUEST['lis_outcome_service_url']; $_SESSION['lis_result_sourcedid'] = $_REQUEST['lis_result_sourcedid']; $_SESSION['lis_person_name_given'] = $_REQUEST['lis_person_name_given']; $_SESSION['oauth_consumer_key'] = $_REQUEST['oauth_consumer_key']; $_SESSION['oauth_consumer_secret'] = $oauth_consumer_secret; session_write_close(); /* * READ BACK OUR GRADE * If it exists, show the grade and disable the submit button. */ $endpoint = $_REQUEST['lis_outcome_service_url']; $sourcedid = $_REQUEST['lis_result_sourcedid']; $postBody = str_replace(array('SOURCEDID', 'OPERATION', 'MESSAGE'), array($sourcedid, 'readResultRequest', uniqid()), getPOXRequest()); $response = parseResponse(sendOAuthBodyPOST('POST', $endpoint, $oauth_consumer_key, $oauth_consumer_secret, 'application/xml', $postBody)); if ($response['imsx_codeMajor'] == 'success' && $response['textString'] != '') { $grade = $response['textString']; $showGrade = true; $disabled = 'disabled'; } } /* * CUSTOM LTI LAUNCH PARAMETERS * The "posted date" is the date that the quiz is posted. It is either set * in the "Edit Link" page of "External Learning Tools" in your LMS, or set * when the link is created with the Valence REST API. * This example parameter is NOT automatically set by the LMS! */ if (isset($_SESSION['custom_timecreated'])) { $postedDate = date('l, F j, Y', $_SESSION['custom_timecreated']);
/** * Performs the synchronisation of grades. * * @return bool|void */ public function execute() { global $DB, $CFG; require_once $CFG->dirroot . '/enrol/lti/ims-blti/OAuth.php'; require_once $CFG->dirroot . '/enrol/lti/ims-blti/OAuthBody.php'; require_once $CFG->dirroot . '/lib/completionlib.php'; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->dirroot . '/grade/querylib.php'; // Check if the authentication plugin is disabled. if (!is_enabled_auth('lti')) { mtrace('Skipping task - ' . get_string('pluginnotenabled', 'auth', get_string('pluginname', 'auth_lti'))); return true; } // Check if the enrolment plugin is disabled - isn't really necessary as the task should not run if // the plugin is disabled, but there is no harm in making sure core hasn't done something wrong. if (!enrol_is_enabled('lti')) { mtrace('Skipping task - ' . get_string('enrolisdisabled', 'enrol_lti')); return true; } // Get all the enabled tools. if ($tools = \enrol_lti\helper::get_lti_tools(array('status' => ENROL_INSTANCE_ENABLED, 'gradesync' => 1))) { foreach ($tools as $tool) { mtrace("Starting - Grade sync for shared tool '{$tool->id}' for the course '{$tool->courseid}'."); // Variables to keep track of information to display later. $usercount = 0; $sendcount = 0; // We check for all the users - users can access the same tool from different consumers. if ($ltiusers = $DB->get_records('enrol_lti_users', array('toolid' => $tool->id), 'lastaccess DESC')) { $completion = new \completion_info(get_course($tool->courseid)); foreach ($ltiusers as $ltiuser) { $mtracecontent = "for the user '{$ltiuser->userid}' in the tool '{$tool->id}' for the course " . "'{$tool->courseid}'"; $usercount = $usercount + 1; // Check if we do not have a serviceurl - this can happen if the sync process has an unexpected error. if (empty($ltiuser->serviceurl)) { mtrace("Skipping - Empty serviceurl {$mtracecontent}."); continue; } // Check if we do not have a sourceid - this can happen if the sync process has an unexpected error. if (empty($ltiuser->sourceid)) { mtrace("Skipping - Empty sourceid {$mtracecontent}."); continue; } // Need a valid context to continue. if (!($context = \context::instance_by_id($tool->contextid))) { mtrace("Failed - Invalid contextid '{$tool->contextid}' for the tool '{$tool->id}'."); continue; } // Ok, let's get the grade. $grade = false; if ($context->contextlevel == CONTEXT_COURSE) { // Check if the user did not completed the course when it was required. if ($tool->gradesynccompletion && !$completion->is_course_complete($ltiuser->userid)) { mtrace("Skipping - Course not completed {$mtracecontent}."); continue; } // Get the grade. if ($grade = grade_get_course_grade($ltiuser->userid, $tool->courseid)) { $grademax = floatval($grade->item->grademax); $grade = $grade->grade; } } else { if ($context->contextlevel == CONTEXT_MODULE) { $cm = get_coursemodule_from_id(false, $context->instanceid, 0, false, MUST_EXIST); if ($tool->gradesynccompletion) { $data = $completion->get_data($cm, false, $ltiuser->userid); if ($data->completionstate != COMPLETION_COMPLETE_PASS && $data->completionstate != COMPLETION_COMPLETE) { mtrace("Skipping - Activity not completed {$mtracecontent}."); continue; } } $grades = grade_get_grades($cm->course, 'mod', $cm->modname, $cm->instance, $ltiuser->userid); if (!empty($grades->items[0]->grades)) { $grade = reset($grades->items[0]->grades); if (!empty($grade->item)) { $grademax = floatval($grade->item->grademax); } else { $grademax = floatval($grades->items[0]->grademax); } $grade = $grade->grade; } } } if ($grade === false || $grade === null || strlen($grade) < 1) { mtrace("Skipping - Invalid grade {$mtracecontent}."); continue; } // No need to be dividing by zero. if (empty($grademax)) { mtrace("Skipping - Invalid grade {$mtracecontent}."); continue; } // This can happen if the sync process has an unexpected error. if ($grade == $ltiuser->lastgrade) { mtrace("Not sent - The grade {$mtracecontent} was not sent as the grades are the same."); continue; } // Sync with the external system. $floatgrade = $grade / $grademax; $body = \enrol_lti\helper::create_service_body($ltiuser->sourceid, $floatgrade); try { $response = sendOAuthBodyPOST('POST', $ltiuser->serviceurl, $ltiuser->consumerkey, $ltiuser->consumersecret, 'application/xml', $body); } catch (\Exception $e) { mtrace("Failed - The grade '{$floatgrade}' {$mtracecontent} failed to send."); mtrace($e->getMessage()); continue; } if (strpos(strtolower($response), 'success') !== false) { $DB->set_field('enrol_lti_users', 'lastgrade', intval($grade), array('id' => $ltiuser->id)); mtrace("Success - The grade '{$floatgrade}' {$mtracecontent} was sent."); $sendcount = $sendcount + 1; } else { mtrace("Failed - The grade '{$floatgrade}' {$mtracecontent} failed to send."); } } } mtrace("Completed - Synced grades for tool '{$tool->id}' in the course '{$tool->courseid}'. " . "Processed {$usercount} users; sent {$sendcount} grades."); mtrace(""); } } }
function replaceResultRequest($grade, $sourcedid, $endpoint, $oauth_consumer_key, $oauth_consumer_secret) { $method = "POST"; $content_type = "application/xml"; $operation = 'replaceResultRequest'; $postBody = str_replace(array('SOURCEDID', 'GRADE', 'OPERATION', 'MESSAGE'), array($sourcedid, $grade, $operation, uniqid()), getPOXGradeRequest()); $response = sendOAuthBodyPOST($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $postBody); return parseResponse($response); }
<?php $url = $_REQUEST['url']; $oauth_consumer_key = $_REQUEST['key']; $method = "POST"; $endpoint = $_REQUEST['url']; $content_type = "application/xml"; if ($_REQUEST['submit'] == "Get Course Structure" && isset($_REQUEST['context_id']) && isset($_REQUEST['lis_result_sourcedid'])) { $postBody = str_replace(array('USER_ID', 'CONTEXT_ID', 'LIS_RESULT_SOURCEDID', 'MESSAGE'), array($user_id, $context_id, htmlentities($lis_result_sourcedid), uniqid()), $getCourseStructureRequest); } else { if ($_REQUEST['submit'] == "Add Course Resource" && isset($_REQUEST['context_id']) && isset($_REQUEST['lis_result_sourcedid'])) { $postBody = str_replace(array('USER_ID', 'CONTEXT_ID', 'LIS_RESULT_SOURCEDID', 'FOLDER_ID', 'MESSAGE'), array($user_id, $context_id, htmlentities($lis_result_sourcedid), $folderId, uniqid()), $addCourseResourcesRequest); } else { exit; } } $response = sendOAuthBodyPOST($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $postBody); global $LastOAuthBodyBaseString; $lbs = $LastOAuthBodyBaseString; try { $retval = parseResponse($response); } catch (Exception $e) { $retval = $e->getMessage(); } echo "\n<pre>\n"; echo "Service Url:\n"; echo htmlentities($endpoint) . "\n\n"; print_r($retval); echo "\n"; echo "------------ POST RETURNS ------------\n"; $response = str_replace("><", ">\n<", $response); $response = str_replace("<", "<", $response);
if ($formdata = $mform->get_data()) { if (isset($formdata->replaceResultRequest)) { $operation = 'replaceResultRequest'; $postBody = str_replace(array('SOURCEDID', 'GRADE', 'OPERATION', 'MESSAGE'), array($sourcedid, $_REQUEST['grade'], $operation, uniqid()), getPOXGradeRequest()); } else { if (isset($formdata->readResultRequest)) { $operation = 'readResultRequest'; $postBody = str_replace(array('SOURCEDID', 'OPERATION', 'MESSAGE'), array($sourcedid, $operation, uniqid()), getPOXRequest()); } else { if (isset($formdata->deleteResultRequest)) { $operation = 'deleteResultRequest'; $postBody = str_replace(array('SOURCEDID', 'OPERATION', 'MESSAGE'), array($sourcedid, $operation, uniqid()), getPOXRequest()); } } } $response = sendOAuthBodyPOST('POST', $outcomeurl, $postBody); echo html_writer::link($graderurl, "Check in grade report"); try { $retval = parseResponse($response); } catch (Exception $e) { $retval = $e->getMessage(); } echo $OUTPUT->heading('Grading Results', 5); echo html_writer::start_tag('pre'); print_r($retval); echo html_writer::end_tag('pre'); echo $OUTPUT->heading('RAW Response', 5); echo $OUTPUT->box_start(); echo html_writer::tag('textarea', $response, array('cols' => 80, 'rows' => 10)); echo $OUTPUT->box_end(); }
<sourcedId>' . $_SESSION['lis_result_sourcedid'] . '</sourcedId> </sourcedGUID> <result> <resultScore> <language>en</language> <textString>1</textString> </resultScore> </result> </resultRecord> </replaceResultRequest> </imsx_POXBody> </imsx_POXEnvelopeRequest>'; $method = 'POST'; $endpoint = $_SESSION['lis_outcome_service_url']; $oauth_consumer_key = $_SESSION['oauth_consumer_key']; $oauth_consumer_secret = 'YourSecret'; $content_type = 'application/xml'; $hash = base64_encode(sha1($body, TRUE)); $parms = array('oauth_body_hash' => $hash); $test_token = ''; $hmac_method = new OAuthSignatureMethod_HMAC_SHA1(); $test_consumer = new OAuthConsumer($oauth_consumer_key, $oauth_consumer_secret, NULL); $acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, $method, $endpoint, $parms); $acc_req->sign_request($hmac_method, $test_consumer, $test_token); $header = $acc_req->to_header(); $auth_header = $header . "\r\nContent-type: " . $content_type . "\r\n"; $sendOAuthBodyPOST = sendOAuthBodyPOST($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $body); echo $sendOAuthBodyPOST; } else { echo "Failed to authenticate"; }
function sendLTIOutcome($action, $key, $secret, $url, $sourcedid, $grade = 0) { $method = "POST"; $content_type = "application/xml"; $body = '<?xml version = "1.0" encoding = "UTF-8"?> <imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0"> <imsx_POXHeader> <imsx_POXRequestHeaderInfo> <imsx_version>V1.0</imsx_version> <imsx_messageIdentifier>MESSAGE</imsx_messageIdentifier> </imsx_POXRequestHeaderInfo> </imsx_POXHeader> <imsx_POXBody> <OPERATION> <resultRecord> <sourcedGUID> <sourcedId>SOURCEDID</sourcedId> </sourcedGUID> <result> <resultScore> <language>en-us</language> <textString>GRADE</textString> </resultScore> </result> </resultRecord> </OPERATION> </imsx_POXBody> </imsx_POXEnvelopeRequest>'; $shortBody = '<?xml version = "1.0" encoding = "UTF-8"?> <imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0"> <imsx_POXHeader> <imsx_POXRequestHeaderInfo> <imsx_version>V1.0</imsx_version> <imsx_messageIdentifier>MESSAGE</imsx_messageIdentifier> </imsx_POXRequestHeaderInfo> </imsx_POXHeader> <imsx_POXBody> <OPERATION> <resultRecord> <sourcedGUID> <sourcedId>SOURCEDID</sourcedId> </sourcedGUID> </resultRecord> </OPERATION> </imsx_POXBody> </imsx_POXEnvelopeRequest>'; if ($action == 'update') { $operation = 'replaceResultRequest'; $postBody = str_replace(array('SOURCEDID', 'GRADE', 'OPERATION', 'MESSAGE'), array($sourcedid, $grade, $operation, uniqid()), $body); } else { if ($action == 'read') { $operation = 'readResultRequest'; $postBody = str_replace(array('SOURCEDID', 'OPERATION', 'MESSAGE'), array($sourcedid, $operation, uniqid()), $shortBody); } else { if ($action == 'delete') { $operation = 'deleteResultRequest'; $postBody = str_replace(array('SOURCEDID', 'OPERATION', 'MESSAGE'), array($sourcedid, $operation, uniqid()), $shortBody); } else { return false; } } } $response = sendOAuthBodyPOST($method, $url, $key, $secret, $content_type, $postBody); return $response; }