//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);
}
$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);
$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');
/// 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);
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');
$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;
// Pre-process grade
if ($data_type == 'grade') {
-
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
if ($postedvalue == -1) { // -1 means no grade
$finalgrade = null;
// 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;
}
}
$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);
}
$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)) {
// 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 {
// 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 />';
}
. 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)) {
$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') {
$new_html = '';
foreach ($icons as $icon_name) {
- if ($icon_name == 'edit') {
- $icon_name .= "_$type";
- }
if ($limit) {
$new_html .= ${$icon_name . '_icon'};
} else {
// 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
'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');
$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',
$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.';
$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';
$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';
$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';
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.
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,
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.
// no need to recalculate locked or overridden grades
if ($grade->is_locked() or $grade->is_overridden()) {
- return;
+ return true;
}
// do the calculation
$result = $this->formula->evaluate();
// no raw grade for calculated grades - only final
- $grade->rawgrade = null;
+ $grade->rawgrade = null;
if ($result === false) {