Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]
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 * Handles synchronising grades for the enrolment LTI. 19 * 20 * @package enrol_lti 21 * @copyright 2016 Mark Nelson <markn@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace enrol_lti\task; 26 27 /** 28 * Task for synchronising grades for the enrolment LTI. 29 * 30 * @package enrol_lti 31 * @copyright 2016 Mark Nelson <markn@moodle.com> 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 */ 34 class sync_grades extends \core\task\scheduled_task { 35 36 /** 37 * Get a descriptive name for this task. 38 * 39 * @return string 40 */ 41 public function get_name() { 42 return get_string('tasksyncgrades', 'enrol_lti'); 43 } 44 45 /** 46 * Performs the synchronisation of grades. 47 * 48 * @return bool|void 49 */ 50 public function execute() { 51 global $DB, $CFG; 52 53 require_once($CFG->dirroot . '/enrol/lti/ims-blti/OAuth.php'); 54 require_once($CFG->dirroot . '/enrol/lti/ims-blti/OAuthBody.php'); 55 require_once($CFG->dirroot . '/lib/completionlib.php'); 56 require_once($CFG->libdir . '/gradelib.php'); 57 require_once($CFG->dirroot . '/grade/querylib.php'); 58 59 // Check if the authentication plugin is disabled. 60 if (!is_enabled_auth('lti')) { 61 mtrace('Skipping task - ' . get_string('pluginnotenabled', 'auth', get_string('pluginname', 'auth_lti'))); 62 return true; 63 } 64 65 // Check if the enrolment plugin is disabled - isn't really necessary as the task should not run if 66 // the plugin is disabled, but there is no harm in making sure core hasn't done something wrong. 67 if (!enrol_is_enabled('lti')) { 68 mtrace('Skipping task - ' . get_string('enrolisdisabled', 'enrol_lti')); 69 return true; 70 } 71 72 // Get all the enabled tools. 73 if ($tools = \enrol_lti\helper::get_lti_tools(array('status' => ENROL_INSTANCE_ENABLED, 'gradesync' => 1))) { 74 foreach ($tools as $tool) { 75 mtrace("Starting - Grade sync for shared tool '$tool->id' for the course '$tool->courseid'."); 76 77 // Variables to keep track of information to display later. 78 $usercount = 0; 79 $sendcount = 0; 80 81 // We check for all the users - users can access the same tool from different consumers. 82 if ($ltiusers = $DB->get_records('enrol_lti_users', array('toolid' => $tool->id), 'lastaccess DESC')) { 83 $completion = new \completion_info(get_course($tool->courseid)); 84 foreach ($ltiusers as $ltiuser) { 85 $mtracecontent = "for the user '$ltiuser->userid' in the tool '$tool->id' for the course " . 86 "'$tool->courseid'"; 87 88 $usercount = $usercount + 1; 89 90 // Check if we do not have a serviceurl - this can happen if the sync process has an unexpected error. 91 if (empty($ltiuser->serviceurl)) { 92 mtrace("Skipping - Empty serviceurl $mtracecontent."); 93 continue; 94 } 95 96 // Check if we do not have a sourceid - this can happen if the sync process has an unexpected error. 97 if (empty($ltiuser->sourceid)) { 98 mtrace("Skipping - Empty sourceid $mtracecontent."); 99 continue; 100 } 101 102 // Need a valid context to continue. 103 if (!$context = \context::instance_by_id($tool->contextid, IGNORE_MISSING)) { 104 mtrace("Failed - Invalid contextid '$tool->contextid' for the tool '$tool->id'."); 105 continue; 106 } 107 108 // Ok, let's get the grade. 109 $grade = false; 110 if ($context->contextlevel == CONTEXT_COURSE) { 111 // Check if the user did not completed the course when it was required. 112 if ($tool->gradesynccompletion && !$completion->is_course_complete($ltiuser->userid)) { 113 mtrace("Skipping - Course not completed $mtracecontent."); 114 continue; 115 } 116 117 // Get the grade. 118 if ($grade = grade_get_course_grade($ltiuser->userid, $tool->courseid)) { 119 $grademax = floatval($grade->item->grademax); 120 $grade = $grade->grade; 121 } 122 } else if ($context->contextlevel == CONTEXT_MODULE) { 123 $cm = get_coursemodule_from_id(false, $context->instanceid, 0, false, MUST_EXIST); 124 125 if ($tool->gradesynccompletion) { 126 $data = $completion->get_data($cm, false, $ltiuser->userid); 127 if ($data->completionstate != COMPLETION_COMPLETE_PASS && 128 $data->completionstate != COMPLETION_COMPLETE) { 129 mtrace("Skipping - Activity not completed $mtracecontent."); 130 continue; 131 } 132 } 133 134 $grades = grade_get_grades($cm->course, 'mod', $cm->modname, $cm->instance, $ltiuser->userid); 135 if (!empty($grades->items[0]->grades)) { 136 $grade = reset($grades->items[0]->grades); 137 if (!empty($grade->item)) { 138 $grademax = floatval($grade->item->grademax); 139 } else { 140 $grademax = floatval($grades->items[0]->grademax); 141 } 142 $grade = $grade->grade; 143 } 144 } 145 146 if ($grade === false || $grade === null || strlen($grade) < 1) { 147 mtrace("Skipping - Invalid grade $mtracecontent."); 148 continue; 149 } 150 151 // No need to be dividing by zero. 152 if (empty($grademax)) { 153 mtrace("Skipping - Invalid grade $mtracecontent."); 154 continue; 155 } 156 157 // Check to see if the grade has changed. 158 if (!grade_floats_different($grade, $ltiuser->lastgrade)) { 159 mtrace("Not sent - The grade $mtracecontent was not sent as the grades are the same."); 160 continue; 161 } 162 163 // Sync with the external system. 164 $floatgrade = $grade / $grademax; 165 $body = \enrol_lti\helper::create_service_body($ltiuser->sourceid, $floatgrade); 166 167 try { 168 $response = sendOAuthBodyPOST('POST', $ltiuser->serviceurl, 169 $ltiuser->consumerkey, $ltiuser->consumersecret, 'application/xml', $body); 170 } catch (\Exception $e) { 171 mtrace("Failed - The grade '$floatgrade' $mtracecontent failed to send."); 172 mtrace($e->getMessage()); 173 continue; 174 } 175 176 if (strpos(strtolower($response), 'success') !== false) { 177 $DB->set_field('enrol_lti_users', 'lastgrade', grade_floatval($grade), array('id' => $ltiuser->id)); 178 mtrace("Success - The grade '$floatgrade' $mtracecontent was sent."); 179 $sendcount = $sendcount + 1; 180 } else { 181 mtrace("Failed - The grade '$floatgrade' $mtracecontent failed to send."); 182 } 183 184 } 185 } 186 mtrace("Completed - Synced grades for tool '$tool->id' in the course '$tool->courseid'. " . 187 "Processed $usercount users; sent $sendcount grades."); 188 mtrace(""); 189 } 190 } 191 } 192 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body