Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updating LTI submission viewer

  • Loading branch information...
commit f4f711d79b1c9c3de2ca55c7905c2b93057f82b9 1 parent a35626f
@scriby scriby authored
View
2  mod/lti/db/access.php
@@ -44,7 +44,7 @@
$capabilities = array(
- 'mod/ltii:view' => array(
+ 'mod/lti:view' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
View
23 mod/lti/db/install.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/lti/db" VERSION="20110901" COMMENT="XMLDB file for Moodle mod/lti"
+<XMLDB PATH="mod/lti/db" VERSION="20110923" COMMENT="XMLDB file for Moodle mod/lti"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
@@ -58,7 +58,7 @@
<INDEX NAME="tooldomain" UNIQUE="false" FIELDS="tooldomain" PREVIOUS="course"/>
</INDEXES>
</TABLE>
- <TABLE NAME="lti_types_config" COMMENT="Basic LTI types configuration" PREVIOUS="lti_types">
+ <TABLE NAME="lti_types_config" COMMENT="Basic LTI types configuration" PREVIOUS="lti_types" NEXT="lti_submission">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="typeid"/>
<FIELD NAME="typeid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Basic LTI type id" PREVIOUS="id" NEXT="name"/>
@@ -72,5 +72,24 @@
<INDEX NAME="typeid" UNIQUE="false" FIELDS="typeid"/>
</INDEXES>
</TABLE>
+ <TABLE NAME="lti_submission" COMMENT="Keeps track of individual submissions for LTI activities." PREVIOUS="lti_types_config">
+ <FIELDS>
+ <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="ltiid"/>
+ <FIELD NAME="ltiid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="ID of the LTI tool instance" PREVIOUS="id" NEXT="userid"/>
+ <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="ltiid" NEXT="datesubmitted"/>
+ <FIELD NAME="datesubmitted" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="userid" NEXT="dateupdated"/>
+ <FIELD NAME="dateupdated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="datesubmitted" NEXT="gradepercent"/>
+ <FIELD NAME="gradepercent" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" DECIMALS="5" PREVIOUS="dateupdated" NEXT="originalgrade"/>
+ <FIELD NAME="originalgrade" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" DECIMALS="5" PREVIOUS="gradepercent" NEXT="launchid"/>
+ <FIELD NAME="launchid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="originalgrade" NEXT="state"/>
+ <FIELD NAME="state" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="launchid"/>
+ </FIELDS>
+ <KEYS>
+ <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+ </KEYS>
+ <INDEXES>
+ <INDEX NAME="ltiid" UNIQUE="false" FIELDS="ltiid"/>
+ </INDEXES>
+ </TABLE>
</TABLES>
</XMLDB>
View
94 mod/lti/submissions.php → mod/lti/grade.php
@@ -89,4 +89,96 @@
require_capability('mod/lti:grade', get_context_instance(CONTEXT_MODULE, $cm->id));
-lti_submissions($cm, $course, $basiclti, $mode); // Display or process the submissions
+//lti_submissions($cm, $course, $basiclti, $mode); // Display or process the submissions
+
+$module = array(
+ 'name' => 'mod_lti_submissions',
+ 'fullpath' => '/mod/lti/submissions.js',
+ 'requires' => array('base'),
+ 'strings' => array(
+
+ ),
+);
+
+$PAGE->requires->js_init_call('M.mod_lti.submissions.init', array(), true, $module);
+
+$PAGE->requires->yui2_lib('datatable');
+
+$submissionquery = <<<SQL
+ SELECT s.id, u.firstname, u.lastname, u.id AS userid, s.datesubmitted, s.gradepercent
+ FROM {lti_submission} s
+ INNER JOIN {user} u ON s.userid = u.id
+ WHERE s.ltiid = :ltiid
+ ORDER BY s.datesubmitted DESC
+SQL;
+
+$submissions = $DB->get_records_sql($submissionquery, array('ltiid' => $basiclti->id));
+
+$html = <<<HTML
+<noscript>
+ <!-- If javascript is disabled, we need to show the table using CSS.
+ The table starts out hidden to avoid flickering as it loads -->
+ <style type="text/css">
+ #lti_submissions_table_container { display: block !important; }
+ </style>
+</noscript>
+
+<div id="lti_submissions_table_container" style="display:none">
+ <table id='lti_submissions_table'>
+ <thead>
+ <tr>
+ <th>User</th>
+ <th>Date</th>
+ <th>Grade</th>
+ </tr>
+ </thead>
+ <tbody>
+ <!--table body-->
+ </tbody>
+ </table>
+</div>
+HTML;
+
+$rowtemplate = <<<HTML
+<tr>
+ <td>
+ <!--firstname--> <!--lastname-->
+ </td>
+ <td>
+ <!--datesubmitted-->
+ </td>
+ <td>
+ <!--gradepercent-->
+ </td>
+</tr>
+HTML;
+
+$rows = '';
+
+foreach($submissions as $submission){
+ $row = $rowtemplate;
+
+ foreach($submission as $key => $value){
+ if($key === 'datesubmitted'){
+ $value = userdate($value);
+ }
+
+ $row = str_replace('<!--' . $key . '-->', $value, $row);
+ }
+
+ $rows .= $row;
+}
+
+$table = str_replace('<!--table body-->', $rows, $html);
+
+$title = 'Submissions for ' . $basiclti->name;
+
+$PAGE->set_title(format_string($title , true));
+$PAGE->set_heading($course->fullname);
+
+echo $OUTPUT->header();
+echo $OUTPUT->heading($title );
+
+echo $table;
+
+echo $OUTPUT->footer();
View
657 mod/lti/lib.php
@@ -316,652 +316,6 @@ function lti_get_lti_types() {
}
/**
- * Returns Basic LTI types configuration
- *
- * @return array of basicLTI types
- */
-/*function lti_get_types() {
- $types = array();
-
- $basicltitypes = lti_get_lti_types();
- if (!empty($basicltitypes)) {
- foreach ($basicltitypes as $basicltitype) {
- $ltitypesconfig = lti_get_type_config($basicltitype->id);
-
- $modclass = MOD_CLASS_ACTIVITY;
- if (isset($ltitypesconfig['module_class_type'])) {
- if ($ltitypesconfig['module_class_type']=='1') {
- $modclass = MOD_CLASS_RESOURCE;
- }
- }
-
- $type = new object();
- $type->modclass = $modclass;
- $type->type = 'lti&amp;type='.urlencode($basicltitype->rawname);
- $type->typestr = $basicltitype->name;
- $types[] = $type;
- }
- }
-
- return $types;
-}*/
-
-//////////////////////////////////////////////////////////////////////////////////////
-/// Any other basiclti functions go here. Each of them must have a name that
-/// starts with basiclti_
-/// Remember (see note in first lines) that, if this section grows, it's HIGHLY
-/// recommended to move all funcions below to a new "localib.php" file.
-
-///**
-// *
-// */
-//function process_outcomes($userid, $course, $basiclti) {
-// global $CFG, $USER;
-//
-// if (empty($CFG->enableoutcomes)) {
-// return;
-// }
-//
-// require_once($CFG->libdir.'/gradelib.php');
-//
-// if (!$formdata = data_submitted() or !confirm_sesskey()) {
-// return;
-// }
-//
-// $data = array();
-// $grading_info = grade_get_grades($course->id, 'mod', 'basiclti', $basiclti->id, $userid);
-//
-// if (!empty($grading_info->outcomes)) {
-// foreach ($grading_info->outcomes as $n => $old) {
-// $name = 'outcome_'.$n;
-// if (isset($formdata->{$name}[$userid]) and $old->grades[$userid]->grade != $formdata->{$name}[$userid]) {
-// $data[$n] = $formdata->{$name}[$userid];
-// }
-// }
-// }
-// if (count($data) > 0) {
-// grade_update_outcomes('mod/basiclti', $course->id, 'mod', 'basiclti', $basiclti->id, $userid, $data);
-// }
-//
-//}
-
-/**
- * Top-level function for handling of submissions called by submissions.php
- *
- * This is for handling the teacher interaction with the grading interface
- *
- * @global object
- * @param string $mode Specifies the kind of teacher interaction taking place
- */
-function lti_submissions($cm, $course, $basiclti, $mode) {
- ///The main switch is changed to facilitate
- ///1) Batch fast grading
- ///2) Skip to the next one on the popup
- ///3) Save and Skip to the next one on the popup
-
- //make user global so we can use the id
- global $USER, $OUTPUT, $DB;
-
- $mailinfo = optional_param('mailinfo', null, PARAM_BOOL);
-
- if (optional_param('next', null, PARAM_BOOL)) {
- $mode='next';
- }
- if (optional_param('saveandnext', null, PARAM_BOOL)) {
- $mode='saveandnext';
- }
-
- if (is_null($mailinfo)) {
- if (optional_param('sesskey', null, PARAM_BOOL)) {
- set_user_preference('lti_mailinfo', $mailinfo);
- } else {
- $mailinfo = get_user_preferences('lti_mailinfo', 0);
- }
- } else {
- set_user_preference('lti_mailinfo', $mailinfo);
- }
-
- switch ($mode) {
- case 'grade': // We are in a main window grading
- if ($submission = process_feedback()) {
- lti_display_submissions($cm, $course, $basiclti, get_string('changessaved'));
- } else {
- lti_display_submissions($cm, $course, $basiclti);
- }
- break;
-
- case 'single': // We are in a main window displaying one submission
- if ($submission = process_feedback()) {
- lti_display_submissions($cm, $course, $basiclti, get_string('changessaved'));
- } else {
- display_submission();
- }
- break;
-
- case 'all': // Main window, display everything
- lti_display_submissions($cm, $course, $basiclti);
- break;
-
- case 'fastgrade':
- /// do the fast grading stuff - this process should work for all 3 subclasses
- $grading = false;
- $commenting = false;
- $col = false;
- if (isset($_POST['submissioncomment'])) {
- $col = 'submissioncomment';
- $commenting = true;
- }
- if (isset($_POST['menu'])) {
- $col = 'menu';
- $grading = true;
- }
- if (!$col) {
- //both submissioncomment and grade columns collapsed..
- lti_display_submissions($cm, $course, $basiclti);
- break;
- }
-
- foreach ($_POST[$col] as $id => $unusedvalue) {
-
- $id = (int)$id; //clean parameter name
-
- // Get grade item
- $gradeitem = $DB->get_record('grade_items', array('courseid' => $cm->course, 'iteminstance' => $cm->instance));
-
- // Get grade
- $gradeentry = $DB->get_record('grade_grades', array('userid' => $id, 'itemid' => $gradeitem->id));
-
- $grade = $_POST['menu'][$id];
- $feedback = trim($_POST['submissioncomment'][$id]);
-
- if ((!$gradeentry) && (($grade != '-1') || ($feedback != ''))) {
- $newsubmission = true;
- } else {
- $newsubmission = false;
- }
-
- //for fast grade, we need to check if any changes take place
- $updatedb = false;
-
- if ($gradeentry) {
- if ($grading) {
- $grade = $_POST['menu'][$id];
- $updatedb = $updatedb || (($gradeentry->rawgrade != $grade) && ($gradeentry->rawgrade != '-1'));
- if ($grade != '-1') {
- $gradeentry->rawgrade = $grade;
- $gradeentry->finalgrade = $grade;
- } else {
- $gradeentry->rawgrade = null;
- $gradeentry->finalgrade = null;
- }
- } else {
- if (!$newsubmission) {
- unset($gradeentry->rawgrade); // Don't need to update this.
- }
- }
-
- if ($commenting) {
- $commentvalue = trim($_POST['submissioncomment'][$id]);
- $updatedb = $updatedb || ($gradeentry->feedback != $commentvalue);
- // Special case
- if (($gradeentry->feedback == null) && ($commentvalue == "")) {
- unset($gradeentry->feedback);
- }
- $gradeentry->feedback = $commentvalue;
- } else {
- unset($gradeentry->feedback); // Don't need to update this.
- }
-
- } else { // No previous grade entry found
- if ($newsubmission) {
- if ($grade != '-1') {
- $gradeentry->rawgrade = $grade;
- $updatedb = true;
- }
- if ($feedback != '') {
- $gradeentry->feedback = $feedback;
- $updatedb = true;
- }
- }
- }
-
- $gradeentry->usermodified = $USER->id;
- if (!$gradeentry->timecreated) {
- $gradeentry->timecreated = time();
- }
- $gradeentry->timemodified = time();
-
- //if it is not an update, we don't change the last modified time etc.
- //this will also not write into database if no submissioncomment and grade is entered.
- if ($updatedb) {
- if ($gradeentry->rawgrade == '-1') {
- $gradeentry->rawgrade = null;
- }
-
- if ($newsubmission) {
- if (!isset($gradeentry->feedback)) {
- $gradeentry->feedback = '';
- }
- $gradeentry->itemid = $gradeitem->id;
- $gradeentry->userid = $id;
- $sid = $DB->insert_record("grade_grades", $gradeentry);
- $gradeentry->id = $sid;
- } else {
- $DB->update_record("grade_grades", $gradeentry);
- }
-
- //add to log only if updating
- add_to_log($course->id, 'lti', 'update grades',
- 'submissions.php?id='.$cm->id.'&user='.$USER->id,
- $USER->id, $cm->id);
- }
-
- }
-
- $message = $OUTPUT->notification(get_string('changessaved'), 'notifysuccess');
-
- lti_display_submissions($cm, $course, $basiclti, $message);
- break;
-
- case 'saveandnext':
- ///We are in pop up. save the current one and go to the next one.
- //first we save the current changes
- if ($submission = process_feedback()) {
- //print_heading(get_string('changessaved'));
- //$extra_javascript = $this->update_main_listing($submission);
- }
-
- case 'next':
- /// We are currently in pop up, but we want to skip to next one without saving.
- /// This turns out to be similar to a single case
- /// The URL used is for the next submission.
- $offset = required_param('offset', PARAM_INT);
- $nextid = required_param('nextid', PARAM_INT);
- $id = required_param('id', PARAM_INT);
- $offset = (int)$offset+1;
- //$this->display_submission($offset+1 , $nextid);
- redirect('submissions.php?id='.$id.'&userid='. $nextid . '&mode=single&offset='.$offset);
- break;
-
- case 'singlenosave':
- display_submission();
- break;
-
- default:
- echo "Critical error. Something is seriously wrong!!";
- break;
- }
-}
-
-/**
- * Display all the submissions ready for grading
- *
- * @global object
- * @global object
- * @global object
- * @global object
- * @param string $message
- * @return bool|void
- */
-function lti_display_submissions($cm, $course, $basiclti, $message='') {
- global $CFG, $DB, $OUTPUT, $PAGE;
- require_once($CFG->libdir.'/gradelib.php');
-
- /* first we check to see if the form has just been submitted
- * to request user_preference updates
- */
- $updatepref = optional_param('updatepref', 0, PARAM_INT);
-
- if (isset($_POST['updatepref'])) {
- $perpage = optional_param('perpage', 10, PARAM_INT);
- $perpage = ($perpage <= 0) ? 10 : $perpage;
- $filter = optional_param('filter', 0, PARAM_INT);
- set_user_preference('lti_perpage', $perpage);
- set_user_preference('lti_quickgrade', optional_param('quickgrade', 0, PARAM_BOOL));
- set_user_preference('lti_filter', $filter);
- }
-
- /* next we get perpage and quickgrade (allow quick grade) params
- * from database
- */
- $perpage = get_user_preferences('lti_perpage', 10);
- $quickgrade = get_user_preferences('lti_quickgrade', 0);
- $filter = get_user_preferences('lti_filter', 0);
- $grading_info = grade_get_grades($course->id, 'mod', 'lti', $basiclti->id);
-
- if (!empty($CFG->enableoutcomes) and !empty($grading_info->outcomes)) {
- $uses_outcomes = true;
- } else {
- $uses_outcomes = false;
- }
-
- $page = optional_param('page', 0, PARAM_INT);
- $strsaveallfeedback = get_string('saveallfeedback', 'lti');
-
- $tabindex = 1; //tabindex for quick grading tabbing; Not working for dropdowns yet
- add_to_log($course->id, 'lti', 'view submission', 'submissions.php?id='.$cm->id, $basiclti->id, $cm->id);
-
- $PAGE->set_title(format_string($basiclti->name, true));
- $PAGE->set_heading($course->fullname);
- echo $OUTPUT->header();
-
- echo '<div class="usersubmissions">';
-
- //hook to allow plagiarism plugins to update status/print links.
- plagiarism_update_status($course, $cm);
-
- /// Print quickgrade form around the table
- if ($quickgrade) {
- $formattrs = array();
- $formattrs['action'] = new moodle_url('/mod/lti/submissions.php');
- $formattrs['id'] = 'fastg';
- $formattrs['method'] = 'post';
-
- echo html_writer::start_tag('form', $formattrs);
- echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'id', 'value'=> $cm->id));
- echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'mode', 'value'=> 'fastgrade'));
- echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'page', 'value'=> $page));
- echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=> sesskey()));
- }
-
- $course_context = get_context_instance(CONTEXT_COURSE, $course->id);
- if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
- echo '<div class="allcoursegrades"><a href="' . $CFG->wwwroot . '/grade/report/grader/index.php?id=' . $course->id . '">'
- . get_string('seeallcoursegrades', 'grades') . '</a></div>';
- }
-
- if (!empty($message)) {
- echo $message; // display messages here if any
- }
-
- $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-
-/// Check to see if groups are being used in this tool
-
- /// find out current groups mode
- $groupmode = groups_get_activity_groupmode($cm);
- $currentgroup = groups_get_activity_group($cm, true);
- groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/lti/submissions.php?id=' . $cm->id);
-
- /// Get all ppl that are allowed to submit tools
- list($esql, $params) = get_enrolled_sql($context, 'mod/lti:view', $currentgroup);
-
- $sql = "SELECT u.id FROM {user} u ".
- "LEFT JOIN ($esql) eu ON eu.id=u.id ".
- "WHERE u.deleted = 0 AND eu.id=u.id ";
-
- $users = $DB->get_records_sql($sql, $params);
- if (!empty($users)) {
- $users = array_keys($users);
- }
-
- // if groupmembersonly used, remove users who are not in any group
- if ($users and !empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) {
- if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) {
- $users = array_intersect($users, array_keys($groupingusers));
- }
- }
-
- $tablecolumns = array('picture', 'fullname', 'grade', 'submissioncomment', 'timemodified', 'timemarked', 'status', 'finalgrade');
- if ($uses_outcomes) {
- $tablecolumns[] = 'outcome'; // no sorting based on outcomes column
- }
-
- $tableheaders = array('',
- get_string('fullname'),
- get_string('grade'),
- get_string('comment', 'lti'),
- get_string('lastmodified').' ('.get_string('submission', 'lti').')',
- get_string('lastmodified').' ('.get_string('grade').')',
- get_string('status'),
- get_string('finalgrade', 'grades'));
- if ($uses_outcomes) {
- $tableheaders[] = get_string('outcome', 'grades');
- }
-
- require_once($CFG->libdir.'/tablelib.php');
- $table = new flexible_table('mod-lti-submissions');
-
- $table->define_columns($tablecolumns);
- $table->define_headers($tableheaders);
- $table->define_baseurl($CFG->wwwroot.'/mod/lti/submissions.php?id='.$cm->id.'&amp;currentgroup='.$currentgroup);
-
- $table->sortable(true, 'lastname');//sorted by lastname by default
- $table->collapsible(true);
- $table->initialbars(true);
-
- $table->column_suppress('picture');
- $table->column_suppress('fullname');
-
- $table->column_class('picture', 'picture');
- $table->column_class('fullname', 'fullname');
- $table->column_class('grade', 'grade');
- $table->column_class('submissioncomment', 'comment');
- $table->column_class('timemodified', 'timemodified');
- $table->column_class('timemarked', 'timemarked');
- $table->column_class('status', 'status');
- $table->column_class('finalgrade', 'finalgrade');
- if ($uses_outcomes) {
- $table->column_class('outcome', 'outcome');
- }
-
- $table->set_attribute('cellspacing', '0');
- $table->set_attribute('id', 'attempts');
- $table->set_attribute('class', 'submissions');
- $table->set_attribute('width', '100%');
-
- $table->no_sorting('finalgrade');
- $table->no_sorting('outcome');
-
- // Start working -- this is necessary as soon as the niceties are over
- $table->setup();
-
- if (empty($users)) {
- echo $OUTPUT->heading(get_string('noviewusers', 'lti'));
- echo '</div>';
- return true;
- }
-
- /// Construct the SQL
- list($where, $params) = $table->get_sql_where();
- if ($where) {
- $where .= ' AND ';
- }
-
- if ($sort = $table->get_sql_sort()) {
- $sort = ' ORDER BY '.$sort;
- }
-
- $ufields = user_picture::fields('u');
-
- $gradeitem = $DB->get_record('grade_items', array('courseid' => $cm->course, 'iteminstance' => $cm->instance));
-
- $select = "SELECT $ufields,
- g.rawgrade, g.feedback,
- g.timemodified, g.timecreated ";
-
- $sql = 'FROM {user} u'.
- ' LEFT JOIN {grade_grades} g ON u.id = g.userid AND g.itemid = '.$gradeitem->id.
- ' LEFT JOIN {grade_items} i ON g.itemid = i.id'.
- ' AND i.iteminstance = '.$basiclti->id.
- ' WHERE '.$where.'u.id IN ('.implode(',', $users).') ';
-
- $ausers = $DB->get_records_sql($select.$sql.$sort, $params, $table->get_page_start(), $table->get_page_size());
-
- $table->pagesize($perpage, count($users));
-
- ///offset used to calculate index of student in that particular query, needed for the pop up to know who's next
- $offset = $page * $perpage;
- $strupdate = get_string('update');
- $strgrade = get_string('grade');
- $grademenu = make_grades_menu($basiclti->grade);
- if ($ausers !== false) {
- $grading_info = grade_get_grades($course->id, 'mod', 'lti', $basiclti->id, array_keys($ausers));
- $endposition = $offset + $perpage;
- $currentposition = 0;
- foreach ($ausers as $auser) {
-
- if ($auser->timemodified > 0) {
- $timemodified = '<div id="ts'.$auser->id.'">'.userdate($auser->timemodified).'</div>';
- } else {
- $timemodified = '<div id="ts'.$auser->id.'">&nbsp;</div>';
- }
- if ($auser->timecreated > 0) {
- $timecreated = '<div id="ts'.$auser->id.'">'.userdate($auser->timecreated).'</div>';
- } else {
- $timecreated = '<div id="ts'.$auser->id.'">&nbsp;</div>';
- }
-
- if ($currentposition == $offset && $offset < $endposition) {
- $final_grade = $grading_info->items[0]->grades[$auser->id];
- $grademax = $grading_info->items[0]->grademax;
- $final_grade->formatted_grade = round($final_grade->grade, 2) .' / ' . round($grademax, 2);
- $locked_overridden = 'locked';
- if ($final_grade->overridden) {
- $locked_overridden = 'overridden';
- }
-
- /// Calculate user status
- $picture = $OUTPUT->user_picture($auser);
-
- $studentmodified = '<div id="ts'.$auser->id.'">&nbsp;</div>';
- $teachermodified = '<div id="tt'.$auser->id.'">&nbsp;</div>';
- $status = '<div id="st'.$auser->id.'">&nbsp;</div>';
-
- if ($final_grade->locked or $final_grade->overridden) {
- $grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade . '</div>';
- } else if ($quickgrade) { // allow editing
- $attributes = array();
- $attributes['tabindex'] = $tabindex++;
- if ($auser->rawgrade != "") {
- $menu = html_writer::select(make_grades_menu($basiclti->grade), 'menu['.$auser->id.']', round($auser->rawgrade, 0), array(-1=>get_string('nograde')), $attributes);
- } else {
- $menu = html_writer::select(make_grades_menu($basiclti->grade), 'menu['.$auser->id.']', -1, array(-1=>get_string('nograde')), $attributes);
- }
- $grade = '<div id="g'.$auser->id.'">'.$menu.'</div>';
- } else if ($final_grade->grade) {
- if ($auser->rawgrade != "") {
- $grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade.'</div>';
- } else {
- $grade = '<div id="g'.$auser->id.'">-1</div>';
- }
-
- } else {
- $grade = '<div id="g'.$auser->id.'">No Grade</div>';
- }
-
- if ($final_grade->locked or $final_grade->overridden) {
- $comment = '<div id="com'.$auser->id.'">'.$final_grade->str_feedback.'</div>';
- } else if ($quickgrade) {
- $comment = '<div id="com'.$auser->id.'">'
- . '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'
- . $auser->id.'" rows="2" cols="20">'.($auser->feedback).'</textarea></div>';
- } else {
- $comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($auser->feedback), 15).'</div>';
- }
-
- if (empty($auser->status)) { /// Confirm we have exclusively 0 or 1
- $auser->status = 0;
- } else {
- $auser->status = 1;
- }
-
- $buttontext = ($auser->status == 1) ? $strupdate : $strgrade;
-
- ///No more buttons, we use popups ;-).
- $popup_url = '/mod/lti/submissions.php?id='.$cm->id
- . '&amp;userid='.$auser->id.'&amp;mode=single'.'&amp;filter='.$filter.'&amp;offset='.$offset++;
-
- $button = $OUTPUT->action_link($popup_url, $buttontext);
-
- $status = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';
-
- $finalgrade = '<span id="finalgrade_'.$auser->id.'">'.$final_grade->str_grade.'</span>';
-
- $outcomes = '';
-
- if ($uses_outcomes) {
-
- foreach ($grading_info->outcomes as $n => $outcome) {
- $outcomes .= '<div class="outcome"><label>'.$outcome->name.'</label>';
- $options = make_grades_menu(-$outcome->scaleid);
-
- if ($outcome->grades[$auser->id]->locked or !$quickgrade) {
- $options[0] = get_string('nooutcome', 'grades');
- $outcomes .= ': <span id="outcome_'.$n.'_'.$auser->id.'">'.$options[$outcome->grades[$auser->id]->grade].'</span>';
- } else {
- $attributes = array();
- $attributes['tabindex'] = $tabindex++;
- $attributes['id'] = 'outcome_'.$n.'_'.$auser->id;
- $outcomes .= ' '.html_writer::select($options, 'outcome_'.$n.'['.$auser->id.']', $outcome->grades[$auser->id]->grade, array(0=>get_string('nooutcome', 'grades')), $attributes);
- }
- $outcomes .= '</div>';
- }
- }
-
- $userlink = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $auser->id . '&amp;course=' . $course->id . '">' . fullname($auser, has_capability('moodle/site:viewfullnames', $context)) . '</a>';
- $row = array($picture, $userlink, $grade, $comment, $timemodified, $timecreated, $status, $finalgrade);
- if ($uses_outcomes) {
- $row[] = $outcomes;
- }
-
- $table->add_data($row);
- }
- $currentposition++;
- }
- }
-
- $table->print_html(); /// Print the whole table
-
- /// Print quickgrade form around the table
- if ($quickgrade && $table->started_output) {
- $mailinfopref = false;
- if (get_user_preferences('lti_mailinfo', 1)) {
- $mailinfopref = true;
- }
- $emailnotification = html_writer::checkbox('mailinfo', 1, $mailinfopref, get_string('enableemailnotification', 'lti'));
-
- $emailnotification .= $OUTPUT->help_icon('enableemailnotification', 'lti');
- echo html_writer::tag('div', $emailnotification, array('class'=>'emailnotification'));
-
- $savefeedback = html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'fastg', 'value'=>get_string('saveallfeedback', 'lti')));
- echo html_writer::tag('div', $savefeedback, array('class'=>'fastgbutton'));
-
- echo html_writer::end_tag('form');
- } else if ($quickgrade) {
- echo html_writer::end_tag('form');
- }
-
- echo '</div>';
- /// End of fast grading form
-
- /// Mini form for setting user preference
-
- $formaction = new moodle_url('/mod/lti/submissions.php', array('id'=>$cm->id));
- $mform = new MoodleQuickForm('optionspref', 'post', $formaction, '', array('class'=>'optionspref'));
-
- $mform->addElement('hidden', 'updatepref');
- $mform->setDefault('updatepref', 1);
- $mform->addElement('header', 'qgprefs', get_string('optionalsettings', 'lti'));
-// $mform->addElement('select', 'filter', get_string('show'), $filters);
-
- $mform->setDefault('filter', $filter);
-
- $mform->addElement('text', 'perpage', get_string('pagesize', 'lti'), array('size'=>1));
- $mform->setDefault('perpage', $perpage);
-
- $mform->addElement('checkbox', 'quickgrade', get_string('quickgrade', 'lti'));
- $mform->setDefault('quickgrade', $quickgrade);
- $mform->addHelpButton('quickgrade', 'quickgrade', 'lti');
-
- $mform->addElement('submit', 'savepreferences', get_string('savepreferences'));
-
- $mform->display();
-
- echo $OUTPUT->footer();
-}
-
-/**
* Create grade item for given basiclti
*
* @param object $basiclti object with extra cmidnumber
@@ -1008,3 +362,14 @@ function lti_grade_item_delete($basiclti) {
return grade_update('mod/lti', $basiclti->course, 'mod', 'lti', $basiclti->id, 0, null, array('deleted'=>1));
}
+function lti_extend_settings_navigation($settings, $parentnode) {
+ global $PAGE;
+
+ $keys = $parentnode->get_children_key_list();
+
+ $node = navigation_node::create('Submissions',
+ new moodle_url('/mod/lti/grade.php', array('id'=>$PAGE->cm->id)),
+ navigation_node::TYPE_SETTING, null, 'mod_lti_submissions');
+
+ $parentnode->add_node($node, $keys[1]);
+}
View
49 mod/lti/locallib.php
@@ -95,6 +95,8 @@ function lti_view($instance, $makeobject=false) {
$typeconfig['sendname'] = $instance->instructorchoicesendname;
$typeconfig['sendemailaddr'] = $instance->instructorchoicesendemailaddr;
$typeconfig['customparameters'] = $instance->instructorcustomparameters;
+ $typeconfig['acceptgrades'] = $instance->instructorchoiceacceptgrades;
+ $typeconfig['allowroster'] = $instance->instructorchoiceallowroster;
}
//Default the organizationid if not specified
@@ -131,11 +133,16 @@ function lti_view($instance, $makeobject=false) {
echo $content;
}
-function lti_build_sourcedid($instanceid, $userid, $servicesalt){
+function lti_build_sourcedid($instanceid, $userid, $launchid = null, $servicesalt){
$data = new stdClass();
$data->instanceid = $instanceid;
$data->userid = $userid;
+ if(!empty($launchid)){
+ $data->launchid = $launchid;
+ } else {
+ $data->launchid = mt_rand();
+ }
$json = json_encode($data);
@@ -183,7 +190,7 @@ function lti_build_request($instance, $typeconfig, $course) {
$placementsecret = $instance->servicesalt;
if ( isset($placementsecret) ) {
- $sourcedid = json_encode(lti_build_sourcedid($instance->id, $USER->id, $placementsecret));
+ $sourcedid = json_encode(lti_build_sourcedid($instance->id, $USER->id, null, $placementsecret));
}
if ( isset($placementsecret) &&
@@ -998,44 +1005,6 @@ function lti_post_launch_html($newparms, $endpoint, $debug=false) {
return $r;
}
-/**
- * Returns a link with info about the state of the basiclti submissions
- *
- * This is used by view_header to put this link at the top right of the page.
- * For teachers it gives the number of submitted assignments with a link
- * For students it gives the time of their submission.
- * This will be suitable for most assignment types.
- *
- * @global object
- * @global object
- * @param bool $allgroup print all groups info if user can access all groups, suitable for index.php
- * @return string
- */
-function lti_submittedlink($cm, $allgroups=false) {
- global $CFG;
-
- $submitted = '';
- $urlbase = "{$CFG->wwwroot}/mod/lti/";
-
- $context = get_context_instance(CONTEXT_MODULE, $cm->id);
- if (has_capability('mod/lti:grade', $context)) {
- if ($allgroups and has_capability('moodle/site:accessallgroups', $context)) {
- $group = 0;
- } else {
- $group = groups_get_activity_group($cm);
- }
-
- $submitted = '<a href="'.$urlbase.'submissions.php?id='.$cm->id.'">'.
- get_string('viewsubmissions', 'lti').'</a>';
- } else {
- if (isloggedin()) {
- // TODO Insert code for students if needed
- }
- }
-
- return $submitted;
-}
-
function lti_get_type($typeid){
global $DB;
View
2  mod/lti/service.php
@@ -20,7 +20,7 @@
lti_verify_sourcedid($ltiinstance, $parsed);
lti_verify_message($ltiinstance, $rawbody);
- $gradestatus = lti_update_grade($ltiinstance, $parsed->userid, $parsed->gradeval);
+ $gradestatus = lti_update_grade($ltiinstance, $parsed->userid, $parsed->launchid, $parsed->gradeval);
$responsexml = lti_get_response_xml(
$gradestatus ? 'success' : 'error',
View
36 mod/lti/servicelib.php
@@ -49,6 +49,7 @@ function lti_parse_grade_replace_message($xml){
$parsed->instanceid = $resultjson->data->instanceid;
$parsed->userid = $resultjson->data->userid;
+ $parsed->launchid = $resultjson->data->launchid;
$parsed->sourcedidhash = $resultjson->hash;
$parsed->messageid = lti_parse_message_id($xml);
@@ -63,6 +64,7 @@ function lti_parse_grade_read_message($xml){
$parsed = new stdClass();
$parsed->instanceid = $resultjson->data->instanceid;
$parsed->userid = $resultjson->data->userid;
+ $parsed->launchid = $resultjson->data->launchid;
$parsed->sourcedidhash = $resultjson->hash;
$parsed->messageid = lti_parse_message_id($xml);
@@ -77,6 +79,7 @@ function lti_parse_grade_delete_message($xml){
$parsed = new stdClass();
$parsed->instanceid = $resultjson->data->instanceid;
$parsed->userid = $resultjson->data->userid;
+ $parsed->launchid = $resultjson->data->launchid;
$parsed->sourcedidhash = $resultjson->hash;
$parsed->messageid = lti_parse_message_id($xml);
@@ -84,8 +87,8 @@ function lti_parse_grade_delete_message($xml){
return $parsed;
}
-function lti_update_grade($ltiinstance, $userid, $gradeval){
- global $CFG;
+function lti_update_grade($ltiinstance, $userid, $launchid, $gradeval){
+ global $CFG, $DB;
require_once($CFG->libdir . '/gradelib.php');
$params = array();
@@ -97,6 +100,33 @@ function lti_update_grade($ltiinstance, $userid, $gradeval){
$status = grade_update(LTI_SOURCE, $ltiinstance->course, LTI_ITEM_TYPE, LTI_ITEM_MODULE, $ltiinstance->id, 0, $grade, $params);
+ $record = $DB->get_record('lti_submission', array('ltiid' => $ltiinstance->id, 'userid' => $userid, 'launchid' => $launchid), 'id');
+ if($record){
+ $id = $record->id;
+ } else {
+ $id = null;
+ }
+
+ if(!empty($id)){
+ $DB->update_record('lti_submission', array(
+ 'id' => $id,
+ 'dateupdated' => time(),
+ 'gradepercent' => $gradeval,
+ 'state' => 2
+ ));
+ } else {
+ $DB->insert_record('lti_submission', array(
+ 'ltiid' => $ltiinstance->id,
+ 'userid' => $userid,
+ 'datesubmitted' => time(),
+ 'dateupdated' => time(),
+ 'gradepercent' => $gradeval,
+ 'originalgrade' => $gradeval,
+ 'launchid' => $launchid,
+ 'state' => 1
+ ));
+ }
+
return $status == GRADE_UPDATE_OK;
}
@@ -156,7 +186,7 @@ function lti_verify_message($ltiinstance, $body, $headers = null){
}
function lti_verify_sourcedid($ltiinstance, $parsed){
- $sourceid = lti_build_sourcedid($parsed->instanceid, $parsed->userid, $ltiinstance->servicesalt);
+ $sourceid = lti_build_sourcedid($parsed->instanceid, $parsed->userid, $parsed->launchid, $ltiinstance->servicesalt);
if($sourceid->hash != $parsed->sourcedidhash){
throw new Exception('SourcedId hash not valid');
View
52 mod/lti/submissions.js
@@ -0,0 +1,52 @@
+(function(){
+ var Y;
+
+ M.mod_lti = M.mod_lti || {};
+
+ M.mod_lti.submissions = {
+ init: function(yui3){
+ if(yui3){
+ Y = yui3;
+ }
+
+ this.setupTable();
+
+
+ },
+
+ setupTable: function(){
+ var lti_submissions_table = YAHOO.util.Dom.get('lti_submissions_table');
+
+ var dataSource = new YAHOO.util.DataSource(lti_submissions_table);
+
+ var configuredColumns = [
+ { key: "user", label: "User", sortable:true },
+ { key: "date", label: "Submission Date", sortable:true, formatter: 'date' },
+ { key: "grade",
+ label: "Grade",
+ sortable:true,
+ formatter: function(cell, record, column, data){
+ cell.innerHTML = parseFloat(data).toFixed(1) + '%';
+ }
+ }
+ ];
+
+ dataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
+ dataSource.responseSchema = {
+ fields: [
+ { key: "user" },
+ { key: "date", parser: "date" },
+ { key: "grade", parser: "number" },
+ ]
+ };
+
+ new YAHOO.widget.DataTable("lti_submissions_table_container", configuredColumns, dataSource,
+ {
+ sortedBy: {key:"date", dir:"desc"}
+ }
+ );
+
+ Y.one('#lti_submissions_table_container').setStyle('display', '');
+ }
+ }
+})();
View
4 mod/lti/view.php
@@ -122,10 +122,6 @@
echo $OUTPUT->box($basiclti->intro, 'generalbox description', 'intro');
}
-if ($basiclti->instructorchoiceacceptgrades == 1) {
- echo '<div class="reportlink">'.lti_submittedlink($cm).'</div>';
-}
-
if ( $launchcontainer == LTI_LAUNCH_CONTAINER_WINDOW ) {
echo "<script language=\"javascript\">//<![CDATA[\n";
echo "window.open('launch.php?id=".$cm->id."','lti');";
Please sign in to comment.
Something went wrong with that request. Please try again.