mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
major grade editing fixes and improvements - grader form now knows if grade is editable; fixed broken quickgrading; feedback format is handled the same way as in the rest of moodle - automatically converted to FORMAT_HTML when editor enabled; fixed calculation of grades that was breaking locking
This commit is contained in:
parent
fefe8b06a1
commit
79eabc2ab2
@ -21,12 +21,21 @@ require_capability('gradereport/grader:manage', $context);
|
||||
//TODO: implement proper return support
|
||||
$returnurl = $CFG->wwwroot.'/grade/report.php?report=grader&id='.$course->id;
|
||||
|
||||
// TODO: add proper check that grade is editable
|
||||
|
||||
$grade_grades = get_record('grade_grades', 'id', $id);
|
||||
$gradeitem = get_record('grade_items', 'id', $grade_grades->itemid);
|
||||
|
||||
$mform = new edit_grade_form(qualified_me(), array('gradeitem'=>$gradeitem));
|
||||
if ($grade_grades = get_record('grade_grades', 'id', $id)) {
|
||||
if ($grade_text = get_record('grade_grades_text', 'gradeid', $id)) {
|
||||
if (can_use_html_editor()) {
|
||||
$options = new object();
|
||||
$options->smiley = false;
|
||||
$options->filter = false;
|
||||
$grade_text->feedback = format_text($grade_text->feedback, $grade_text->feedbackformat, $options);
|
||||
$grade_text->feedbackformat = FORMAT_HTML;
|
||||
}
|
||||
$mform->set_data($grade_text);
|
||||
}
|
||||
|
||||
@ -45,7 +54,7 @@ if ($mform->is_cancelled()) {
|
||||
|
||||
$grade_grades = new grade_grades(array('id'=>$id));
|
||||
$grade_item = new grade_item(array('id'=>$grade_grades->itemid));
|
||||
$grade_item->update_final_grade($grade_grades->userid, $data->finalgrade, NULL, NULL, $data->feedback);
|
||||
$grade_item->update_final_grade($grade_grades->userid, $data->finalgrade, NULL, NULL, $data->feedback, $data->feedbackformat);
|
||||
|
||||
// set locked
|
||||
$grade_grades->set_locked($data->locked);
|
||||
|
@ -11,10 +11,11 @@ class edit_grade_form extends moodleform {
|
||||
$gradeitem = $this->_customdata['gradeitem'];
|
||||
|
||||
/// actual grade - numeric or scale
|
||||
if ($gradeitem->gradetype == 1) {
|
||||
if ($gradeitem->gradetype == GRADE_TYPE_VALUE) {
|
||||
// numeric grade
|
||||
$mform->addElement('text', 'finalgrade', get_string('finalgrade', 'grades'));
|
||||
} else if ($gradeitem->gradetype == 2) {
|
||||
|
||||
} else if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
|
||||
// scale grade
|
||||
$scaleopt[-1] = get_string('nograde');
|
||||
|
||||
@ -38,21 +39,13 @@ class edit_grade_form extends moodleform {
|
||||
/// locktime
|
||||
$mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true));
|
||||
$mform->disabledIf('locktime', 'gradetype', 'eq', GRADE_TYPE_NONE);
|
||||
/// hidden/visible
|
||||
|
||||
/// feedback
|
||||
$feedbackformat = get_user_preferences('grade_report_feedbackformat', $CFG->grade_report_feedbackformat);
|
||||
|
||||
// visible elements
|
||||
// User preference determines the format
|
||||
if ($CFG->htmleditor && $USER->htmleditor && $feedbackformat == GRADER_REPORT_FEEDBACK_FORMAT_HTML) {
|
||||
$mform->addElement('htmleditor', 'feedback', get_string('feedback', 'grades'),
|
||||
array('rows'=> '15', 'course' => $gradeitem->courseid, 'cols'=>'45'));
|
||||
} else {
|
||||
$mform->addElement('textarea', 'feedback', get_string('feedback', 'grades'));
|
||||
}
|
||||
|
||||
//TODO: add other elements
|
||||
// Feedback format is automatically converted to html if user has enabled editor
|
||||
$mform->addElement('htmleditor', 'feedback', get_string('feedback', 'grades'),
|
||||
array('rows'=> '15', 'course' => $gradeitem->courseid, 'cols'=>'45'));
|
||||
$mform->setType('text', PARAM_RAW); // to be cleaned before display
|
||||
$mform->addElement('format', 'feedbackformat', get_string('format'));
|
||||
$mform->setHelpButton('feedbackformat', array('textformat', get_string('helpformatting')));
|
||||
|
||||
// hidden params
|
||||
$mform->addElement('hidden', 'id', 0);
|
||||
|
@ -10,8 +10,6 @@ define('GRADER_REPORT_AGGREGATION_VIEW_FULL', 0);
|
||||
define('GRADER_REPORT_AGGREGATION_VIEW_COMPACT', 1);
|
||||
define('GRADER_REPORT_GRADE_DISPLAY_TYPE_RAW', 0);
|
||||
define('GRADER_REPORT_GRADE_DISPLAY_TYPE_PERCENTAGE', 1);
|
||||
define('GRADER_REPORT_FEEDBACK_FORMAT_TEXT', 0);
|
||||
define('GRADER_REPORT_FEEDBACK_FORMAT_HTML', 1);
|
||||
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
require_once($CFG->libdir.'/gradelib.php');
|
||||
@ -218,10 +216,9 @@ class grade_report_grader {
|
||||
$note = false; // TODO implement note??
|
||||
|
||||
// skip, not a grade nor feedback
|
||||
$data_type = '';
|
||||
if (strstr($varname, 'grade')) {
|
||||
if (strpos($varname, 'grade') === 0) {
|
||||
$data_type = 'grade';
|
||||
} elseif (strstr($varname, 'feedback')) {
|
||||
} else if (strpos($varname, 'feedback') === 0) {
|
||||
$data_type = 'feedback';
|
||||
} else {
|
||||
continue;
|
||||
@ -238,7 +235,6 @@ class grade_report_grader {
|
||||
|
||||
// Pre-process grade
|
||||
if ($data_type == 'grade') {
|
||||
|
||||
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
|
||||
if ($postedvalue == -1) { // -1 means no grade
|
||||
$finalgrade = null;
|
||||
@ -258,25 +254,37 @@ class grade_report_grader {
|
||||
// another possiblity is to use bounded number instead
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if ($data_type == 'feedback') {
|
||||
$trimmed = trim($postedvalue);
|
||||
if (empty($trimmed)) {
|
||||
$postedvalue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the grade object to compare old value with new value
|
||||
if ($grade = grade_grades::fetch(array('userid'=>$userid, 'itemid'=>$grade_item->id))) {
|
||||
if ($data_type == 'feedback') {
|
||||
$finalgrade = false;
|
||||
$text = $grade->load_text();
|
||||
if ($text != s($postedvalue)) {
|
||||
$feedback = s($postedvalue);
|
||||
$feedbackformat = GRADER_REPORT_FEEDBACK_FORMAT_TEXT;
|
||||
$needsupdate = true;
|
||||
if ($text = $grade->load_text()) {
|
||||
if ($text->feedback !== $postedvalue) {
|
||||
$feedback = $postedvalue;
|
||||
$feedbackformat = $text->feedbackformat; // keep original format or else we would have to do proper conversion (but it is not always possible)
|
||||
$needsupdate = true;
|
||||
}
|
||||
} else {
|
||||
$feedback = $postedvalue;
|
||||
$feedbackformat = MOODLE_FORMAT; // this is the default format option everywhere else
|
||||
$needsupdate = true;
|
||||
}
|
||||
} elseif ($data_type == 'grade') {
|
||||
|
||||
} else if ($data_type == 'grade') {
|
||||
$feedback = false;
|
||||
$feedbackformat = false;
|
||||
if (!is_null($grade->finalgrade)) {
|
||||
$grade->finalgrade = (float)$grade->finalgrade;
|
||||
}
|
||||
if ($grade->finalgrade === $finalgrade) {
|
||||
if ($grade->finalgrade !== $finalgrade) {
|
||||
$needsupdate = true;
|
||||
}
|
||||
}
|
||||
@ -731,6 +739,7 @@ class grade_report_grader {
|
||||
$element = array ('eid'=>'g'.$grade->id, 'object'=>$grade, 'type'=>'grade');
|
||||
|
||||
// Do not show any icons if no grade (no record in DB to match)
|
||||
// TODO: change edit/hide/etc. links to use itemid and userid to allow creating of new grade objects
|
||||
if (!empty($grade->id)) {
|
||||
$studentshtml .= $this->get_icons($element);
|
||||
}
|
||||
@ -753,7 +762,7 @@ class grade_report_grader {
|
||||
$scaleopt[$i] = $scaleoption;
|
||||
}
|
||||
|
||||
if ($this->get_user_pref('quickgrading')) {
|
||||
if ($this->get_user_pref('quickgrading') and $grade->is_editable()) {
|
||||
$studentshtml .= choose_from_menu($scaleopt, 'grade_'.$userid.'_'.$item->id,
|
||||
$gradeval, get_string('nograde'), '', -1, true);
|
||||
} elseif ($scale = get_record('scale', 'id', $item->scaleid)) {
|
||||
@ -769,8 +778,9 @@ class grade_report_grader {
|
||||
// no such scale, throw error?
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($this->get_user_pref('quickgrading')) {
|
||||
|
||||
} else if ($item->gradetype != GRADE_TYPE_TEXT) {
|
||||
if ($this->get_user_pref('quickgrading') and $grade->is_editable()) {
|
||||
$studentshtml .= '<input size="6" type="text" name="grade_'.$userid.'_'
|
||||
.$item->id.'" value="'.get_grade_clean($gradeval).'"/>';
|
||||
} else {
|
||||
@ -780,7 +790,7 @@ class grade_report_grader {
|
||||
|
||||
|
||||
// If quickfeedback is on, print an input element
|
||||
if ($this->get_user_pref('quickfeedback')) {
|
||||
if ($this->get_user_pref('quickfeedback') and $grade->is_editable()) {
|
||||
if ($this->get_user_pref('quickgrading')) {
|
||||
$studentshtml .= '<br />';
|
||||
}
|
||||
@ -788,7 +798,6 @@ class grade_report_grader {
|
||||
. s($grade->feedback) . '"/>';
|
||||
}
|
||||
|
||||
$studentshtml .= '<div class="grade_icons">' . $this->get_icons($element, array('edit')) . '</div>';
|
||||
} else {
|
||||
// If feedback present, surround grade with feedback tooltip
|
||||
if (!empty($grade->feedback)) {
|
||||
@ -981,24 +990,30 @@ class grade_report_grader {
|
||||
$object->feedback = '';
|
||||
}
|
||||
|
||||
// Prepare image strings
|
||||
$edit_category_icon = '<a href="'.$CFG->wwwroot.'/grade/edit/edit_category.php?courseid='.$object->courseid.'&id='.$object->id.'">'
|
||||
. '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
|
||||
. $stredit.'" title="'.$stredit.'" /></a>'. "\n";
|
||||
|
||||
$edit_item_icon = '<a href="'.$CFG->wwwroot.'/grade/edit/edit_item.php?courseid='.$object->courseid.'&id='.$object->id.'">'
|
||||
. '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
|
||||
. $stredit.'" title="'.$stredit.'" /></a>'. "\n";
|
||||
$overlib = '';
|
||||
if (!empty($object->feedback)) {
|
||||
$overlib = 'onmouseover="return overlib(\''.$object->feedback.'\', CAPTION, \''
|
||||
. $strfeedback.'\');" onmouseout="return nd();"';
|
||||
}
|
||||
|
||||
$edit_grade_icon = '<a href="'.$CFG->wwwroot.'/grade/edit/edit_grade.php?courseid='.$object->courseid.'&id='.$object->id.'">'
|
||||
. '<img ' . $overlib . ' src="'.$CFG->pixpath.'/t/edit.gif"'
|
||||
. 'class="iconsmall" alt="' . $stredit.'" title="'.$stredit.'" /></a>'. "\n";
|
||||
|
||||
// Prepare image strings
|
||||
$edit_icon = '';
|
||||
if ($object->is_editable()) {
|
||||
if ($type == 'category') {
|
||||
$edit_icon = '<a href="'.$CFG->wwwroot.'/grade/edit/edit_category.php?courseid='.$object->courseid.'&id='.$object->id.'">'
|
||||
. '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
|
||||
. $stredit.'" title="'.$stredit.'" /></a>'. "\n";
|
||||
} else if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem'){
|
||||
$edit_icon = '<a href="'.$CFG->wwwroot.'/grade/edit/edit_item.php?courseid='.$object->courseid.'&id='.$object->id.'">'
|
||||
. '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
|
||||
. $stredit.'" title="'.$stredit.'" /></a>'. "\n";
|
||||
} else if ($type == 'grade' and ($object->is_editable() or empty($object->id))) {
|
||||
// TODO: change link to use itemid and userid to allow creating of new grade objects
|
||||
$edit_icon = '<a href="'.$CFG->wwwroot.'/grade/edit/edit_grade.php?courseid='.$object->courseid.'&id='.$object->id.'">'
|
||||
. '<img ' . $overlib . ' src="'.$CFG->pixpath.'/t/edit.gif"'
|
||||
. 'class="iconsmall" alt="' . $stredit.'" title="'.$stredit.'" /></a>'. "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$edit_calculation_icon = '';
|
||||
if ($type == 'item' or $type == 'courseitem' or $type == 'categoryitem') {
|
||||
@ -1051,9 +1066,6 @@ class grade_report_grader {
|
||||
$new_html = '';
|
||||
|
||||
foreach ($icons as $icon_name) {
|
||||
if ($icon_name == 'edit') {
|
||||
$icon_name .= "_$type";
|
||||
}
|
||||
if ($limit) {
|
||||
$new_html .= ${$icon_name . '_icon'};
|
||||
} else {
|
||||
@ -1070,11 +1082,8 @@ class grade_report_grader {
|
||||
// Icons shown when edit mode is on
|
||||
if ($USER->gradeediting) {
|
||||
// Edit icon (except for grade_grades)
|
||||
if ($type == 'category') {
|
||||
$html .= $edit_category_icon;
|
||||
|
||||
} else if ($type == 'item' or $type == 'courseitem' or $type == 'categoryitem') {
|
||||
$html .= $edit_item_icon;
|
||||
if ($edit_icon) {
|
||||
$html .= $edit_icon;
|
||||
}
|
||||
|
||||
// Calculation icon for items and categories
|
||||
|
@ -33,7 +33,6 @@ class grader_report_preferences_form extends moodleform {
|
||||
'aggregationview' => array(get_string('full', 'grades'), get_string('compact', 'grades')),
|
||||
'gradedisplaytype' => array(get_string('raw', 'grades'), get_string('percentage', 'grades')),
|
||||
'grandtotalsdisplaytype' => array(get_string('raw', 'grades'), get_string('percentage', 'grades')),
|
||||
'feedbackformat' => array(get_string('text', 'grades'), get_string('html', 'grades')),
|
||||
'decimalpoints' => array(0, 1, 2, 3, 4, 5),
|
||||
'studentsperpage' => 'text');
|
||||
|
||||
|
@ -50,10 +50,6 @@ $settings->add(new admin_setting_configcheckbox('grade_report_quickfeedback', ge
|
||||
$settings->add(new admin_setting_configtext('grade_report_studentsperpage', get_string('studentsperpage', 'grades'),
|
||||
get_string('configstudentsperpage', 'grades'), 20));
|
||||
|
||||
$settings->add(new admin_setting_configselect('grade_report_feedbackformat', get_string('feedbackformat', 'grades'),
|
||||
get_string('configfeedbackformat', 'grades'), false,
|
||||
array(get_string('text', 'grades'), get_string('html', 'grades'))));
|
||||
|
||||
$settings->add(new admin_setting_configselect('grade_report_decimalpoints', get_string('decimalpoints', 'grades'),
|
||||
get_string('configdecimalpoints', 'grades'), 2,
|
||||
array( '0' => '0',
|
||||
|
@ -34,7 +34,6 @@ $string['configaggregationview'] = 'The way aggregations are displayed: either a
|
||||
$string['configbulkcheckboxes'] = 'Checkboxes near each grade for Bulk grade operations.';
|
||||
$string['configdecimalpoints'] = 'The number of decimal points to display for each grade. This can be overriden per grading item.';
|
||||
$string['configenableajax'] = 'Adds a layer of AJAX functionality to the grader report, simplifying and speeding up common operations. Depends on Javascript being switched on at the user\'s browser level.';
|
||||
$string['configfeedbackformat'] = 'The format of feedback notes attached to grades. This also determines the interface element used to enter such feedback (htmleditor for HTML format).';
|
||||
$string['configgradedisplaytype'] = 'Grades can be shown as raw grades or as percentages (in reference to the minimum and maximum grades).';
|
||||
$string['configgrandtotalsdisplaytype'] = 'Column totals can be shown as raw grades or as percentages (in reference to the minimum and maximum grades).';
|
||||
$string['configquickfeedback'] = 'Quick Feedback adds a text input element in each grade cell on the grader report, allowing you to edit many grades at once. You can then click the Update button to perform all these changes at once, instead of one at a time.';
|
||||
@ -81,7 +80,6 @@ $string['feedback'] = 'Feedback';
|
||||
$string['feedbackadd'] = 'Add feedback';
|
||||
$string['feedbackedit'] = 'Edit feedback';
|
||||
$string['feedbackview'] = 'View feedback';
|
||||
$string['feedbackformat'] = 'Feedback format';
|
||||
$string['feedbacksaved'] = 'Feedback saved';
|
||||
$string['forelementtypes'] = ' for the selected $a';
|
||||
$string['forstudents'] = 'For Students';
|
||||
@ -131,7 +129,6 @@ $string['hidescales'] = 'Hide scales';
|
||||
$string['highgradeascending'] = 'Sort by high grade ascending';
|
||||
$string['highgradedescending'] = 'Sort by high grade descending';
|
||||
$string['highgradeletter'] = 'High';
|
||||
$string['html'] = 'HTML';
|
||||
$string['identifier'] = 'Identify user by';
|
||||
$string['importcsv'] = 'Import CSV';
|
||||
$string['importfailed'] = 'Import failed';
|
||||
@ -230,7 +227,6 @@ $string['student'] = 'Student';
|
||||
$string['studentsperpage'] = 'Students per page';
|
||||
$string['subcategory'] = 'Normal Category';
|
||||
$string['synclegacygrades'] = 'Synchronise legacy grades';
|
||||
$string['text'] = 'Text';
|
||||
$string['topcategory'] = 'Super Category';
|
||||
$string['total'] = 'Total';
|
||||
$string['totalweight100'] = 'The total weight is equal to 100';
|
||||
|
@ -891,6 +891,14 @@ class grade_category extends grade_object {
|
||||
return $course_category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is grading object editable?
|
||||
* @return boolean
|
||||
*/
|
||||
function is_editable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locked state/date of the associated grade_item. This method is also available in
|
||||
* grade_item, for cases where the object type is not known.
|
||||
|
@ -155,6 +155,25 @@ class grade_grades extends grade_object {
|
||||
return $this->grade_item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is grading object editable?
|
||||
* @return boolean
|
||||
*/
|
||||
function is_editable() {
|
||||
if ($this->is_locked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$grade_item = $this->load_grade_item();
|
||||
|
||||
if ($grade_item->gradetype == GRADE_TYPE_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check grade lock status. Uses both grade item lock and grade lock.
|
||||
* Internally any date in locked field (including future ones) means locked,
|
||||
|
@ -843,6 +843,14 @@ class grade_item extends grade_object {
|
||||
return grade_item::fetch(array('courseid'=>$courseid, 'itemtype'=>'course'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Is grading object editable?
|
||||
* @return boolean
|
||||
*/
|
||||
function is_editable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if grade calculated. Returns this object's calculation.
|
||||
* @return boolean true if grade item calculated.
|
||||
@ -1430,7 +1438,7 @@ class grade_item extends grade_object {
|
||||
|
||||
// no need to recalculate locked or overridden grades
|
||||
if ($grade->is_locked() or $grade->is_overridden()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// do the calculation
|
||||
@ -1438,7 +1446,7 @@ class grade_item extends grade_object {
|
||||
$result = $this->formula->evaluate();
|
||||
|
||||
// no raw grade for calculated grades - only final
|
||||
$grade->rawgrade = null;
|
||||
$grade->rawgrade = null;
|
||||
|
||||
|
||||
if ($result === false) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user