MDL-29481: added support for remarks in rubric feedback

This commit is contained in:
Marina Glancy
2011-10-24 13:36:33 +08:00
parent 9e2eca0fde
commit 5060997ba5
4 changed files with 73 additions and 39 deletions
+3 -3
View File
@@ -48,7 +48,7 @@ abstract class gradingform_controller {
protected $areaid;
/** @var stdClass|false the definition structure */
protected $definition;
protected $definition = false;
/** @var array graderange array of valid grades for this area. Use set_grade_range and get_grade_range to access this */
private $graderange = null;
@@ -110,7 +110,7 @@ abstract class gradingform_controller {
* @return boolean
*/
public function is_form_defined() {
return !empty($this->definition);
return ($this->definition !== false);
}
/**
@@ -181,7 +181,7 @@ abstract class gradingform_controller {
* @return stdClass|false definition data or false if the form is not defined yet
*/
public function get_definition($force = false) {
if (is_null($this->definition)) {
if ($this->definition === false || $force) {
$this->load_definition();
}
return $this->definition;
+39 -29
View File
@@ -190,7 +190,7 @@ class gradingform_rubric_controller extends gradingform_controller {
$this->definition = false;
foreach ($rs as $record) {
// pick the common definition data
if (empty($this->definition)) {
if ($this->definition === false) {
$this->definition = new stdClass();
foreach (array('id', 'name', 'description', 'descriptionformat', 'status', 'copiedfromid',
'timecreated', 'usercreated', 'timemodified', 'usermodified', 'options') as $fieldname) {
@@ -290,7 +290,7 @@ class gradingform_rubric_controller extends gradingform_controller {
}
public function get_formatted_description() {
if (!$this->definition) {
if ($this->definition === false) {
return null;
}
$context = $this->get_context();
@@ -385,6 +385,8 @@ class gradingform_rubric_controller extends gradingform_controller {
*/
class gradingform_rubric_instance extends gradingform_instance {
protected $rubric;
/**
* Deletes this (INCOMPLETE) instance from database.
*/
@@ -406,11 +408,11 @@ class gradingform_rubric_instance extends gradingform_instance {
global $DB;
$instanceid = parent::copy($raterid, $itemid);
$currentgrade = $this->get_rubric_filling();
foreach ($currentgrade as $criterionid => $levelid) {
$params = array('forminstanceid' => $instanceid, 'criterionid' => $criterionid, 'levelid' => $levelid);
foreach ($currentgrade['criteria'] as $criterionid => $record) {
$params = array('forminstanceid' => $instanceid, 'criterionid' => $criterionid,
'levelid' => $record['levelid'], 'remark' => $record['remark'], 'remarkformat' => $record['remarkformat']);
$DB->insert_record('gradingform_rubric_fillings', $params);
}
// TODO remarks
return $instanceid;
}
@@ -421,11 +423,12 @@ class gradingform_rubric_instance extends gradingform_instance {
public function validate_grading_element($elementvalue) {
// TODO: if there is nothing selected in rubric, we don't enter this function at all :(
$criteria = $this->get_controller()->get_definition()->rubric_criteria;
if (!is_array($elementvalue) || sizeof($elementvalue) < sizeof($criteria)) {
if (!isset($elementvalue['criteria']) || !is_array($elementvalue['criteria']) || sizeof($elementvalue['criteria']) < sizeof($criteria)) {
return false;
}
foreach ($criteria as $id => $criterion) {
if (!array_key_exists($id, $elementvalue) || !array_key_exists($elementvalue[$id], $criterion['levels'])) {
if (!isset($elementvalue['criteria'][$id]['levelid'])
|| !array_key_exists($elementvalue['criteria'][$id]['levelid'], $criterion['levels'])) {
return false;
}
}
@@ -435,20 +438,19 @@ class gradingform_rubric_instance extends gradingform_instance {
/**
* Retrieves from DB and returns the data how this rubric was filled
*
* @param boolean $force whether to force DB query even if the data is cached
* @return array
*/
public function get_rubric_filling() {
// TODO cache
public function get_rubric_filling($force = false) {
global $DB;
$rs = $DB->get_records('gradingform_rubric_fillings', array('forminstanceid' => $this->get_id()));
$grading = array();
foreach ($rs as $record) {
if ($record->levelid) {
$grading[$record->criterionid] = $record->levelid;
if ($this->rubric === null || $force) {
$records = $DB->get_records('gradingform_rubric_fillings', array('forminstanceid' => $this->get_id()));
$this->rubric = array('criteria' => array());
foreach ($records as $record) {
$this->rubric['criteria'][$record->criterionid] = (array)$record;
}
// TODO: remarks
}
return $grading;
return $this->rubric;
}
/**
@@ -460,21 +462,29 @@ class gradingform_rubric_instance extends gradingform_instance {
global $DB;
$currentgrade = $this->get_rubric_filling();
parent::update($data); // TODO ? +timemodified
foreach ($data as $criterionid => $levelid) {
$params = array('forminstanceid' => $this->get_id(), 'criterionid' => $criterionid);
if (!array_key_exists($criterionid, $currentgrade)) {
$DB->insert_record('gradingform_rubric_fillings', $params + array('levelid' => $levelid));
} else if ($currentgrade[$criterionid] != $levelid) {
$DB->set_field('gradingform_rubric_fillings', 'levelid', $levelid, $params);
foreach ($data['criteria'] as $criterionid => $record) {
if (!array_key_exists($criterionid, $currentgrade['criteria'])) {
$newrecord = array('forminstanceid' => $this->get_id(), 'criterionid' => $criterionid,
'levelid' => $record['levelid'], 'remark' => $record['remark'], 'remarkformat' => FORMAT_MOODLE);
$DB->insert_record('gradingform_rubric_fillings', $newrecord);
} else {
$newrecord = array('id' => $currentgrade['criteria'][$criterionid]['id']);
foreach (array('levelid', 'remark'/*, 'remarkformat' TODO */) as $key) {
if ($currentgrade['criteria'][$criterionid][$key] != $record[$key]) {
$newrecord[$key] = $record[$key];
}
}
if (count($newrecord) > 1) {
$DB->update_record('gradingform_rubric_fillings', $newrecord);
}
}
}
foreach ($currentgrade as $criterionid => $levelid) {
if (!array_key_exists($criterionid, $data)) {
$params = array('forminstanceid' => $this->get_id(), 'criterionid' => $criterionid);
$DB->delete_records('gradingform_rubric_fillings', $params);
foreach ($currentgrade['criteria'] as $criterionid => $record) {
if (!array_key_exists($criterionid, $data['criteria'])) {
$DB->delete_records('gradingform_rubric_fillings', array('id' => $record['id']));
}
}
// TODO: remarks
$this->get_rubric_filling(true);
}
/**
@@ -508,8 +518,8 @@ class gradingform_rubric_instance extends gradingform_instance {
$maxgrade = $graderange[sizeof($graderange) - 1];
$curscore = 0;
foreach ($grade as $id => $levelid) {
$curscore += $this->get_controller()->get_definition()->rubric_criteria[$id]['levels'][$levelid]['score'];
foreach ($grade['criteria'] as $id => $record) {
$curscore += $this->get_controller()->get_definition()->rubric_criteria[$id]['levels'][$record['levelid']]['score'];
}
return round(($curscore-$minscore)/($maxscore-$minscore)*($maxgrade-$mingrade), 0) + $mingrade; // TODO mapping
}
+27 -7
View File
@@ -35,8 +35,8 @@ class gradingform_rubric_renderer {
* @param int $mode @see gradingform_rubric_controller
* @return string
*/
public function criterion_template($mode, $elementname = '{NAME}', $criterion = null, $levels_str = '{LEVELS}') {
// TODO description format
public function criterion_template($mode, $elementname = '{NAME}', $criterion = null, $levels_str = '{LEVELS}', $value = null) {
// TODO description format, remark format
if ($criterion === null || !is_array($criterion) || !array_key_exists('id', $criterion)) {
$criterion = array('id' => '{CRITERION-id}', 'description' => '{CRITERION-description}', 'sortorder' => '{CRITERION-sortorder}', 'class' => '{CRITERION-class}');
} else {
@@ -74,6 +74,21 @@ class gradingform_rubric_renderer {
'id' => '{NAME}-{CRITERION-id}-levels-addlevel', 'value' => $value, 'title' => $value)); //TODO '{NAME}-{CRITERION-id}-levels-addlevel
$criterion_template .= html_writer::tag('div', $button, array('class' => 'addlevel'));
}
if (isset($value['remark'])) {
$currentremark = $value['remark'];
} else {
$currentremark = '';
}
if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) {
$input = html_writer::tag('textarea', htmlspecialchars($currentremark), array('name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'cols' => '10', 'rows' => '5'));
$criterion_template .= html_writer::tag('div', $input, array('class' => 'remark'));
}
if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN) {
$criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'value' => $currentremark));
}
if ($mode == gradingform_rubric_controller::DISPLAY_REVIEW) {
$criterion_template .= html_writer::tag('div', $currentremark, array('class' => 'remark')); // TODO maybe some prefix here like 'Teacher remark:'
}
$criterion_template .= html_writer::end_tag('div'); // .criterion
$criterion_template = str_replace('{NAME}', $elementname, $criterion_template);
@@ -83,7 +98,7 @@ class gradingform_rubric_renderer {
public function level_template($mode, $elementname = '{NAME}', $criterionid = '{CRITERION-id}', $level = null) {
// TODO definition format
if ($level === null || !is_array($level) || !array_key_exists('id', $level)) {
if (!isset($level['id'])) {
$level = array('id' => '{LEVEL-id}', 'definition' => '{LEVEL-definition}', 'score' => '{LEVEL-score}', 'class' => '{LEVEL-class}', 'checked' => false);
} else {
foreach (array('score', 'definition', 'class', 'checked') as $key) {
@@ -108,12 +123,12 @@ class gradingform_rubric_renderer {
$score = $level['score'];
}
if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) {
$input = html_writer::empty_tag('input', array('type' => 'radio', 'name' => '{NAME}[{CRITERION-id}]', 'value' => $level['id']) +
$input = html_writer::empty_tag('input', array('type' => 'radio', 'name' => '{NAME}[criteria][{CRITERION-id}][levelid]', 'value' => $level['id']) +
($level['checked'] ? array('checked' => 'checked') : array()));
$level_template .= html_writer::tag('div', $input, array('class' => 'radio'));
}
if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN && $level['checked']) {
$html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}]', 'value' => $level['id']));
$level_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levelid]', 'value' => $level['id']));
}
$score = html_writer::tag('span', $score, array('id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-score'));
$level_template .= html_writer::tag('div', $definition, array('class' => 'definition', 'id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-definition'));
@@ -176,17 +191,22 @@ class gradingform_rubric_renderer {
$criterion['class'] = $this->get_css_class_suffix($cnt++, sizeof($criteria) -1);
$levels_str = '';
$levelcnt = 0;
if (isset($values['criteria'][$id])) {
$criterionvalue = $values['criteria'][$id];
} else {
$criterionvalue = null;
}
foreach ($criterion['levels'] as $levelid => $level) {
$level['score'] = (float)$level['score']; // otherwise the display will look like 1.00000
$level['class'] = $this->get_css_class_suffix($levelcnt++, sizeof($criterion['levels']) -1);
$level['checked'] = (is_array($values) && (array_key_exists($id, $values) && ((int)$values[$id] === $levelid)));
$level['checked'] = (isset($criterionvalue['levelid']) && ((int)$criterionvalue['levelid'] === $levelid));
if ($level['checked'] && ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN || $mode == gradingform_rubric_controller::DISPLAY_REVIEW)) {
$level['class'] .= ' checked';
//in mode DISPLAY_EVAL the class 'checked' will be added by JS if it is enabled. If it is not enabled, the 'checked' class will only confuse
}
$levels_str .= $this->level_template($mode, $elementname, $id, $level);
}
$criteria_str .= $this->criterion_template($mode, $elementname, $criterion, $levels_str);
$criteria_str .= $this->criterion_template($mode, $elementname, $criterion, $levels_str, $criterionvalue);
}
return $this->rubric_template($mode, $elementname, $criteria_str);
}
+4
View File
@@ -20,6 +20,8 @@
[input type=submit]
.addlevel
[input type=submit]
.remark
textarea
.addcriterion
[input type=submit]
@@ -41,11 +43,13 @@
.form_rubric .criterion .description,
.form_rubric .criterion .levels,
.form_rubric.editor .criterion .addlevel,
.form_rubric .criterion .remark,
.form_rubric .criterion .levels .level {display: inline-block; vertical-align: top;overflow: hidden;}
.form_rubric.editor .criterion .controls,
.form_rubric .criterion .description,
.form_rubric.editor .criterion .addlevel,
.form_rubric .criterion .remark,
.form_rubric .criterion .levels .level {padding:3px;}
/* Those divs should extend vertically and fill 100% of parent element height */