mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
Updating LTI submission viewer
This commit is contained in:
parent
a35626f9bc
commit
f4f711d79b
@ -44,7 +44,7 @@
|
||||
|
||||
$capabilities = array(
|
||||
|
||||
'mod/ltii:view' => array(
|
||||
'mod/lti:view' => array(
|
||||
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_MODULE,
|
||||
|
@ -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>
|
@ -89,4 +89,96 @@ require_login($course, false, $cm);
|
||||
|
||||
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();
|
657
mod/lti/lib.php
657
mod/lti/lib.php
@ -315,652 +315,6 @@ function lti_get_lti_types() {
|
||||
return $DB->get_records('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&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.'&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.'"> </div>';
|
||||
}
|
||||
if ($auser->timecreated > 0) {
|
||||
$timecreated = '<div id="ts'.$auser->id.'">'.userdate($auser->timecreated).'</div>';
|
||||
} else {
|
||||
$timecreated = '<div id="ts'.$auser->id.'"> </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.'"> </div>';
|
||||
$teachermodified = '<div id="tt'.$auser->id.'"> </div>';
|
||||
$status = '<div id="st'.$auser->id.'"> </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
|
||||
. '&userid='.$auser->id.'&mode=single'.'&filter='.$filter.'&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 . '&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
|
||||
*
|
||||
@ -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]);
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -20,7 +20,7 @@ switch($messagetype){
|
||||
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',
|
||||
|
@ -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');
|
||||
|
52
mod/lti/submissions.js
Normal file
52
mod/lti/submissions.js
Normal file
@ -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', '');
|
||||
}
|
||||
}
|
||||
})();
|
@ -122,10 +122,6 @@ if($basiclti->showdescription && $basiclti->intro){
|
||||
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');";
|
||||
|
Loading…
x
Reference in New Issue
Block a user